@atlaskit/renderer 148.0.4 → 149.0.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 (62) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/cjs/actions/index.js +35 -3
  3. package/dist/cjs/entry-points/expand-body.js +12 -0
  4. package/dist/cjs/react/index.js +8 -0
  5. package/dist/cjs/react/marks/annotation.js +3 -1
  6. package/dist/cjs/react/nodes/extension-comments.compiled.css +4 -0
  7. package/dist/cjs/react/nodes/extension-comments.js +144 -0
  8. package/dist/cjs/react/nodes/extension.js +86 -11
  9. package/dist/cjs/steps/index.js +23 -0
  10. package/dist/cjs/ui/Expand.js +10 -0
  11. package/dist/cjs/ui/Renderer/index.js +1 -1
  12. package/dist/cjs/ui/annotations/contexts/AnnotationRangeContext.js +29 -11
  13. package/dist/cjs/ui/annotations/element/extension.compiled.css +6 -0
  14. package/dist/cjs/ui/annotations/element/extension.js +34 -0
  15. package/dist/cjs/ui/annotations/element/index.js +4 -2
  16. package/dist/cjs/ui/annotations/element/mark.js +11 -1
  17. package/dist/cjs/ui/annotations/index.js +2 -1
  18. package/dist/es2019/actions/index.js +33 -3
  19. package/dist/es2019/entry-points/expand-body.js +3 -0
  20. package/dist/es2019/react/index.js +8 -0
  21. package/dist/es2019/react/marks/annotation.js +3 -1
  22. package/dist/es2019/react/nodes/extension-comments.compiled.css +4 -0
  23. package/dist/es2019/react/nodes/extension-comments.js +115 -0
  24. package/dist/es2019/react/nodes/extension.js +83 -7
  25. package/dist/es2019/steps/index.js +25 -0
  26. package/dist/es2019/ui/Expand.js +10 -0
  27. package/dist/es2019/ui/Renderer/index.js +1 -1
  28. package/dist/es2019/ui/annotations/contexts/AnnotationRangeContext.js +28 -12
  29. package/dist/es2019/ui/annotations/element/extension.compiled.css +6 -0
  30. package/dist/es2019/ui/annotations/element/extension.js +26 -0
  31. package/dist/es2019/ui/annotations/element/index.js +4 -2
  32. package/dist/es2019/ui/annotations/element/mark.js +11 -1
  33. package/dist/es2019/ui/annotations/index.js +2 -1
  34. package/dist/esm/actions/index.js +35 -3
  35. package/dist/esm/entry-points/expand-body.js +3 -0
  36. package/dist/esm/react/index.js +8 -0
  37. package/dist/esm/react/marks/annotation.js +3 -1
  38. package/dist/esm/react/nodes/extension-comments.compiled.css +4 -0
  39. package/dist/esm/react/nodes/extension-comments.js +135 -0
  40. package/dist/esm/react/nodes/extension.js +86 -7
  41. package/dist/esm/steps/index.js +23 -0
  42. package/dist/esm/ui/Expand.js +10 -0
  43. package/dist/esm/ui/Renderer/index.js +1 -1
  44. package/dist/esm/ui/annotations/contexts/AnnotationRangeContext.js +30 -12
  45. package/dist/esm/ui/annotations/element/extension.compiled.css +6 -0
  46. package/dist/esm/ui/annotations/element/extension.js +27 -0
  47. package/dist/esm/ui/annotations/element/index.js +4 -2
  48. package/dist/esm/ui/annotations/element/mark.js +11 -1
  49. package/dist/esm/ui/annotations/index.js +2 -1
  50. package/dist/types/actions/index.d.ts +13 -0
  51. package/dist/types/entry-points/expand-body.d.ts +2 -0
  52. package/dist/types/react/marks/annotation.d.ts +1 -1
  53. package/dist/types/react/nodes/extension-comments.d.ts +17 -0
  54. package/dist/types/react/nodes/extension.d.ts +12 -0
  55. package/dist/types/react/types.d.ts +1 -0
  56. package/dist/types/ui/annotations/contexts/AnnotationRangeContext.d.ts +4 -2
  57. package/dist/types/ui/annotations/element/extension.d.ts +17 -0
  58. package/dist/types/ui/annotations/element/index.d.ts +2 -1
  59. package/dist/types/ui/annotations/element/mark.d.ts +3 -107
  60. package/dist/types/ui/utils/expand-body.d.ts +5 -3
  61. package/expand-body/package.json +10 -0
  62. package/package.json +5 -5
@@ -15,6 +15,7 @@ import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/anal
15
15
  import { ExpandIconWrapper, ExpandLayoutWrapperWithRef, expandMessages, WidthProvider } from '@atlaskit/editor-common/ui';
16
16
  import { akEditorLineHeight, akEditorSwoopCubicBezier, akLayoutGutterOffset } from '@atlaskit/editor-shared-styles';
17
17
  import ChevronRightIcon from '@atlaskit/icon/core/chevron-right';
18
+ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
18
19
  import Tooltip from '@atlaskit/tooltip/Tooltip';
19
20
  import { MODE, PLATFORM } from '../analytics/events';
20
21
  import { ActiveHeaderIdConsumer } from './active-header-id-provider';
@@ -379,10 +380,19 @@ function Expand({
379
380
  e.preventDefault();
380
381
  e.stopPropagation();
381
382
  fireExpandToggleAnalytics(nodeType, expanded, fireAnalyticsEvent);
383
+ // Recorded so a product remounting this expand under its own body gets it back as the
384
+ // reader left it.
385
+ const recordsToggle = node !== undefined && isExperimentEnabled('cc_light_mode_table_virtualization');
382
386
  if (expanded) {
383
387
  setExpanded(false);
388
+ if (recordsToggle) {
389
+ revealedByFind.delete(node);
390
+ }
384
391
  } else {
385
392
  openBody();
393
+ if (recordsToggle) {
394
+ revealedByFind.add(node);
395
+ }
386
396
  }
387
397
  e.persist();
388
398
  // @ts-ignore detail doesn't exist on type
@@ -57,7 +57,7 @@ export const DEGRADED_SEVERITY_THRESHOLD = 3000;
57
57
  const TABLE_INFO_TIMEOUT = 10000;
58
58
  const RENDER_EVENT_SAMPLE_RATE = 0.1;
59
59
  const packageName = "@atlaskit/renderer";
60
- const packageVersion = "148.0.3";
60
+ const packageVersion = "148.1.0";
61
61
  const setAsQueryContainerStyles = css({
62
62
  containerName: 'ak-renderer-wrapper',
63
63
  containerType: 'inline-size'
@@ -1,4 +1,5 @@
1
- import React, { createContext, useCallback, useContext, useMemo, useReducer } from 'react';
1
+ import React, { createContext, useCallback, useContext, useMemo, useReducer, useRef } from 'react';
2
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
2
3
 
3
4
  // oxlint-disable-next-line eslint/no-redeclare
4
5
 
@@ -117,8 +118,10 @@ export const AnnotationRangeDispatchContext = /*#__PURE__*/createContext({
117
118
  });
118
119
  export const AnnotationRangeProviderInner = ({
119
120
  children,
120
- allowCommentsOnMedia
121
+ allowCommentsOnMedia,
122
+ hasBlockNodeSupport
121
123
  }) => {
124
+ const extensionCommentsEnabled = !!hasBlockNodeSupport && fg('cc_maui_annotations_on_extensions');
122
125
  const [{
123
126
  selectionRange,
124
127
  hoverRange,
@@ -138,21 +141,32 @@ export const AnnotationRangeProviderInner = ({
138
141
  type: 'setSelection',
139
142
  range
140
143
  }), []);
144
+ const hoverDraftRangeRef = useRef(hoverDraftRange);
145
+ hoverDraftRangeRef.current = hoverDraftRange;
141
146
  const setHoverTarget = useCallback(target => {
142
- // the HoverComponent expects an element deeply nested inside media, these classes work with the current implementation
143
- const mediaNode = target.querySelector('.media-card-inline-player, .media-file-card-view');
144
- if (!mediaNode) {
147
+ const draftRange = hoverDraftRangeRef.current;
148
+ const draftTarget = draftRange === null || draftRange === void 0 ? void 0 : draftRange.startContainer.childNodes[draftRange.startOffset];
149
+ if (extensionCommentsEnabled && draftTarget instanceof HTMLElement && draftTarget.matches('.ak-renderer-extension[data-inline-comments-target="true"]')) {
150
+ // Keep the composer callbacks bound to the chart chosen when its draft opened.
151
+ return;
152
+ }
153
+ // The HoverComponent expects an element deeply nested inside media or the eligible
154
+ // block node's wrapper. Each selector is only included when its comment type is
155
+ // supported, so hover targeting never activates on an ineligible block node.
156
+ const selectors = [allowCommentsOnMedia && '.media-card-inline-player, .media-file-card-view', extensionCommentsEnabled && '.ak-renderer-extension[data-inline-comments-target="true"]'].filter(selector => Boolean(selector)).join(', ');
157
+ const hoverableNode = extensionCommentsEnabled && target.matches('.ak-renderer-extension[data-inline-comments-target="true"]') ? target : selectors ? target.querySelector(selectors) : null;
158
+ if (!hoverableNode) {
145
159
  return;
146
160
  }
147
- // eslint-disable-next-line @atlaskit/platform/no-direct-document-usage -- range for media hover highlight
161
+ // eslint-disable-next-line @atlaskit/platform/no-direct-document-usage -- range for media/extension hover highlight
148
162
  const range = document.createRange();
149
- range.setStartBefore(mediaNode);
150
- range.setEndAfter(mediaNode);
163
+ range.setStartBefore(hoverableNode);
164
+ range.setEndAfter(hoverableNode);
151
165
  dispatch({
152
166
  type: 'setHover',
153
167
  range
154
168
  });
155
- }, []);
169
+ }, [allowCommentsOnMedia, extensionCommentsEnabled]);
156
170
  const promoteSelectionToDraft = useCallback(position => {
157
171
  dispatch({
158
172
  type: 'promoteSelectionToDraft',
@@ -191,12 +205,12 @@ export const AnnotationRangeProviderInner = ({
191
205
  clearSelectionRange,
192
206
  clearHoverRange,
193
207
  setSelectionRange,
194
- setHoverTarget: !!allowCommentsOnMedia ? setHoverTarget : undefined,
208
+ setHoverTarget: allowCommentsOnMedia || extensionCommentsEnabled ? setHoverTarget : undefined,
195
209
  promoteSelectionToDraft,
196
210
  promoteHoverToDraft,
197
211
  clearSelectionDraft,
198
212
  clearHoverDraft
199
- }), [allowCommentsOnMedia, clearSelectionRange, clearHoverRange, setSelectionRange, setHoverTarget, promoteSelectionToDraft, promoteHoverToDraft, clearSelectionDraft, clearHoverDraft]);
213
+ }), [allowCommentsOnMedia, extensionCommentsEnabled, clearSelectionRange, clearHoverRange, setSelectionRange, setHoverTarget, promoteSelectionToDraft, promoteHoverToDraft, clearSelectionDraft, clearHoverDraft]);
200
214
  return /*#__PURE__*/React.createElement(AnnotationRangeStateContext.Provider, {
201
215
  value: stateData
202
216
  }, /*#__PURE__*/React.createElement(AnnotationRangeDispatchContext.Provider, {
@@ -206,6 +220,7 @@ export const AnnotationRangeProviderInner = ({
206
220
  export const AnnotationRangeProvider = ({
207
221
  children,
208
222
  allowCommentsOnMedia,
223
+ hasBlockNodeSupport,
209
224
  isNestedRender
210
225
  }) => {
211
226
  /*
@@ -214,7 +229,8 @@ export const AnnotationRangeProvider = ({
214
229
  * and we need the original context to create annotations on extensions.
215
230
  */
216
231
  return isNestedRender ? /*#__PURE__*/React.createElement(React.Fragment, null, children) : /*#__PURE__*/React.createElement(AnnotationRangeProviderInner, {
217
- allowCommentsOnMedia: allowCommentsOnMedia
232
+ allowCommentsOnMedia: allowCommentsOnMedia,
233
+ hasBlockNodeSupport: hasBlockNodeSupport
218
234
  }, children);
219
235
  };
220
236
  export const useAnnotationRangeState = () => {
@@ -0,0 +1,6 @@
1
+ ._154iidpf{top:0}
2
+ ._1ltvidpf{left:0}
3
+ ._1xi2idpf{right:0}
4
+ ._94n5idpf{bottom:0}
5
+ ._kqswstnw{position:absolute}
6
+ ._lcxvglyw{pointer-events:none}
@@ -0,0 +1,26 @@
1
+ /* extension.tsx generated by @compiled/babel-plugin v3.0.2 */
2
+ import "./extension.compiled.css";
3
+ import { ax, ix } from "@compiled/react/runtime";
4
+ import React from 'react';
5
+ const styles = {
6
+ anchor: "_kqswstnw _154iidpf _1xi2idpf _94n5idpf _1ltvidpf _lcxvglyw"
7
+ };
8
+
9
+ /** Full-chart anchors for comment navigation, without wrapping or intercepting the iframe. */
10
+ export const ExtensionAnnotation = ({
11
+ id,
12
+ dataAttributes,
13
+ markRef
14
+ }) => /*#__PURE__*/React.createElement("div", {
15
+ id: id,
16
+ ref: markRef,
17
+ "data-id": dataAttributes['data-id'],
18
+ "data-mark-type": dataAttributes['data-mark-type'],
19
+ "data-mark-annotation-type": dataAttributes['data-mark-annotation-type'],
20
+ "data-mark-annotation-state": dataAttributes['data-mark-annotation-state'],
21
+ "data-block-mark": dataAttributes['data-block-mark'],
22
+ "data-renderer-mark": dataAttributes['data-renderer-mark'],
23
+ "data-has-focus": dataAttributes['data-has-focus'],
24
+ "data-is-hovered": dataAttributes['data-is-hovered'],
25
+ className: ax([styles.anchor])
26
+ });
@@ -12,7 +12,8 @@ const MarkElement = ({
12
12
  children,
13
13
  dataAttributes,
14
14
  id,
15
- useBlockLevel
15
+ useBlockLevel,
16
+ isExtension
16
17
  }) => {
17
18
  const updateSubscriber = useInlineCommentSubscriberContext();
18
19
  const states = useContext(InlineCommentsStateContext);
@@ -93,7 +94,8 @@ const MarkElement = ({
93
94
  hasFocus: hasFocus,
94
95
  isHovered: isHovered,
95
96
  state: states[id],
96
- useBlockLevel: useBlockLevel
97
+ useBlockLevel: useBlockLevel,
98
+ isExtension: isExtension
97
99
  }, children);
98
100
  };
99
101
  export { MarkElement };
@@ -12,6 +12,7 @@ import { AnnotationMarkStates } from '@atlaskit/adf-schema/annotation';
12
12
  import { fg } from '@atlaskit/platform-feature-flags/fg';
13
13
  import { inlineCommentMessages } from '../../../messages';
14
14
  import { useAnnotationManagerDispatch, useAnnotationManagerState } from '../contexts/AnnotationManagerContext';
15
+ import { ExtensionAnnotation } from './extension';
15
16
  const markStyles = css({
16
17
  color: 'inherit',
17
18
  backgroundColor: 'unset',
@@ -130,7 +131,8 @@ export const MarkComponent = ({
130
131
  hasFocus,
131
132
  isHovered,
132
133
  onClick,
133
- useBlockLevel
134
+ useBlockLevel,
135
+ isExtension
134
136
  }) => {
135
137
  const intl = useIntl();
136
138
  const annotationIds = useMemo(() => [...new Set([...annotationParentIds, id])], [id, annotationParentIds]);
@@ -223,6 +225,14 @@ export const MarkComponent = ({
223
225
  'aria-details': annotationIds.join(', '),
224
226
  ...desktopAccessibilityAttributes
225
227
  };
228
+ if (isExtension && fg('cc_maui_annotations_on_extensions')) {
229
+ // The chart's badge owns interaction. Anchors only supply geometry and annotation state.
230
+ return jsx(ExtensionAnnotation, {
231
+ id: id,
232
+ dataAttributes: overriddenData,
233
+ markRef: id === currentSelectedAnnotationId ? markRef : undefined
234
+ });
235
+ }
226
236
  return jsx(useBlockLevel ? 'div' : 'mark', {
227
237
  ref: id === currentSelectedAnnotationId ? markRef : undefined,
228
238
  id,
@@ -30,7 +30,7 @@ export const AnnotationsPositionContext = /*#__PURE__*/React.createContext({
30
30
  startPos: 1
31
31
  });
32
32
  export const AnnotationsWrapperInner = props => {
33
- var _providers$inlineComm, _providers$inlineComm2;
33
+ var _providers$inlineComm, _providers$inlineComm2, _providers$inlineComm3;
34
34
  const {
35
35
  children,
36
36
  rendererRef,
@@ -51,6 +51,7 @@ export const AnnotationsWrapperInner = props => {
51
51
  value: inlineCommentAnnotationsState
52
52
  }, /*#__PURE__*/React.createElement(AnnotationRangeProvider, {
53
53
  allowCommentsOnMedia: (_providers$inlineComm = providers === null || providers === void 0 ? void 0 : (_providers$inlineComm2 = providers.inlineComment) === null || _providers$inlineComm2 === void 0 ? void 0 : _providers$inlineComm2.allowCommentsOnMedia) !== null && _providers$inlineComm !== void 0 ? _providers$inlineComm : false,
54
+ hasBlockNodeSupport: Boolean(providers === null || providers === void 0 ? void 0 : (_providers$inlineComm3 = providers.inlineComment) === null || _providers$inlineComm3 === void 0 ? void 0 : _providers$inlineComm3.isBlockNodeSupported),
54
55
  isNestedRender: isNestedRender
55
56
  }, /*#__PURE__*/React.createElement(AnnotationHoverContext, null, /*#__PURE__*/React.createElement(AnnotationsContextWrapper, {
56
57
  createAnalyticsEvent: createAnalyticsEvent,
@@ -87,9 +87,10 @@ var RendererActions = /*#__PURE__*/function () {
87
87
  var to;
88
88
  var nodePos;
89
89
  var step;
90
+ var schema = this.schema;
90
91
  this.doc.descendants(function (node, pos) {
91
92
  var found = mark.isInSet(node.marks);
92
- if (found && node.type.name === 'media') {
93
+ if (found && isBlockAnnotationTarget(node, schema)) {
93
94
  nodePos = pos;
94
95
  }
95
96
  if (found && !from) {
@@ -184,13 +185,12 @@ var RendererActions = /*#__PURE__*/function () {
184
185
  key: "isRangeAnnotatable",
185
186
  value: function isRangeAnnotatable(range) {
186
187
  try {
187
- var _startContainer$paren, _endContainer$parentE;
188
188
  if (!range) {
189
189
  return false;
190
190
  }
191
191
  var startContainer = range.startContainer,
192
192
  endContainer = range.endContainer;
193
- if ((_startContainer$paren = startContainer.parentElement) !== null && _startContainer$paren !== void 0 && _startContainer$paren.closest('.ak-renderer-extension') || (_endContainer$parentE = endContainer.parentElement) !== null && _endContainer$parentE !== void 0 && _endContainer$parentE.closest('.ak-renderer-extension')) {
193
+ if (this.isInsideNestedExtensionRenderer(startContainer) || this.isInsideNestedExtensionRenderer(endContainer)) {
194
194
  return false;
195
195
  }
196
196
  return this.isValidAnnotationRange(range);
@@ -206,6 +206,38 @@ var RendererActions = /*#__PURE__*/function () {
206
206
  }
207
207
  }
208
208
 
209
+ /**
210
+ * A range only threatens a nested renderer's own document (e.g. a bodiedExtension's macro
211
+ * body, which renders its own nested `<Renderer>`) when it sits inside that nested renderer's
212
+ * `.ak-renderer-document`. Landing directly on the extension's own outer wrapper -- with no
213
+ * nested document in between -- must stay annotatable so the whole chart/extension can be
214
+ * targeted (MAUI-1256), rather than being rejected outright the way any range touching
215
+ * `.ak-renderer-extension` previously was.
216
+ *
217
+ * Behind `cc_maui_annotations_on_extensions` -- the same gate MAUI-1255 added for extension
218
+ * node-mark support -- to preserve the previous behaviour (reject anything touching
219
+ * `.ak-renderer-extension`) while the feature is off.
220
+ */
221
+ }, {
222
+ key: "isInsideNestedExtensionRenderer",
223
+ value: function isInsideNestedExtensionRenderer(container) {
224
+ // Preserve the legacy parent-based rejection while the gate is disabled.
225
+ if (!fg('cc_maui_annotations_on_extensions')) {
226
+ var _container$parentElem;
227
+ return !!((_container$parentElem = container.parentElement) !== null && _container$parentElem !== void 0 && _container$parentElem.closest('.ak-renderer-extension'));
228
+ }
229
+ var element = container instanceof Element ? container : container.parentElement;
230
+ if (!element) {
231
+ return false;
232
+ }
233
+ var extensionAncestor = element.closest('.ak-renderer-extension');
234
+ if (!extensionAncestor) {
235
+ return false;
236
+ }
237
+ var nestedDocument = element.closest('.ak-renderer-document');
238
+ return !!nestedDocument && extensionAncestor.contains(nestedDocument);
239
+ }
240
+
209
241
  // eslint-disable-next-line @repo/internal/deprecations/deprecation-ticket-required -- Ignored via go/ED-25883
210
242
  /**
211
243
  * This is replaced by `isRangeAnnotatable`.
@@ -0,0 +1,3 @@
1
+ /* eslint-disable @atlaskit/editor/no-re-export */
2
+
3
+ export { ExpandBodyProvider } from '../ui/utils/expand-body';
@@ -97,6 +97,11 @@ var ReactSerializer = /*#__PURE__*/function () {
97
97
  if (shouldSkipLinkMark(mark) || shouldSkipBorderMark(mark)) {
98
98
  return content;
99
99
  }
100
+ // Extension annotations are sibling anchors inside the stable extension shell.
101
+ // Wrapping the extension here would remount its iframe whenever marks change.
102
+ if (node.type.name === 'extension' && mark.type.name === 'annotation' && _this.allowAnnotations && fg('cc_maui_annotations_on_extensions')) {
103
+ return content;
104
+ }
100
105
  return _this.renderMark(markToReact(mark), _this.withMediaMarkProps(node, mark, _this.getMarkProps(mark, [], node)), "".concat(mark.type.name, "-").concat(index), content);
101
106
  }, serializedContent);
102
107
  return withExpandBodyBlock(node, currentPath, index, serialized);
@@ -549,6 +554,9 @@ var ReactSerializer = /*#__PURE__*/function () {
549
554
  var _this$getExtensionHei;
550
555
  var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
551
556
  return _objectSpread(_objectSpread({}, this.getProps(node, path)), {}, {
557
+ allowAnnotations: this.allowAnnotations,
558
+ allowAnnotationsDraftMode: this.surroundTextNodesWithTextWrapper,
559
+ extensionNode: node,
552
560
  extensionViewportSizes: this.extensionViewportSizes,
553
561
  hideExtensionKeysWhilePending: this.hideExtensionKeysWhilePending,
554
562
  nodeHeight: (_this$getExtensionHei = this.getExtensionHeight) === null || _this$getExtensionHei === void 0 ? void 0 : _this$getExtensionHei.call(this, node),
@@ -17,6 +17,7 @@ var AnnotationComponent = function AnnotationComponent(_ref) {
17
17
  annotationParentIds = _ref$annotationParent === void 0 ? [] : _ref$annotationParent,
18
18
  allowAnnotations = _ref.allowAnnotations,
19
19
  useBlockLevel = _ref.useBlockLevel,
20
+ isExtension = _ref.isExtension,
20
21
  isMediaInline = _ref.isMediaInline;
21
22
  var data = _objectSpread(_objectSpread({}, dataAttributes), buildAnnotationMarkDataAttributes({
22
23
  id: id,
@@ -36,7 +37,8 @@ var AnnotationComponent = function AnnotationComponent(_ref) {
36
37
  dataAttributes: data,
37
38
  annotationParentIds: annotationParentIds,
38
39
  annotationType: annotationType,
39
- useBlockLevel: useBlockLevel
40
+ useBlockLevel: useBlockLevel,
41
+ isExtension: isExtension
40
42
  }, children);
41
43
  }
42
44
  return (
@@ -0,0 +1,4 @@
1
+ ._154iu2gc{top:var(--ds-space-100,8px)}
2
+ ._1xi2u2gc{right:var(--ds-space-100,8px)}
3
+ ._kqswh2mm{position:relative}
4
+ ._kqswstnw{position:absolute}
@@ -0,0 +1,135 @@
1
+ /* extension-comments.tsx generated by @compiled/babel-plugin v3.0.2 */
2
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
+ import "./extension-comments.compiled.css";
4
+ import { ax, ix } from "@compiled/react/runtime";
5
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
6
+ import { AnnotationMarkStates, AnnotationTypes } from '@atlaskit/adf-schema/annotation';
7
+ import { VIEW_METHOD } from '@atlaskit/editor-common/analytics';
8
+ import { CommentBadgeNext } from '@atlaskit/editor-common/media-single';
9
+ import { AnnotationUpdateEvent } from '@atlaskit/editor-common/types';
10
+ import { useAnnotationManagerState } from '../../ui/annotations/contexts/AnnotationManagerContext';
11
+ import { useAnnotationRangeState } from '../../ui/annotations/contexts/AnnotationRangeContext';
12
+ import { useInlineCommentSubscriberContext } from '../../ui/annotations/hooks/use-inline-comment-subscriber';
13
+ import { useInlineCommentsFilter } from '../../ui/annotations/hooks/use-inline-comments-filter';
14
+ import AnnotationComponent from '../marks/annotation';
15
+ var containerStyles = null;
16
+ var annotationParentIds = [];
17
+ var annotationDataAttributes = {
18
+ 'data-renderer-mark': true,
19
+ 'data-block-mark': true
20
+ };
21
+ var badgeStyles = null;
22
+ var ExtensionCommentsEnabled = function ExtensionCommentsEnabled(_ref) {
23
+ var marks = _ref.marks,
24
+ children = _ref.children,
25
+ enabled = _ref.enabled,
26
+ allowAnnotations = _ref.allowAnnotations,
27
+ allowAnnotationsDraftMode = _ref.allowAnnotationsDraftMode,
28
+ startPos = _ref.startPos;
29
+ var _useAnnotationRangeSt = useAnnotationRangeState(),
30
+ hoverDraftDocumentPosition = _useAnnotationRangeSt.hoverDraftDocumentPosition;
31
+ var isDraft = Boolean(enabled && allowAnnotationsDraftMode && hoverDraftDocumentPosition && hoverDraftDocumentPosition.from + 1 === startPos);
32
+ var updateSubscriber = useInlineCommentSubscriberContext();
33
+ var annotationIds = useMemo(function () {
34
+ var _marks$filter$map;
35
+ return (_marks$filter$map = marks === null || marks === void 0 ? void 0 : marks.filter(function (mark) {
36
+ return mark.type.name === 'annotation';
37
+ }).map(function (mark) {
38
+ return mark.attrs.id;
39
+ })) !== null && _marks$filter$map !== void 0 ? _marks$filter$map : [];
40
+ }, [marks]);
41
+ var activeIds = useInlineCommentsFilter({
42
+ annotationIds: annotationIds,
43
+ filter: {
44
+ state: AnnotationMarkStates.ACTIVE
45
+ }
46
+ });
47
+ var _useState = useState(),
48
+ _useState2 = _slicedToArray(_useState, 2),
49
+ focusedId = _useState2[0],
50
+ setFocusedId = _useState2[1];
51
+ var _useState3 = useState(false),
52
+ _useState4 = _slicedToArray(_useState3, 2),
53
+ entered = _useState4[0],
54
+ setEntered = _useState4[1];
55
+ var _useAnnotationManager = useAnnotationManagerState(),
56
+ currentSelectedAnnotationId = _useAnnotationManager.currentSelectedAnnotationId;
57
+ var active = activeIds.some(function (id) {
58
+ return id === focusedId || id === currentSelectedAnnotationId;
59
+ });
60
+ useEffect(function () {
61
+ if (!updateSubscriber) {
62
+ return;
63
+ }
64
+ var onFocus = function onFocus(payload) {
65
+ return setFocusedId(payload === null || payload === void 0 ? void 0 : payload.annotationId);
66
+ };
67
+ var onBlur = function onBlur() {
68
+ return setFocusedId(undefined);
69
+ };
70
+ updateSubscriber.on(AnnotationUpdateEvent.SET_ANNOTATION_FOCUS, onFocus);
71
+ updateSubscriber.on(AnnotationUpdateEvent.REMOVE_ANNOTATION_FOCUS, onBlur);
72
+ return function () {
73
+ updateSubscriber.off(AnnotationUpdateEvent.SET_ANNOTATION_FOCUS, onFocus);
74
+ updateSubscriber.off(AnnotationUpdateEvent.REMOVE_ANNOTATION_FOCUS, onBlur);
75
+ };
76
+ }, [updateSubscriber]);
77
+ var onClick = useCallback(function (event) {
78
+ event.preventDefault();
79
+ event.stopPropagation();
80
+ // Anchor the thread to this chart, not an icon inside the badge or a nested renderer.
81
+ var extension = event.currentTarget.closest('.ak-renderer-extension');
82
+ if (extension && activeIds.length) {
83
+ updateSubscriber === null || updateSubscriber === void 0 || updateSubscriber.emit(AnnotationUpdateEvent.ON_ANNOTATION_CLICK, {
84
+ annotationIds: activeIds,
85
+ eventTarget: extension,
86
+ eventTargetType: 'extension',
87
+ viewMethod: VIEW_METHOD.BADGE
88
+ });
89
+ }
90
+ }, [activeIds, updateSubscriber]);
91
+ var onMouseEnter = useCallback(function () {
92
+ return setEntered(true);
93
+ }, []);
94
+ var onMouseLeave = useCallback(function () {
95
+ return setEntered(false);
96
+ }, []);
97
+ return /*#__PURE__*/React.createElement("div", {
98
+ "data-annotation-draft-mark": isDraft || undefined,
99
+ "data-renderer-mark": isDraft || undefined,
100
+ "data-renderer-start-pos": isDraft ? startPos : undefined,
101
+ className: ax(["_kqswh2mm"])
102
+ }, children, allowAnnotations && annotationIds.map(function (id) {
103
+ return /*#__PURE__*/React.createElement(AnnotationComponent, {
104
+ key: id,
105
+ id: id,
106
+ annotationType: AnnotationTypes.INLINE_COMMENT,
107
+ annotationParentIds: annotationParentIds,
108
+ allowAnnotations: true,
109
+ useBlockLevel: true,
110
+ isExtension: true,
111
+ dataAttributes: annotationDataAttributes
112
+ });
113
+ }), enabled && activeIds.length > 0 && updateSubscriber && /*#__PURE__*/React.createElement("div", {
114
+ className: ax(["_kqswstnw _154iu2gc _1xi2u2gc"])
115
+ }, /*#__PURE__*/React.createElement(CommentBadgeNext, {
116
+ status: active ? 'active' : entered ? 'entered' : 'default',
117
+ onClick: onClick,
118
+ onMouseEnter: onMouseEnter,
119
+ onMouseLeave: onMouseLeave
120
+ })));
121
+ };
122
+
123
+ /** Only node-aware provider-approved extensions receive comment visuals. */
124
+ export var ExtensionComments = function ExtensionComments(props) {
125
+ if (!props.enabled && !props.allowAnnotations) {
126
+ return /*#__PURE__*/React.createElement(React.Fragment, null, props.children);
127
+ }
128
+ return /*#__PURE__*/React.createElement(ExtensionCommentsEnabled, {
129
+ enabled: props.enabled,
130
+ allowAnnotations: props.allowAnnotations,
131
+ allowAnnotationsDraftMode: props.allowAnnotationsDraftMode,
132
+ startPos: props.startPos,
133
+ marks: props.marks
134
+ }, props.children);
135
+ };
@@ -1,10 +1,13 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
+ 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; }
4
+ 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; }
2
5
  /**
3
6
  * @jsxRuntime classic
4
7
  * @jsx jsx
5
8
  */
6
9
 
7
- import React, { useEffect, useRef } from 'react';
10
+ import React, { useCallback, useContext, useEffect, useMemo, useRef } from 'react';
8
11
 
9
12
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
10
13
  import { jsx, css } from '@emotion/react';
@@ -13,8 +16,12 @@ import { overflowShadow } from '@atlaskit/editor-common/ui';
13
16
  import { fg } from '@atlaskit/platform-feature-flags/fg';
14
17
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
15
18
  import { RendererCssClassName } from '../../consts';
19
+ import { ProvidersContext } from '../../ui/annotations/context';
20
+ import { useAnnotationHoverDispatch } from '../../ui/annotations/contexts/AnnotationHoverContext';
21
+ import { useAnnotationRangeDispatch } from '../../ui/annotations/contexts/AnnotationRangeContext';
16
22
  import ExtensionRenderer from '../../ui/ExtensionRenderer';
17
23
  import { calcBreakoutWidthCss } from '../utils/breakout';
24
+ import { ExtensionComments } from './extension-comments';
18
25
  var FORGE_EXTENSION_TYPE = 'com.atlassian.ecosystem';
19
26
  /**
20
27
  * Mirrors `FORGE_INLINE_BODIED_PARAM` in `@atlassian/xen-editor-provider`. Duplicated rather than
@@ -69,7 +76,7 @@ var FireExtensionAsInlineAnalytics = function FireExtensionAsInlineAnalytics(_re
69
76
  return null;
70
77
  };
71
78
  export var renderExtension = function renderExtension(content, layout) {
72
- var _node$parameters, _node$parameters2;
79
+ var _node$parameters, _node$parameters2, _options$dataAttribut;
73
80
  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
74
81
  var removeOverflow = arguments.length > 3 ? arguments[3] : undefined;
75
82
  var extensionId = arguments.length > 4 ? arguments[4] : undefined;
@@ -157,11 +164,17 @@ export var renderExtension = function renderExtension(content, layout) {
157
164
  },
158
165
  "data-layout": layout,
159
166
  "data-local-id": localId,
167
+ "data-renderer-start-pos": (_options$dataAttribut = options.dataAttributes) === null || _options$dataAttribut === void 0 ? void 0 : _options$dataAttribut['data-renderer-start-pos'],
160
168
  "data-testid": "extension--wrapper",
161
169
  "data-node-type": "extension",
170
+ "data-inline-comments-target": options.isCommentTarget || undefined,
162
171
  "data-top-level": isTopLevel || undefined,
163
172
  "data-forge-inline": isNativeForgeInline || undefined,
164
- "data-migrated-inline": isMigratedInlineBodied || undefined
173
+ "data-migrated-inline": isMigratedInlineBodied || undefined,
174
+ onBlur: options.onBlur,
175
+ onFocus: options.onFocus,
176
+ onMouseEnter: options.onMouseEnter,
177
+ onMouseLeave: options.onMouseLeave
165
178
  }, jsx("div", {
166
179
  tabIndex: options.tabIndex
167
180
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
@@ -175,6 +188,7 @@ export var renderExtension = function renderExtension(content, layout) {
175
188
  }, extensionDiv) : extensionDiv;
176
189
  };
177
190
  var Extension = function Extension(props) {
191
+ var _providers$inlineComm, _props$dataAttributes;
178
192
  var text = props.text,
179
193
  _props$layout = props.layout,
180
194
  layout = _props$layout === void 0 ? 'default' : _props$layout,
@@ -187,6 +201,57 @@ var Extension = function Extension(props) {
187
201
  nodeHeight = props.nodeHeight,
188
202
  localId = props.localId,
189
203
  isInsideOfInlineExtension = props.isInsideOfInlineExtension;
204
+ var providers = useContext(ProvidersContext);
205
+ var _useAnnotationRangeDi = useAnnotationRangeDispatch(),
206
+ setHoverTarget = _useAnnotationRangeDi.setHoverTarget;
207
+ var _useAnnotationHoverDi = useAnnotationHoverDispatch(),
208
+ cancelTimeout = _useAnnotationHoverDi.cancelTimeout,
209
+ initiateTimeout = _useAnnotationHoverDi.initiateTimeout,
210
+ setIsWithinRange = _useAnnotationHoverDi.setIsWithinRange;
211
+ var isBlockNodeSupported = providers === null || providers === void 0 || (_providers$inlineComm = providers.inlineComment) === null || _providers$inlineComm === void 0 ? void 0 : _providers$inlineComm.isBlockNodeSupported;
212
+ var isCommentTarget = useMemo(function () {
213
+ return Boolean(fg('cc_maui_annotations_on_extensions') && props.extensionNode && (isBlockNodeSupported === null || isBlockNodeSupported === void 0 ? void 0 : isBlockNodeSupported(props.extensionNode)) === true);
214
+ }, [props.extensionNode, isBlockNodeSupported]);
215
+ var isFullPageRenderer = props.rendererAppearance === 'full-page' || props.rendererAppearance === 'full-width';
216
+ var onMouseEnter = useCallback(function (event) {
217
+ cancelTimeout();
218
+ if (event.buttons === 0) {
219
+ setHoverTarget === null || setHoverTarget === void 0 || setHoverTarget(event.currentTarget);
220
+ setIsWithinRange(true);
221
+ }
222
+ }, [cancelTimeout, setHoverTarget, setIsWithinRange]);
223
+ var onMouseLeave = useCallback(function () {
224
+ return initiateTimeout();
225
+ }, [initiateTimeout]);
226
+ var onFocus = useCallback(function (event) {
227
+ if (event.currentTarget.contains(event.relatedTarget)) {
228
+ return;
229
+ }
230
+ cancelTimeout();
231
+ setHoverTarget === null || setHoverTarget === void 0 || setHoverTarget(event.currentTarget);
232
+ setIsWithinRange(true);
233
+ }, [cancelTimeout, setHoverTarget, setIsWithinRange]);
234
+ var onBlur = useCallback(function (event) {
235
+ if (!event.currentTarget.contains(event.relatedTarget)) {
236
+ initiateTimeout();
237
+ }
238
+ }, [initiateTimeout]);
239
+ var commentTargetOptions = isCommentTarget && isFullPageRenderer ? {
240
+ isCommentTarget: true,
241
+ onBlur: onBlur,
242
+ onFocus: onFocus,
243
+ onMouseEnter: onMouseEnter,
244
+ onMouseLeave: onMouseLeave
245
+ } : {
246
+ isCommentTarget: isCommentTarget
247
+ };
248
+ var commentProps = {
249
+ enabled: isCommentTarget,
250
+ allowAnnotations: props.allowAnnotations && fg('cc_maui_annotations_on_extensions'),
251
+ allowAnnotationsDraftMode: props.allowAnnotationsDraftMode,
252
+ startPos: (_props$dataAttributes = props.dataAttributes) === null || _props$dataAttributes === void 0 ? void 0 : _props$dataAttributes['data-renderer-start-pos'],
253
+ marks: props.marks
254
+ };
190
255
  return jsx(ExtensionRenderer
191
256
  // Ignored via go/ees005
192
257
  // eslint-disable-next-line react/jsx-props-no-spreading
@@ -199,13 +264,20 @@ var Extension = function Extension(props) {
199
264
  try {
200
265
  // Return the result directly if it's a valid JSX.Element
201
266
  if (result && /*#__PURE__*/React.isValidElement(result)) {
202
- return renderExtension(result, layout, {
267
+ return renderExtension(jsx(ExtensionComments, {
268
+ enabled: commentProps.enabled,
269
+ allowAnnotations: commentProps.allowAnnotations,
270
+ allowAnnotationsDraftMode: commentProps.allowAnnotationsDraftMode,
271
+ startPos: commentProps.startPos,
272
+ marks: commentProps.marks
273
+ }, result), layout, _objectSpread({
274
+ dataAttributes: props.dataAttributes,
203
275
  isTopLevel: path.length < 1,
204
276
  handleRef: handleRef,
205
277
  shadowClassNames: shadowClassNames,
206
278
  tabIndex: props.tabIndex,
207
279
  rendererAppearance: props.rendererAppearance
208
- }, undefined, parameters === null || parameters === void 0 ? void 0 : parameters.extensionId, extensionViewportSizes, nodeHeight, localId, undefined, undefined, isInsideOfInlineExtension);
280
+ }, commentTargetOptions), undefined, parameters === null || parameters === void 0 ? void 0 : parameters.extensionId, extensionViewportSizes, nodeHeight, localId, undefined, undefined, isInsideOfInlineExtension);
209
281
  }
210
282
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
211
283
  } catch (e) {
@@ -217,13 +289,20 @@ var Extension = function Extension(props) {
217
289
  }
218
290
 
219
291
  // Always return default content if anything goes wrong
220
- return renderExtension(text || 'extension', layout, {
292
+ return renderExtension(jsx(ExtensionComments, {
293
+ enabled: commentProps.enabled,
294
+ allowAnnotations: commentProps.allowAnnotations,
295
+ allowAnnotationsDraftMode: commentProps.allowAnnotationsDraftMode,
296
+ startPos: commentProps.startPos,
297
+ marks: commentProps.marks
298
+ }, text || 'extension'), layout, _objectSpread({
299
+ dataAttributes: props.dataAttributes,
221
300
  isTopLevel: path.length < 1,
222
301
  handleRef: handleRef,
223
302
  shadowClassNames: shadowClassNames,
224
303
  tabIndex: props.tabIndex,
225
304
  rendererAppearance: props.rendererAppearance
226
- }, undefined, parameters === null || parameters === void 0 ? void 0 : parameters.extensionId, extensionViewportSizes, nodeHeight, localId, undefined, undefined, isInsideOfInlineExtension);
305
+ }, commentTargetOptions), undefined, parameters === null || parameters === void 0 ? void 0 : parameters.extensionId, extensionViewportSizes, nodeHeight, localId, undefined, undefined, isInsideOfInlineExtension);
227
306
  });
228
307
  };
229
308
  var _default_1 = overflowShadow(Extension, {