@atlaskit/editor-common 125.2.1 → 125.4.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 (95) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/dist/cjs/element-browser/components/ElementBrowserLoader.js +8 -31
  3. package/dist/cjs/extensions/buildMenuItem.js +6 -3
  4. package/dist/cjs/extensions/extension-handlers.js +17 -96
  5. package/dist/cjs/floating-toolbar/DropdownMenuExtensionItems.js +4 -25
  6. package/dist/cjs/icons/index.js +10 -33
  7. package/dist/cjs/monitoring/error.js +1 -1
  8. package/dist/cjs/quick-insert/CompactQuickInsertMenuItem.compiled.css +0 -1
  9. package/dist/cjs/quick-insert/CompactQuickInsertMenuItem.js +22 -28
  10. package/dist/cjs/quick-insert/QuickInsertHoverPreview.compiled.css +42 -1
  11. package/dist/cjs/quick-insert/QuickInsertHoverPreview.js +147 -68
  12. package/dist/cjs/quick-insert/QuickInsertMenuItem.js +4 -0
  13. package/dist/cjs/quick-insert/QuickInsertMenuSection.js +11 -4
  14. package/dist/cjs/quick-insert/assets/index.js +257 -888
  15. package/dist/cjs/quick-insert/confluence-attribution-icon.js +18 -0
  16. package/dist/cjs/quick-insert/jira-attribution-icon.js +18 -0
  17. package/dist/cjs/quick-insert/messages.js +30 -0
  18. package/dist/cjs/quick-insert/preview.js +5 -0
  19. package/dist/cjs/quick-insert/snippetPreviewImageUrls.js +43 -43
  20. package/dist/cjs/quick-insert/use-menu-list-height.js +58 -0
  21. package/dist/cjs/quick-insert/use-menu-popup-sizing.js +60 -0
  22. package/dist/cjs/toolbar-flag-check.js +2 -2
  23. package/dist/cjs/ui/DropList/index.js +1 -1
  24. package/dist/cjs/ui/Mention/mention-with-profilecard.js +19 -30
  25. package/dist/cjs/ui/Popup/index.js +101 -17
  26. package/dist/es2019/element-browser/components/ElementBrowserLoader.js +2 -16
  27. package/dist/es2019/extensions/buildMenuItem.js +5 -1
  28. package/dist/es2019/extensions/extension-handlers.js +15 -70
  29. package/dist/es2019/floating-toolbar/DropdownMenuExtensionItems.js +2 -16
  30. package/dist/es2019/icons/index.js +3 -17
  31. package/dist/es2019/monitoring/error.js +1 -1
  32. package/dist/es2019/quick-insert/CompactQuickInsertMenuItem.compiled.css +0 -1
  33. package/dist/es2019/quick-insert/CompactQuickInsertMenuItem.js +20 -29
  34. package/dist/es2019/quick-insert/QuickInsertHoverPreview.compiled.css +42 -1
  35. package/dist/es2019/quick-insert/QuickInsertHoverPreview.js +130 -55
  36. package/dist/es2019/quick-insert/QuickInsertMenuItem.js +4 -0
  37. package/dist/es2019/quick-insert/QuickInsertMenuSection.js +11 -4
  38. package/dist/es2019/quick-insert/assets/index.js +66 -386
  39. package/dist/es2019/quick-insert/confluence-attribution-icon.js +10 -0
  40. package/dist/es2019/quick-insert/jira-attribution-icon.js +10 -0
  41. package/dist/es2019/quick-insert/messages.js +30 -0
  42. package/dist/es2019/quick-insert/preview.js +1 -0
  43. package/dist/es2019/quick-insert/snippetPreviewImageUrls.js +43 -43
  44. package/dist/es2019/quick-insert/use-menu-list-height.js +37 -0
  45. package/dist/es2019/quick-insert/use-menu-popup-sizing.js +49 -0
  46. package/dist/es2019/toolbar-flag-check.js +2 -2
  47. package/dist/es2019/ui/DropList/index.js +1 -1
  48. package/dist/es2019/ui/Mention/mention-with-profilecard.js +12 -15
  49. package/dist/es2019/ui/Popup/index.js +89 -7
  50. package/dist/esm/element-browser/components/ElementBrowserLoader.js +6 -28
  51. package/dist/esm/extensions/buildMenuItem.js +6 -3
  52. package/dist/esm/extensions/extension-handlers.js +17 -97
  53. package/dist/esm/floating-toolbar/DropdownMenuExtensionItems.js +4 -24
  54. package/dist/esm/icons/index.js +7 -29
  55. package/dist/esm/monitoring/error.js +1 -1
  56. package/dist/esm/quick-insert/CompactQuickInsertMenuItem.compiled.css +0 -1
  57. package/dist/esm/quick-insert/CompactQuickInsertMenuItem.js +23 -29
  58. package/dist/esm/quick-insert/QuickInsertHoverPreview.compiled.css +42 -1
  59. package/dist/esm/quick-insert/QuickInsertHoverPreview.js +150 -68
  60. package/dist/esm/quick-insert/QuickInsertMenuItem.js +4 -0
  61. package/dist/esm/quick-insert/QuickInsertMenuSection.js +11 -4
  62. package/dist/esm/quick-insert/assets/index.js +194 -764
  63. package/dist/esm/quick-insert/confluence-attribution-icon.js +12 -0
  64. package/dist/esm/quick-insert/jira-attribution-icon.js +12 -0
  65. package/dist/esm/quick-insert/messages.js +30 -0
  66. package/dist/esm/quick-insert/preview.js +1 -0
  67. package/dist/esm/quick-insert/snippetPreviewImageUrls.js +43 -43
  68. package/dist/esm/quick-insert/use-menu-list-height.js +51 -0
  69. package/dist/esm/quick-insert/use-menu-popup-sizing.js +53 -0
  70. package/dist/esm/toolbar-flag-check.js +2 -2
  71. package/dist/esm/ui/DropList/index.js +1 -1
  72. package/dist/esm/ui/Mention/mention-with-profilecard.js +16 -25
  73. package/dist/esm/ui/Popup/index.js +101 -17
  74. package/dist/types/extensions/types/extension-manifest.d.ts +5 -0
  75. package/dist/types/extensions/types/utils.d.ts +2 -0
  76. package/dist/types/icons/index.d.ts +3 -5
  77. package/dist/types/provider-factory/profile-card-provider.d.ts +14 -1
  78. package/dist/types/provider-factory/quick-insert-provider.d.ts +3 -0
  79. package/dist/types/quick-insert/CompactQuickInsertMenuItem.d.ts +1 -1
  80. package/dist/types/quick-insert/QuickInsertHoverPreview.d.ts +7 -6
  81. package/dist/types/quick-insert/QuickInsertMenuItem.d.ts +7 -2
  82. package/dist/types/quick-insert/assets/index.d.ts +32 -34
  83. package/dist/types/quick-insert/confluence-attribution-icon.d.ts +3 -0
  84. package/dist/types/quick-insert/jira-attribution-icon.d.ts +3 -0
  85. package/dist/types/quick-insert/messages.d.ts +5 -2
  86. package/dist/types/quick-insert/preview.d.ts +16 -0
  87. package/dist/types/quick-insert/use-menu-list-height.d.ts +6 -0
  88. package/dist/types/quick-insert/use-menu-popup-sizing.d.ts +11 -0
  89. package/dist/types/ui/Popup/index.d.ts +11 -0
  90. package/package.json +6 -6
  91. package/quick-insert/confluence-attribution-icon/package.json +10 -0
  92. package/quick-insert/jira-attribution-icon/package.json +10 -0
  93. package/quick-insert/preview/package.json +10 -0
  94. package/quick-insert/use-menu-list-height/package.json +10 -0
  95. package/quick-insert/use-menu-popup-sizing/package.json +10 -0
@@ -1,109 +1,109 @@
1
- const DAM_ASSET_LINK = 'https://dam-cdn.atl.orangelogic.com/AssetLink';
1
+ const DAM_CDN_LINK = 'https://dam-cdn.atl.orangelogic.com/CDNLink';
2
2
  const snippetPreviewImageUrlsByKey = {
3
3
  // Action items
4
4
  '019e5cd9-5ca1-7258-befd-4f50d491bb42': {
5
- light: `${DAM_ASSET_LINK}/qq0503l11x2ub0506p2s046o2ep5gw1w.png`,
6
- dark: `${DAM_ASSET_LINK}/i77e8128ir0e34t8w11mar77ngq53o00.png`
5
+ light: `${DAM_CDN_LINK}/AT12OVLE.png`,
6
+ dark: `${DAM_CDN_LINK}/AT12OVJI.png`
7
7
  },
8
8
  // Bug report
9
9
  '019e5cd9-5ca1-7258-befd-1c3c59b0aa00': {
10
- light: `${DAM_ASSET_LINK}/221f56s64c186314ka8a7uaj7m4di32l.png`,
11
- dark: `${DAM_ASSET_LINK}/1c86e0v3ygh5ct5600luum0w67unpa23.png`
10
+ light: `${DAM_CDN_LINK}/AT12OVMN.png`,
11
+ dark: `${DAM_CDN_LINK}/AT12OVJ6.png`
12
12
  },
13
13
  // Campaign brief
14
14
  '019e5cd9-5ca1-7258-befd-398bb4e40f15': {
15
- light: `${DAM_ASSET_LINK}/55j1ie55ad1nal6t3awxxui52rp47wn1.png`,
16
- dark: `${DAM_ASSET_LINK}/36h5jgou0pw7v532411mbl501b8de4hm.png`
15
+ light: `${DAM_CDN_LINK}/AT12OVMY.png`,
16
+ dark: `${DAM_CDN_LINK}/AT12OVJE.png`
17
17
  },
18
18
  // Colorful layout
19
19
  '019e5cd9-5ca1-7258-befd-53b6eec19427': {
20
- light: `${DAM_ASSET_LINK}/53j8kth40pkysk4rqs64038r4cw2i867.png`,
21
- dark: `${DAM_ASSET_LINK}/k7ofa1q6r10dydey04780514v75j3fvx.png`
20
+ light: `${DAM_CDN_LINK}/AT12OVN6.png`,
21
+ dark: `${DAM_CDN_LINK}/AT12OVIG.png`
22
22
  },
23
23
  // Colorful numbered table
24
24
  '019e5cd9-5ca1-7258-befd-70a282facf16': {
25
- light: `${DAM_ASSET_LINK}/f02n6041opl0rqvbygs2hv162mt6jq3u.png`,
26
- dark: `${DAM_ASSET_LINK}/s63mw28263h0oi8we3x052m7rsw2o1k8.png`
25
+ light: `${DAM_CDN_LINK}/AT12OVN7.png`,
26
+ dark: `${DAM_CDN_LINK}/AT12OVJL.png`
27
27
  },
28
28
  // Colorful summary
29
29
  '019e5cd9-5ca1-7258-befd-7e200502de8e': {
30
- light: `${DAM_ASSET_LINK}/242qv11f2p7y1u461v71glq85x76b5gp.png`,
31
- dark: `${DAM_ASSET_LINK}/jeaj3a8g7x61syy45d73c2223647b14j.png`
30
+ light: `${DAM_CDN_LINK}/AT12OVN4.png`,
31
+ dark: `${DAM_CDN_LINK}/AT12OVIE.png`
32
32
  },
33
33
  // Colorful table
34
34
  '019e5cd9-5ca1-7258-befd-5524d394ba0a': {
35
- light: `${DAM_ASSET_LINK}/8w8571k707dlx556rxr3hs72gs5q4m42.png`,
36
- dark: `${DAM_ASSET_LINK}/wkt55v21i5q520pqxjh31x5g2j8upth4.png`
35
+ light: `${DAM_CDN_LINK}/AT12OVMJ.png`,
36
+ dark: `${DAM_CDN_LINK}/AT12OVJM.png`
37
37
  },
38
38
  // Competitive snapshot
39
39
  '019e5cd9-5ca1-7258-befd-40d1947b7b84': {
40
- light: `${DAM_ASSET_LINK}/k5cm81s2h7i41d4d6832n67c2m767h6t.png`,
41
- dark: `${DAM_ASSET_LINK}/ks38nc26451n7384d52413lck2qhq4e6.png`
40
+ light: `${DAM_CDN_LINK}/AT12OVMR.png`,
41
+ dark: `${DAM_CDN_LINK}/AT12OVJC.png`
42
42
  },
43
43
  // Criteria rubric
44
44
  '019e5cd9-5ca1-7258-befd-84723a493931': {
45
- light: `${DAM_ASSET_LINK}/n00f5ur678kbqdqjj5e13xpij6u3kkuq.png`,
46
- dark: `${DAM_ASSET_LINK}/54k2y2f7n2tpg2n12is326376102c3b5.png`
45
+ light: `${DAM_CDN_LINK}/AT12OVMA.png`,
46
+ dark: `${DAM_CDN_LINK}/AT12OVJ1.png`
47
47
  },
48
48
  // Customer quote
49
49
  '019e5cd9-5ca1-7258-befd-5fcf6165870f': {
50
- light: `${DAM_ASSET_LINK}/k8q5l4htp63652mhw572ed6chren37mv.png`,
51
- dark: `${DAM_ASSET_LINK}/y0leijw14xp7mdpi3265xn0d5ymo5lfm.png`
50
+ light: `${DAM_CDN_LINK}/AT12OVLF.png`,
51
+ dark: `${DAM_CDN_LINK}/AT12OVJK.png`
52
52
  },
53
53
  // Decision log
54
54
  '019e5cd9-5ca1-7258-befd-30c6e8712ba4': {
55
- light: `${DAM_ASSET_LINK}/4vuxracm3c33555h1u4ug65q55267574.png`,
56
- dark: `${DAM_ASSET_LINK}/5445044f626dcb58dbc7s6axr32e4ywl.png`
55
+ light: `${DAM_CDN_LINK}/AT12OVMT.png`,
56
+ dark: `${DAM_CDN_LINK}/AT12OVJ9.png`
57
57
  },
58
58
  // Launch checklist
59
59
  '019e5cd9-5ca1-7258-befd-3ce1c551015e': {
60
- light: `${DAM_ASSET_LINK}/1o0gj47oprg341fe6iip8fdx8561t54n.png`,
61
- dark: `${DAM_ASSET_LINK}/lay6kpn21b264q2q8144h3s18uwjud0f.png`
60
+ light: `${DAM_CDN_LINK}/AT12OVKW.png`,
61
+ dark: `${DAM_CDN_LINK}/AT12OVHN.png`
62
62
  },
63
63
  // Meeting agenda
64
64
  '019e5cd9-5ca1-7258-befd-47559a8d7cfc': {
65
- light: `${DAM_ASSET_LINK}/2hn6q5dt118vwyqi438725l141u70fb8.png`,
66
- dark: `${DAM_ASSET_LINK}/r4l0ydb7ujg4lms6n0wrrnsmsd1x65kw.png`
65
+ light: `${DAM_CDN_LINK}/AT12OVMU.png`,
66
+ dark: `${DAM_CDN_LINK}/AT12OVJD.png`
67
67
  },
68
68
  // Project status snapshot
69
69
  '019e5cd9-5ca1-7258-befd-2943939d1b79': {
70
- light: `${DAM_ASSET_LINK}/qk6emfe0oa2260ldt11748672gs65y1l.png`,
71
- dark: `${DAM_ASSET_LINK}/tt36rsll4cmq4607ik7g2d10fxmysyt4.png`
70
+ light: `${DAM_CDN_LINK}/AT12OVMO.png`,
71
+ dark: `${DAM_CDN_LINK}/AT12OVJU.png`
72
72
  },
73
73
  // Pros and cons
74
74
  '019e5cd9-5ca1-7258-befd-6db9658d75f4': {
75
- light: `${DAM_ASSET_LINK}/22078yl6viws8rc3au187m76x07xcu61.png`,
76
- dark: `${DAM_ASSET_LINK}/4tfd6w50y4yxfh4ks75w5ql04u17n7ub.png`
75
+ light: `${DAM_CDN_LINK}/AT12OVN5.png`,
76
+ dark: `${DAM_CDN_LINK}/AT12OVHY.png`
77
77
  },
78
78
  // Quick project update
79
79
  '019e5cd9-5ca1-7258-befd-820ce1acd7a0': {
80
- light: `${DAM_ASSET_LINK}/i8cfkp8v6716121f0w054g85mkw15wgu.png`,
81
- dark: `${DAM_ASSET_LINK}/x7a25y5f33ok60871t31e1my5c7880cr.png`
80
+ light: `${DAM_CDN_LINK}/AT12OVNA.png`,
81
+ dark: `${DAM_CDN_LINK}/AT12OVI5.png`
82
82
  },
83
83
  // Risks and assumptions
84
84
  '019e5cd9-5ca1-7258-befd-2da95ce98772': {
85
- light: `${DAM_ASSET_LINK}/yl7w10ms70ptlodhc703f6byo3wf7xty.png`,
86
- dark: `${DAM_ASSET_LINK}/mn14wqw150cu05w3s358w3f2f1vfgv7r.png`
85
+ light: `${DAM_CDN_LINK}/AT12OVMQ.png`,
86
+ dark: `${DAM_CDN_LINK}/AT12OVJ7.png`
87
87
  },
88
88
  // Roles and responsibilities matrix
89
89
  '019e5cd9-5ca1-7258-befd-37cd3a06776d': {
90
- light: `${DAM_ASSET_LINK}/67hs5t8u4t63c4fepm6ho1c4d5u12bed.png`,
91
- dark: `${DAM_ASSET_LINK}/wj5s3dy5nvb810t87f7x45cie88783h6.png`
90
+ light: `${DAM_CDN_LINK}/AT12OVM8.png`,
91
+ dark: `${DAM_CDN_LINK}/AT12OVHG.png`
92
92
  },
93
93
  // Run sheet
94
94
  '019e5cd9-5ca1-7258-befd-4a9979f87235': {
95
- light: `${DAM_ASSET_LINK}/tt0n285m6jl5lxb46c5v4fn856540351.png`,
96
- dark: `${DAM_ASSET_LINK}/qcrcqcs14753208xqw1j8r38mgs57w2f.png`
95
+ light: `${DAM_CDN_LINK}/AT12OVMZ.png`,
96
+ dark: `${DAM_CDN_LINK}/AT12OVJB.png`
97
97
  },
98
98
  // Started → Now
99
99
  '019e5cd9-5ca1-7258-befd-74fb1585da6f': {
100
- light: `${DAM_ASSET_LINK}/5ggat8yryusxvaqj3o800t8v6hcyh22v.png`,
101
- dark: `${DAM_ASSET_LINK}/287u8yil1jb1j5p1fih0141h07k2f64w.png`
100
+ light: `${DAM_CDN_LINK}/AT12OVN8.png`,
101
+ dark: `${DAM_CDN_LINK}/AT12OVJQ.png`
102
102
  },
103
103
  // Weekly calendar
104
104
  '019e5cd9-5ca1-7258-befd-580c2c95a0a0': {
105
- light: `${DAM_ASSET_LINK}/na153u604p852n54aji7aj1gf14431o7.png`,
106
- dark: `${DAM_ASSET_LINK}/sw7m5s5ay718h025c6ed3gaq63orv4gu.png`
105
+ light: `${DAM_CDN_LINK}/AT12OVN2.png`,
106
+ dark: `${DAM_CDN_LINK}/AT12OVIJ.png`
107
107
  }
108
108
  };
109
109
  export const getSnippetPreviewImageUrls = snippetKey => Object.prototype.hasOwnProperty.call(snippetPreviewImageUrlsByKey, snippetKey) ? snippetPreviewImageUrlsByKey[snippetKey] : undefined;
@@ -0,0 +1,37 @@
1
+ import { useCallback, useLayoutEffect, useRef, useState } from 'react';
2
+ /** Keep the list viewport in sync with measured rows, including short search results. */
3
+ export function useMenuListHeight(cache, rowCount, rowKeySignature) {
4
+ const [height, setHeight] = useState(() => Array.from({
5
+ length: rowCount
6
+ }, (_, index) => cache.rowHeight({
7
+ index
8
+ })).reduce((sum, value) => sum + value, 0));
9
+ const frame = useRef();
10
+ const updateHeight = useCallback(() => {
11
+ if (frame.current !== undefined) {
12
+ cancelAnimationFrame(frame.current);
13
+ }
14
+ // CellMeasurer updates its cache during commit. Read it after all rows have measured.
15
+ frame.current = requestAnimationFrame(() => {
16
+ frame.current = undefined;
17
+ const total = Array.from({
18
+ length: rowCount
19
+ }, (_, index) => cache.rowHeight({
20
+ index
21
+ })).reduce((sum, height) => sum + height, 0);
22
+ setHeight(total);
23
+ });
24
+ }, [cache, rowCount]);
25
+ useLayoutEffect(() => {
26
+ updateHeight();
27
+ return () => {
28
+ if (frame.current !== undefined) {
29
+ cancelAnimationFrame(frame.current);
30
+ }
31
+ };
32
+ }, [rowKeySignature, updateHeight]);
33
+ return {
34
+ height,
35
+ updateHeight
36
+ };
37
+ }
@@ -0,0 +1,49 @@
1
+ import { useLayoutEffect, useState } from 'react';
2
+ import { bind } from 'bind-event-listener';
3
+ import rafSchedule from 'raf-schd';
4
+ import { findOverflowScrollParent } from '../ui/Popup/utils';
5
+ /** Constrain menu height to the available space; Popup chooses placement. */
6
+ export function useMenuPopupSizing({
7
+ target,
8
+ boundariesElement,
9
+ scrollableElement,
10
+ maxHeight,
11
+ offset,
12
+ isOpen = true
13
+ }) {
14
+ const [height, setHeight] = useState(maxHeight);
15
+ useLayoutEffect(() => {
16
+ const view = target === null || target === void 0 ? void 0 : target.ownerDocument.defaultView;
17
+ if (!target || !view || !isOpen) {
18
+ return;
19
+ }
20
+ const boundary = boundariesElement || target.ownerDocument.body;
21
+ const scrollParent = scrollableElement || findOverflowScrollParent(target);
22
+ const update = () => {
23
+ const rect = target.getBoundingClientRect();
24
+ const bounds = boundary.getBoundingClientRect();
25
+ const above = Math.max(0, rect.top - (bounds.top - boundary.scrollTop) - offset);
26
+ const below = Math.max(0, bounds.bottom - rect.bottom - offset);
27
+ const space = below >= maxHeight ? below : Math.max(above, below);
28
+ // Popup rounds its position up to a CSS pixel. Reserve that pixel at the edge.
29
+ const available = Math.max(0, Math.floor(space) - 1);
30
+ setHeight(Math.min(maxHeight, available));
31
+ };
32
+ const schedule = rafSchedule(update);
33
+ update();
34
+ const unbindResize = bind(view, {
35
+ type: 'resize',
36
+ listener: schedule
37
+ });
38
+ const unbindScroll = scrollParent ? bind(scrollParent, {
39
+ type: 'scroll',
40
+ listener: schedule
41
+ }) : undefined;
42
+ return () => {
43
+ unbindResize();
44
+ unbindScroll === null || unbindScroll === void 0 ? void 0 : unbindScroll();
45
+ schedule.cancel();
46
+ };
47
+ }, [target, boundariesElement, scrollableElement, maxHeight, offset, isOpen]);
48
+ return height;
49
+ }
@@ -1,2 +1,2 @@
1
- import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
2
- export const areToolbarFlagsEnabled = isNewToolbarEnabled => Boolean(expValEqualsNoExposure('platform_editor_controls', 'cohort', 'variant1') || isNewToolbarEnabled);
1
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
2
+ export const areToolbarFlagsEnabled = isNewToolbarEnabled => Boolean(editorExperiment('platform_editor_controls', 'variant1') || isNewToolbarEnabled);
@@ -14,7 +14,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
14
14
  import { fg } from '@atlaskit/platform-feature-flags/fg';
15
15
  import Layer from '../Layer';
16
16
  const packageName = "@atlaskit/editor-common";
17
- const packageVersion = "125.2.0";
17
+ const packageVersion = "125.3.0";
18
18
  const halfFocusRing = 1;
19
19
  const dropOffset = '0, 8';
20
20
  const fadeIn = keyframes({
@@ -1,7 +1,5 @@
1
1
  import React, { useMemo } from 'react';
2
2
  import Loadable from 'react-loadable';
3
- // oxlint-disable-next-line @atlassian/no-restricted-imports
4
- import { lazy, LazySuspense } from 'react-loosely-lazy';
5
3
  import ResourcedMention from '@atlaskit/mention/resourced-mention';
6
4
  import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
7
5
  import { fg } from '@atlaskit/platform-feature-flags/fg';
@@ -13,21 +11,12 @@ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
13
11
  // Lazy-loaded so the agent profile card chunk (and its `@atlaskit/rovo-agent-components`
14
12
  // dependency) stays off the critical path — it is only fetched when an agent mention
15
13
  // (`userType === 'APP'`) actually renders, never for person mentions.
16
- const loadAgentProfileCardTrigger = () => import( /* webpackChunkName: "@atlaskit-internal_profilecard/agent-profile-card-trigger" */
17
- '@atlaskit/profilecard/agent-profile-card-trigger').then(mod => mod.AgentProfileCardTrigger);
18
- const AgentProfileCardTriggerLazy = lazy(() => import( /* webpackChunkName: "@atlaskit-internal_profilecard/agent-profile-card-trigger" */
19
- '@atlaskit/profilecard/agent-profile-card-trigger').then(mod => mod.AgentProfileCardTrigger));
20
- AgentProfileCardTriggerLazy.displayName = 'lazy(AgentProfileCardTrigger)';
21
- const AgentProfileCardTriggerLoadable = Loadable({
22
- loader: loadAgentProfileCardTrigger,
14
+ // Uses react-loadable to match editor-common's code-splitting factory (see src/icons/index.ts).
15
+ const AgentProfileCardTrigger = Loadable({
16
+ loader: () => import( /* webpackChunkName: "@atlaskit-internal_profilecard/agent-profile-card-trigger" */
17
+ '@atlaskit/profilecard/agent-profile-card-trigger').then(mod => mod.AgentProfileCardTrigger),
23
18
  loading: () => null
24
19
  });
25
- const AgentProfileCardTrigger = props => isExperimentEnabled('platform_editor_loosely_lazy_migration') ? /*#__PURE__*/React.createElement(LazySuspense, {
26
- fallback: null
27
- }, /*#__PURE__*/React.createElement(AgentProfileCardTriggerLazy, props)) :
28
- /*#__PURE__*/
29
- // eslint-disable-next-line react/jsx-props-no-spreading
30
- React.createElement(AgentProfileCardTriggerLoadable, props);
31
20
 
32
21
  // Ignored via go/ees005
33
22
  // eslint-disable-next-line require-unicode-regexp
@@ -58,6 +47,7 @@ export default function MentionWithProfileCard({
58
47
  }) {
59
48
  const {
60
49
  cloudId,
50
+ renderAgentMentionCard,
61
51
  renderUserMentionCard,
62
52
  resourceClient
63
53
  } = profilecardProvider;
@@ -81,6 +71,13 @@ export default function MentionWithProfileCard({
81
71
 
82
72
  // Agent mentions (userType 'APP') open the Rovo agent profile card on click.
83
73
  if (userType === 'APP' && cloudId && isExperimentEnabled('rovo_chat_mention_agents')) {
74
+ if (renderAgentMentionCard) {
75
+ return /*#__PURE__*/React.createElement(React.Fragment, null, renderAgentMentionCard({
76
+ accountId: id,
77
+ children: mention,
78
+ cloudId
79
+ }));
80
+ }
84
81
  return /*#__PURE__*/React.createElement(AgentProfileCardTrigger, {
85
82
  agentId: id,
86
83
  agentIdType: isExperimentEnabled('platform_editor_comment_mention_card_fixes') ? 'identity' : undefined,
@@ -5,6 +5,7 @@ import { bind } from 'bind-event-listener';
5
5
  import createFocusTrap from 'focus-trap';
6
6
  import rafSchedule from 'raf-schd';
7
7
  import { akEditorFloatingPanelZIndex } from '@atlaskit/editor-shared-styles';
8
+ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
8
9
  import { calculatePlacement, calculatePosition, findOverflowScrollParent } from './utils';
9
10
  import { validatePosition } from './validatePosition';
10
11
  // Ignored via go/ees005
@@ -15,10 +16,45 @@ export default class Popup extends React.Component {
15
16
  super(...args);
16
17
  _defineProperty(this, "rafIds", new Set());
17
18
  _defineProperty(this, "state", {
19
+ targetVisible: true,
18
20
  validPosition: true
19
21
  });
20
22
  _defineProperty(this, "popupRef", /*#__PURE__*/React.createRef());
21
23
  _defineProperty(this, "placement", ['', '']);
24
+ _defineProperty(this, "setTargetVisibility", targetVisible => {
25
+ if (targetVisible !== this.state.targetVisible) {
26
+ if (!targetVisible) {
27
+ var _this$focusTrap;
28
+ // Let consumers preserve focus before the popup becomes hidden.
29
+ this.reportTargetVisibility(targetVisible);
30
+ (_this$focusTrap = this.focusTrap) === null || _this$focusTrap === void 0 ? void 0 : _this$focusTrap.pause();
31
+ this.setState({
32
+ targetVisible
33
+ });
34
+ return;
35
+ }
36
+
37
+ // Reveal the popup before consumers restore focus to its contents.
38
+ this.setState({
39
+ targetVisible
40
+ }, () => {
41
+ if (this.props.focusTrap) {
42
+ var _this$focusTrap2;
43
+ (_this$focusTrap2 = this.focusTrap) === null || _this$focusTrap2 === void 0 ? void 0 : _this$focusTrap2.unpause();
44
+ }
45
+ this.reportTargetVisibility(targetVisible);
46
+ });
47
+ return;
48
+ }
49
+ this.reportTargetVisibility(targetVisible);
50
+ });
51
+ _defineProperty(this, "reportTargetVisibility", targetVisible => {
52
+ if (targetVisible !== this.reportedTargetVisibility) {
53
+ var _this$props$onTargetV, _this$props;
54
+ this.reportedTargetVisibility = targetVisible;
55
+ (_this$props$onTargetV = (_this$props = this.props).onTargetVisibilityChanged) === null || _this$props$onTargetV === void 0 ? void 0 : _this$props$onTargetV.call(_this$props, targetVisible);
56
+ }
57
+ });
22
58
  _defineProperty(this, "handleRef", popup => {
23
59
  if (!popup) {
24
60
  return;
@@ -137,6 +173,38 @@ export default class Popup extends React.Component {
137
173
  });
138
174
  }
139
175
  }
176
+ initTargetVisibilityObserver() {
177
+ var _this$targetVisibilit, _observedTarget$owner;
178
+ const {
179
+ hideWhenTargetOutOfView,
180
+ target,
181
+ visibilityTarget
182
+ } = this.props;
183
+ const observedTarget = visibilityTarget !== null && visibilityTarget !== void 0 ? visibilityTarget : target;
184
+ (_this$targetVisibilit = this.targetVisibilityObserver) === null || _this$targetVisibilit === void 0 ? void 0 : _this$targetVisibilit.disconnect();
185
+ this.targetVisibilityObserver = undefined;
186
+ if (!hideWhenTargetOutOfView || !isExperimentEnabled('platform_editor_popup_target_visibility')) {
187
+ if (!this.state.targetVisible) {
188
+ this.setTargetVisibility(true);
189
+ }
190
+ return;
191
+ }
192
+ this.reportedTargetVisibility = undefined;
193
+ const IntersectionObserverConstructor = observedTarget === null || observedTarget === void 0 ? void 0 : (_observedTarget$owner = observedTarget.ownerDocument.defaultView) === null || _observedTarget$owner === void 0 ? void 0 : _observedTarget$owner.IntersectionObserver;
194
+ if (!IntersectionObserverConstructor || !observedTarget) {
195
+ this.setTargetVisibility(true);
196
+ return;
197
+ }
198
+ this.targetVisibilityObserver = new IntersectionObserverConstructor(entries => {
199
+ var _entry$isIntersecting;
200
+ const entry = entries[entries.length - 1];
201
+ this.setTargetVisibility((_entry$isIntersecting = entry === null || entry === void 0 ? void 0 : entry.isIntersecting) !== null && _entry$isIntersecting !== void 0 ? _entry$isIntersecting : true);
202
+ }, {
203
+ root: null
204
+ });
205
+ this.targetVisibilityObserver.observe(observedTarget);
206
+ this.setTargetVisibility(true);
207
+ }
140
208
  cannotSetPopup(popup, target, overflowScrollParent) {
141
209
  /**
142
210
  * Check whether:
@@ -199,9 +267,9 @@ export default class Popup extends React.Component {
199
267
  * Deactivates the focus trap if it exists
200
268
  */
201
269
  destroyFocusTrap() {
202
- var _this$focusTrap;
270
+ var _this$focusTrap3;
203
271
  this.initFocusTrap.cancel();
204
- (_this$focusTrap = this.focusTrap) === null || _this$focusTrap === void 0 ? void 0 : _this$focusTrap.deactivate();
272
+ (_this$focusTrap3 = this.focusTrap) === null || _this$focusTrap3 === void 0 ? void 0 : _this$focusTrap3.deactivate();
205
273
  }
206
274
 
207
275
  /**
@@ -211,8 +279,8 @@ export default class Popup extends React.Component {
211
279
  if (prevProps.focusTrap !== this.props.focusTrap) {
212
280
  // If currently set to disable, then pause the trap if it exists
213
281
  if (!this.props.focusTrap) {
214
- var _this$focusTrap2;
215
- return (_this$focusTrap2 = this.focusTrap) === null || _this$focusTrap2 === void 0 ? void 0 : _this$focusTrap2.pause();
282
+ var _this$focusTrap4;
283
+ return (_this$focusTrap4 = this.focusTrap) === null || _this$focusTrap4 === void 0 ? void 0 : _this$focusTrap4.pause();
216
284
  }
217
285
 
218
286
  // If set to enabled and trap already exists, unpause
@@ -259,6 +327,11 @@ export default class Popup extends React.Component {
259
327
  if (prevProps.scrollableElement !== this.props.scrollableElement) {
260
328
  this.initScrollElement();
261
329
  }
330
+ // Reconfigure while enabled, or once after disabling to clean up the existing observer.
331
+ // A different target must be observed again.
332
+ if ((prevProps.hideWhenTargetOutOfView || this.props.hideWhenTargetOutOfView) && (prevProps.hideWhenTargetOutOfView !== this.props.hideWhenTargetOutOfView || prevProps.target !== this.props.target || prevProps.visibilityTarget !== this.props.visibilityTarget)) {
333
+ this.initTargetVisibilityObserver();
334
+ }
262
335
  if (this.props !== prevProps) {
263
336
  this.scheduledUpdatePosition(prevProps);
264
337
  }
@@ -268,12 +341,16 @@ export default class Popup extends React.Component {
268
341
  // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
269
342
  window.addEventListener('resize', this.onResize);
270
343
  this.initScrollElement();
344
+ if (this.props.hideWhenTargetOutOfView) {
345
+ this.initTargetVisibilityObserver();
346
+ }
271
347
  }
272
348
  componentWillUnmount() {
273
- var _this$unbindScroll2, _this$resizeObserver3;
349
+ var _this$targetVisibilit2, _this$unbindScroll2, _this$resizeObserver3;
274
350
  // Ignored via go/ees005
275
351
  // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
276
352
  window.removeEventListener('resize', this.onResize);
353
+ (_this$targetVisibilit2 = this.targetVisibilityObserver) === null || _this$targetVisibilit2 === void 0 ? void 0 : _this$targetVisibilit2.disconnect();
277
354
  (_this$unbindScroll2 = this.unbindScroll) === null || _this$unbindScroll2 === void 0 ? void 0 : _this$unbindScroll2.call(this);
278
355
  if (this.scrollElement) {
279
356
  // Ignored via go/ees005
@@ -293,7 +370,8 @@ export default class Popup extends React.Component {
293
370
  renderPopup() {
294
371
  var _this$props$ariaLabel;
295
372
  const {
296
- position
373
+ position,
374
+ targetVisible
297
375
  } = this.state;
298
376
  const {
299
377
  shouldRenderPopup
@@ -327,7 +405,11 @@ export default class Popup extends React.Component {
327
405
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
328
406
  ...position,
329
407
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
330
- ...this.props.style
408
+ ...this.props.style,
409
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Runtime visibility follows the target's scroll position.
410
+ ...(this.props.hideWhenTargetOutOfView && isExperimentEnabled('platform_editor_popup_target_visibility') && !targetVisible && {
411
+ visibility: 'hidden'
412
+ })
331
413
  },
332
414
  role: getRole(),
333
415
  "aria-label": ariaLabel,
@@ -7,11 +7,6 @@ import React from 'react';
7
7
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
8
8
  import { css, jsx } from '@emotion/react';
9
9
  import Loadable from 'react-loadable';
10
- // oxlint-disable-next-line @atlassian/no-restricted-imports
11
- import { lazy, LazySuspense } from 'react-loosely-lazy';
12
-
13
- // oxlint-disable-next-line @atlassian/no-restricted-imports
14
- import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
15
10
  import Spinner from '@atlaskit/spinner/spinner';
16
11
  var spinnerContainer = css({
17
12
  display: 'flex',
@@ -20,19 +15,12 @@ var spinnerContainer = css({
20
15
  height: '100%',
21
16
  width: '100%'
22
17
  });
23
- var loadElementBrowser = function loadElementBrowser() {
24
- return import( /* webpackChunkName: "@atlaskit-internal_editor-element-browser" */'../ElementBrowser').then(function (module) {
25
- return module.default;
26
- });
27
- };
28
- var ElementBrowserLazy = lazy(function () {
29
- return import( /* webpackChunkName: "@atlaskit-internal_editor-element-browser" */'../ElementBrowser').then(function (module) {
30
- return module.default;
31
- });
32
- });
33
- ElementBrowserLazy.displayName = 'lazy(ElementBrowser)';
34
- var ElementBrowserLoadable = Loadable({
35
- loader: loadElementBrowser,
18
+ var ElementBrowserLoader = Loadable({
19
+ loader: function loader() {
20
+ return import( /* webpackChunkName: "@atlaskit-internal_editor-element-browser" */'../ElementBrowser').then(function (module) {
21
+ return module.default;
22
+ });
23
+ },
36
24
  loading: function loading() {
37
25
  return jsx("div", {
38
26
  css: spinnerContainer
@@ -42,14 +30,4 @@ var ElementBrowserLoadable = Loadable({
42
30
  }));
43
31
  }
44
32
  });
45
- var ElementBrowserLoader = function ElementBrowserLoader(props) {
46
- return isExperimentEnabled('platform_editor_loosely_lazy_migration') ? jsx(LazySuspense, {
47
- fallback: null
48
- }, jsx(ElementBrowserLazy, props)) :
49
- // eslint-disable-next-line react/jsx-props-no-spreading
50
- jsx(ElementBrowserLoadable, props);
51
- };
52
- ElementBrowserLoader.preload = function () {
53
- return isExperimentEnabled('platform_editor_loosely_lazy_migration') ? ElementBrowserLazy.preload() : ElementBrowserLoadable.preload();
54
- };
55
33
  export default ElementBrowserLoader;
@@ -4,15 +4,16 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
4
4
  import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
5
5
  import { buildAction } from './manifest-helpers';
6
6
  export function buildMenuItem(manifest, extensionModule) {
7
- var _extensionModule$cate, _ref, _extensionModule$app;
7
+ var _extensionModule$prev, _extensionModule$cate, _ref, _extensionModule$app;
8
8
  var title = extensionModule.title || manifest.title;
9
9
  var key = "".concat(manifest.key, ":").concat(extensionModule.key);
10
10
  var node = buildAction(extensionModule.action, manifest);
11
+ var preview = (_extensionModule$prev = extensionModule.preview) !== null && _extensionModule$prev !== void 0 ? _extensionModule$prev : manifest.preview;
11
12
  var category = isExperimentEnabled('platform_editor_slash_command') ? (_extensionModule$cate = extensionModule.category) !== null && _extensionModule$cate !== void 0 ? _extensionModule$cate : manifest.category : undefined;
12
13
  if (!node) {
13
14
  throw new Error("Couldn't find any action for ".concat(title, " (").concat(key, ")"));
14
15
  }
15
- return _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, isExperimentEnabled('platform_editor_slash_app_category_analytics') || isExperimentEnabled('platform_editor_slash_command') ? {
16
+ return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, isExperimentEnabled('platform_editor_slash_app_category_analytics') || isExperimentEnabled('platform_editor_slash_command') ? {
16
17
  app: (_ref = (_extensionModule$app = extensionModule.app) !== null && _extensionModule$app !== void 0 ? _extensionModule$app : manifest.app) !== null && _ref !== void 0 ? _ref : {
17
18
  key: manifest.key
18
19
  }
@@ -31,7 +32,9 @@ export function buildMenuItem(manifest, extensionModule) {
31
32
  summary: manifest.summary,
32
33
  documentationUrl: manifest.documentationUrl,
33
34
  priority: extensionModule.priority
34
- }, extensionModule.lozenge != null && {
35
+ }, preview != null && {
36
+ preview: preview
37
+ }), extensionModule.lozenge != null && {
35
38
  lozenge: extensionModule.lozenge
36
39
  }), {}, {
37
40
  icon: extensionModule.icon || manifest.icons['48'],