@wordpress/editor 14.42.0 → 14.43.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 (199) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/collaborators-overlay/cursor-registry.cjs +86 -0
  3. package/build/components/collaborators-overlay/cursor-registry.cjs.map +7 -0
  4. package/build/components/collaborators-overlay/index.cjs +7 -2
  5. package/build/components/collaborators-overlay/index.cjs.map +2 -2
  6. package/build/components/collaborators-overlay/overlay-iframe-styles.cjs +1 -1
  7. package/build/components/collaborators-overlay/overlay-iframe-styles.cjs.map +2 -2
  8. package/build/components/collaborators-overlay/overlay.cjs +31 -1
  9. package/build/components/collaborators-overlay/overlay.cjs.map +2 -2
  10. package/build/components/collaborators-presence/index.cjs +14 -4
  11. package/build/components/collaborators-presence/index.cjs.map +2 -2
  12. package/build/components/collaborators-presence/list.cjs +20 -4
  13. package/build/components/collaborators-presence/list.cjs.map +2 -2
  14. package/build/components/post-card-panel/index.cjs +4 -15
  15. package/build/components/post-card-panel/index.cjs.map +2 -2
  16. package/build/components/post-content-information/index.cjs +10 -13
  17. package/build/components/post-content-information/index.cjs.map +2 -2
  18. package/build/components/post-revisions-panel/index.cjs +164 -0
  19. package/build/components/post-revisions-panel/index.cjs.map +7 -0
  20. package/build/components/post-revisions-preview/revisions-slider.cjs +24 -5
  21. package/build/components/post-revisions-preview/revisions-slider.cjs.map +2 -2
  22. package/build/components/post-template/create-new-template-modal.cjs +39 -46
  23. package/build/components/post-template/create-new-template-modal.cjs.map +2 -2
  24. package/build/components/post-template/hooks.cjs +52 -6
  25. package/build/components/post-template/hooks.cjs.map +2 -2
  26. package/build/components/post-template/swap-template-button.cjs +31 -20
  27. package/build/components/post-template/swap-template-button.cjs.map +2 -2
  28. package/build/components/preferences-modal/index.cjs +35 -27
  29. package/build/components/preferences-modal/index.cjs.map +2 -2
  30. package/build/components/revision-block-diff/index.cjs +9 -32
  31. package/build/components/revision-block-diff/index.cjs.map +3 -3
  32. package/build/components/revision-diff-panel/index.cjs +68 -0
  33. package/build/components/revision-diff-panel/index.cjs.map +7 -0
  34. package/build/components/revision-fields-diff/index.cjs +96 -0
  35. package/build/components/revision-fields-diff/index.cjs.map +7 -0
  36. package/build/components/sidebar/dataform-post-summary.cjs +8 -53
  37. package/build/components/sidebar/dataform-post-summary.cjs.map +2 -2
  38. package/build/components/sidebar/index.cjs +25 -22
  39. package/build/components/sidebar/index.cjs.map +3 -3
  40. package/build/components/sidebar/post-revision-summary.cjs +74 -0
  41. package/build/components/sidebar/post-revision-summary.cjs.map +7 -0
  42. package/build/components/sidebar/post-summary.cjs +35 -42
  43. package/build/components/sidebar/post-summary.cjs.map +3 -3
  44. package/build/components/style-book/index.cjs +4 -3
  45. package/build/components/style-book/index.cjs.map +2 -2
  46. package/build/components/sync-connection-error-modal/index.cjs +2 -2
  47. package/build/components/sync-connection-error-modal/index.cjs.map +1 -1
  48. package/build/components/template-actions-panel/block-theme-content.cjs +188 -0
  49. package/build/components/template-actions-panel/block-theme-content.cjs.map +7 -0
  50. package/build/components/template-actions-panel/classic-theme-content.cjs +159 -0
  51. package/build/components/template-actions-panel/classic-theme-content.cjs.map +7 -0
  52. package/build/components/template-actions-panel/index.cjs +59 -0
  53. package/build/components/template-actions-panel/index.cjs.map +7 -0
  54. package/build/dataviews/store/private-actions.cjs +2 -0
  55. package/build/dataviews/store/private-actions.cjs.map +2 -2
  56. package/build/store/private-actions.cjs +21 -2
  57. package/build/store/private-actions.cjs.map +2 -2
  58. package/build/store/private-selectors.cjs +40 -15
  59. package/build/store/private-selectors.cjs.map +2 -2
  60. package/build-module/components/collaborators-overlay/cursor-registry.mjs +61 -0
  61. package/build-module/components/collaborators-overlay/cursor-registry.mjs.map +7 -0
  62. package/build-module/components/collaborators-overlay/index.mjs +7 -2
  63. package/build-module/components/collaborators-overlay/index.mjs.map +2 -2
  64. package/build-module/components/collaborators-overlay/overlay-iframe-styles.mjs +1 -1
  65. package/build-module/components/collaborators-overlay/overlay-iframe-styles.mjs.map +2 -2
  66. package/build-module/components/collaborators-overlay/overlay.mjs +32 -2
  67. package/build-module/components/collaborators-overlay/overlay.mjs.map +2 -2
  68. package/build-module/components/collaborators-presence/index.mjs +14 -4
  69. package/build-module/components/collaborators-presence/index.mjs.map +2 -2
  70. package/build-module/components/collaborators-presence/list.mjs +20 -4
  71. package/build-module/components/collaborators-presence/list.mjs.map +2 -2
  72. package/build-module/components/post-card-panel/index.mjs +6 -17
  73. package/build-module/components/post-card-panel/index.mjs.map +2 -2
  74. package/build-module/components/post-content-information/index.mjs +6 -13
  75. package/build-module/components/post-content-information/index.mjs.map +2 -2
  76. package/build-module/components/post-revisions-panel/index.mjs +139 -0
  77. package/build-module/components/post-revisions-panel/index.mjs.map +7 -0
  78. package/build-module/components/post-revisions-preview/revisions-slider.mjs +24 -5
  79. package/build-module/components/post-revisions-preview/revisions-slider.mjs.map +2 -2
  80. package/build-module/components/post-template/create-new-template-modal.mjs +39 -46
  81. package/build-module/components/post-template/create-new-template-modal.mjs.map +2 -2
  82. package/build-module/components/post-template/hooks.mjs +53 -7
  83. package/build-module/components/post-template/hooks.mjs.map +2 -2
  84. package/build-module/components/post-template/swap-template-button.mjs +27 -20
  85. package/build-module/components/post-template/swap-template-button.mjs.map +2 -2
  86. package/build-module/components/preferences-modal/index.mjs +35 -27
  87. package/build-module/components/preferences-modal/index.mjs.map +2 -2
  88. package/build-module/components/revision-block-diff/index.mjs +9 -32
  89. package/build-module/components/revision-block-diff/index.mjs.map +2 -2
  90. package/build-module/components/revision-diff-panel/index.mjs +37 -0
  91. package/build-module/components/revision-diff-panel/index.mjs.map +7 -0
  92. package/build-module/components/revision-fields-diff/index.mjs +65 -0
  93. package/build-module/components/revision-fields-diff/index.mjs.map +7 -0
  94. package/build-module/components/sidebar/dataform-post-summary.mjs +8 -53
  95. package/build-module/components/sidebar/dataform-post-summary.mjs.map +2 -2
  96. package/build-module/components/sidebar/index.mjs +25 -22
  97. package/build-module/components/sidebar/index.mjs.map +2 -2
  98. package/build-module/components/sidebar/post-revision-summary.mjs +43 -0
  99. package/build-module/components/sidebar/post-revision-summary.mjs.map +7 -0
  100. package/build-module/components/sidebar/post-summary.mjs +31 -42
  101. package/build-module/components/sidebar/post-summary.mjs.map +2 -2
  102. package/build-module/components/style-book/index.mjs +4 -3
  103. package/build-module/components/style-book/index.mjs.map +2 -2
  104. package/build-module/components/sync-connection-error-modal/index.mjs +2 -2
  105. package/build-module/components/sync-connection-error-modal/index.mjs.map +1 -1
  106. package/build-module/components/template-actions-panel/block-theme-content.mjs +167 -0
  107. package/build-module/components/template-actions-panel/block-theme-content.mjs.map +7 -0
  108. package/build-module/components/template-actions-panel/classic-theme-content.mjs +138 -0
  109. package/build-module/components/template-actions-panel/classic-theme-content.mjs.map +7 -0
  110. package/build-module/components/template-actions-panel/index.mjs +28 -0
  111. package/build-module/components/template-actions-panel/index.mjs.map +7 -0
  112. package/build-module/dataviews/store/private-actions.mjs +5 -1
  113. package/build-module/dataviews/store/private-actions.mjs.map +2 -2
  114. package/build-module/store/private-actions.mjs +21 -2
  115. package/build-module/store/private-actions.mjs.map +2 -2
  116. package/build-module/store/private-selectors.mjs +40 -15
  117. package/build-module/store/private-selectors.mjs.map +2 -2
  118. package/build-style/style-rtl.css +111 -42
  119. package/build-style/style.css +111 -42
  120. package/build-types/components/collaborators-overlay/cursor-registry.d.ts +36 -0
  121. package/build-types/components/collaborators-overlay/cursor-registry.d.ts.map +1 -0
  122. package/build-types/components/collaborators-overlay/index.d.ts +7 -4
  123. package/build-types/components/collaborators-overlay/index.d.ts.map +1 -1
  124. package/build-types/components/collaborators-overlay/overlay-iframe-styles.d.ts +1 -1
  125. package/build-types/components/collaborators-overlay/overlay-iframe-styles.d.ts.map +1 -1
  126. package/build-types/components/collaborators-overlay/overlay.d.ts +4 -1
  127. package/build-types/components/collaborators-overlay/overlay.d.ts.map +1 -1
  128. package/build-types/components/collaborators-presence/index.d.ts.map +1 -1
  129. package/build-types/components/collaborators-presence/list.d.ts +4 -1
  130. package/build-types/components/collaborators-presence/list.d.ts.map +1 -1
  131. package/build-types/components/post-card-panel/index.d.ts.map +1 -1
  132. package/build-types/components/post-content-information/index.d.ts +4 -1
  133. package/build-types/components/post-content-information/index.d.ts.map +1 -1
  134. package/build-types/components/post-revisions-panel/index.d.ts +2 -0
  135. package/build-types/components/post-revisions-panel/index.d.ts.map +1 -0
  136. package/build-types/components/post-revisions-preview/revisions-slider.d.ts.map +1 -1
  137. package/build-types/components/post-template/create-new-template-modal.d.ts.map +1 -1
  138. package/build-types/components/post-template/hooks.d.ts +1 -1
  139. package/build-types/components/post-template/hooks.d.ts.map +1 -1
  140. package/build-types/components/post-template/swap-template-button.d.ts +4 -0
  141. package/build-types/components/post-template/swap-template-button.d.ts.map +1 -1
  142. package/build-types/components/revision-block-diff/index.d.ts.map +1 -1
  143. package/build-types/components/revision-diff-panel/index.d.ts +14 -0
  144. package/build-types/components/revision-diff-panel/index.d.ts.map +1 -0
  145. package/build-types/components/revision-fields-diff/index.d.ts +6 -0
  146. package/build-types/components/revision-fields-diff/index.d.ts.map +1 -0
  147. package/build-types/components/sidebar/dataform-post-summary.d.ts.map +1 -1
  148. package/build-types/components/sidebar/index.d.ts.map +1 -1
  149. package/build-types/components/sidebar/post-revision-summary.d.ts +2 -0
  150. package/build-types/components/sidebar/post-revision-summary.d.ts.map +1 -0
  151. package/build-types/components/sidebar/post-summary.d.ts +3 -0
  152. package/build-types/components/sidebar/post-summary.d.ts.map +1 -1
  153. package/build-types/components/style-book/index.d.ts +2 -1
  154. package/build-types/components/style-book/index.d.ts.map +1 -1
  155. package/build-types/components/template-actions-panel/block-theme-content.d.ts +2 -0
  156. package/build-types/components/template-actions-panel/block-theme-content.d.ts.map +1 -0
  157. package/build-types/components/template-actions-panel/classic-theme-content.d.ts +2 -0
  158. package/build-types/components/template-actions-panel/classic-theme-content.d.ts.map +1 -0
  159. package/build-types/components/template-actions-panel/index.d.ts +2 -0
  160. package/build-types/components/template-actions-panel/index.d.ts.map +1 -0
  161. package/build-types/dataviews/store/private-actions.d.ts.map +1 -1
  162. package/build-types/store/private-actions.d.ts.map +1 -1
  163. package/build-types/store/private-selectors.d.ts.map +1 -1
  164. package/package.json +45 -44
  165. package/src/components/collaborators-overlay/cursor-registry.ts +96 -0
  166. package/src/components/collaborators-overlay/index.tsx +12 -4
  167. package/src/components/collaborators-overlay/overlay-iframe-styles.ts +1 -1
  168. package/src/components/collaborators-overlay/overlay.tsx +45 -1
  169. package/src/components/collaborators-presence/index.tsx +9 -1
  170. package/src/components/collaborators-presence/list.tsx +25 -1
  171. package/src/components/post-card-panel/index.js +7 -21
  172. package/src/components/post-content-information/index.js +5 -16
  173. package/src/components/post-revisions-panel/index.js +151 -0
  174. package/src/components/post-revisions-panel/style.scss +16 -0
  175. package/src/components/post-revisions-preview/revisions-slider.js +29 -7
  176. package/src/components/post-template/create-new-template-modal.js +1 -4
  177. package/src/components/post-template/hooks.js +65 -9
  178. package/src/components/post-template/style.scss +0 -6
  179. package/src/components/post-template/swap-template-button.js +30 -21
  180. package/src/components/preferences-modal/index.js +37 -25
  181. package/src/components/revision-block-diff/index.js +8 -43
  182. package/src/components/revision-diff-panel/index.js +59 -0
  183. package/src/components/revision-fields-diff/index.js +91 -0
  184. package/src/components/sidebar/dataform-post-summary.js +8 -55
  185. package/src/components/sidebar/index.js +33 -22
  186. package/src/components/sidebar/post-revision-summary.js +50 -0
  187. package/src/components/sidebar/post-summary.js +22 -40
  188. package/src/components/sidebar/style.scss +7 -0
  189. package/src/components/style-book/index.js +4 -2
  190. package/src/components/sync-connection-error-modal/index.tsx +2 -2
  191. package/src/components/template-actions-panel/block-theme-content.js +196 -0
  192. package/src/components/template-actions-panel/classic-theme-content.js +170 -0
  193. package/src/components/template-actions-panel/index.js +32 -0
  194. package/src/components/template-actions-panel/style.scss +39 -0
  195. package/src/dataviews/store/private-actions.ts +6 -0
  196. package/src/store/private-actions.js +24 -3
  197. package/src/store/private-selectors.js +46 -16
  198. package/src/style.scss +3 -1
  199. /package/src/components/{revision-block-diff → revision-diff-panel}/style.scss +0 -0
@@ -0,0 +1,61 @@
1
+ // packages/editor/src/components/collaborators-overlay/cursor-registry.ts
2
+ function highlightCursor(element, duration) {
3
+ element.classList.add("collaborators-overlay-cursor-highlighted");
4
+ setTimeout(() => {
5
+ element.classList.remove("collaborators-overlay-cursor-highlighted");
6
+ }, duration);
7
+ }
8
+ function createCursorRegistry() {
9
+ const cursorMap = /* @__PURE__ */ new Map();
10
+ return {
11
+ /**
12
+ * Register a cursor element when it's created.
13
+ *
14
+ * @param clientId - The clientId of the cursor to register.
15
+ * @param element - The cursor element to register.
16
+ */
17
+ registerCursor(clientId, element) {
18
+ cursorMap.set(clientId, element);
19
+ },
20
+ /**
21
+ * Unregister a cursor element when it's removed.
22
+ *
23
+ * @param clientId - The clientId of the cursor to unregister.
24
+ */
25
+ unregisterCursor(clientId) {
26
+ cursorMap.delete(clientId);
27
+ },
28
+ /**
29
+ * Scroll to a cursor by clientId.
30
+ *
31
+ * @param clientId - The clientId of the cursor to scroll to.
32
+ * @param options - The options for the scroll.
33
+ * @return true if cursor was found and scrolled to, false otherwise.
34
+ */
35
+ scrollToCursor(clientId, options) {
36
+ const cursorElement = cursorMap.get(clientId);
37
+ if (!cursorElement) {
38
+ return false;
39
+ }
40
+ cursorElement.scrollIntoView({
41
+ behavior: options?.behavior ?? "smooth",
42
+ block: options?.block ?? "center",
43
+ inline: options?.inline ?? "nearest"
44
+ });
45
+ if (options?.highlightDuration) {
46
+ highlightCursor(cursorElement, options.highlightDuration);
47
+ }
48
+ return true;
49
+ },
50
+ /**
51
+ * Clear the registry.
52
+ */
53
+ removeAll() {
54
+ cursorMap.clear();
55
+ }
56
+ };
57
+ }
58
+ export {
59
+ createCursorRegistry
60
+ };
61
+ //# sourceMappingURL=cursor-registry.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/components/collaborators-overlay/cursor-registry.ts"],
4
+ "sourcesContent": ["interface ScrollToCursorOptions {\n\tbehavior?: ScrollBehavior;\n\tblock?: ScrollLogicalPosition;\n\tinline?: ScrollLogicalPosition;\n\thighlightDuration?: number;\n}\n\n/**\n * Cursor Registry\n * ===\n * This registry stores references to cursor elements so that we can access them\n * in different parts of the component tree. This would more ideally be solved\n * with React context or state in the awareness store, but:\n *\n * 1. EditorPresence and BlockCanvasCover slot/fill break context propagation. We\n * don't currently have a way to provide context to both the slot and fill.\n * 2. Storing pointers to the cursor elements in the awareness store might be a\n * better solution, but would require broader refactoring.\n *\n * For now, we create a single instance of this registry and pass it down to the\n * components that need it. It's important that we create a single instance and\n * not a new instance per component or render; use useState with a lazy\n * initializer to accomplish this.\n */\n\nfunction highlightCursor( element: HTMLElement, duration: number ): void {\n\telement.classList.add( 'collaborators-overlay-cursor-highlighted' );\n\n\tsetTimeout( () => {\n\t\telement.classList.remove( 'collaborators-overlay-cursor-highlighted' );\n\t}, duration );\n}\n\nexport function createCursorRegistry() {\n\tconst cursorMap = new Map< number, HTMLElement >();\n\n\treturn {\n\t\t/**\n\t\t * Register a cursor element when it's created.\n\t\t *\n\t\t * @param clientId - The clientId of the cursor to register.\n\t\t * @param element - The cursor element to register.\n\t\t */\n\t\tregisterCursor( clientId: number, element: HTMLElement ): void {\n\t\t\tcursorMap.set( clientId, element );\n\t\t},\n\n\t\t/**\n\t\t * Unregister a cursor element when it's removed.\n\t\t *\n\t\t * @param clientId - The clientId of the cursor to unregister.\n\t\t */\n\t\tunregisterCursor( clientId: number ): void {\n\t\t\tcursorMap.delete( clientId );\n\t\t},\n\n\t\t/**\n\t\t * Scroll to a cursor by clientId.\n\t\t *\n\t\t * @param clientId - The clientId of the cursor to scroll to.\n\t\t * @param options - The options for the scroll.\n\t\t * @return true if cursor was found and scrolled to, false otherwise.\n\t\t */\n\t\tscrollToCursor(\n\t\t\tclientId: number,\n\t\t\toptions?: ScrollToCursorOptions\n\t\t): boolean {\n\t\t\tconst cursorElement = cursorMap.get( clientId );\n\n\t\t\tif ( ! cursorElement ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tcursorElement.scrollIntoView( {\n\t\t\t\tbehavior: options?.behavior ?? 'smooth',\n\t\t\t\tblock: options?.block ?? 'center',\n\t\t\t\tinline: options?.inline ?? 'nearest',\n\t\t\t} );\n\n\t\t\tif ( options?.highlightDuration ) {\n\t\t\t\thighlightCursor( cursorElement, options.highlightDuration );\n\t\t\t}\n\n\t\t\treturn true;\n\t\t},\n\n\t\t/**\n\t\t * Clear the registry.\n\t\t */\n\t\tremoveAll(): void {\n\t\t\tcursorMap.clear();\n\t\t},\n\t};\n}\n\nexport type CursorRegistry = ReturnType< typeof createCursorRegistry >;\n"],
5
+ "mappings": ";AAyBA,SAAS,gBAAiB,SAAsB,UAAyB;AACxE,UAAQ,UAAU,IAAK,0CAA2C;AAElE,aAAY,MAAM;AACjB,YAAQ,UAAU,OAAQ,0CAA2C;AAAA,EACtE,GAAG,QAAS;AACb;AAEO,SAAS,uBAAuB;AACtC,QAAM,YAAY,oBAAI,IAA2B;AAEjD,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAON,eAAgB,UAAkB,SAA6B;AAC9D,gBAAU,IAAK,UAAU,OAAQ;AAAA,IAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,iBAAkB,UAAyB;AAC1C,gBAAU,OAAQ,QAAS;AAAA,IAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,eACC,UACA,SACU;AACV,YAAM,gBAAgB,UAAU,IAAK,QAAS;AAE9C,UAAK,CAAE,eAAgB;AACtB,eAAO;AAAA,MACR;AAEA,oBAAc,eAAgB;AAAA,QAC7B,UAAU,SAAS,YAAY;AAAA,QAC/B,OAAO,SAAS,SAAS;AAAA,QACzB,QAAQ,SAAS,UAAU;AAAA,MAC5B,CAAE;AAEF,UAAK,SAAS,mBAAoB;AACjC,wBAAiB,eAAe,QAAQ,iBAAkB;AAAA,MAC3D;AAEA,aAAO;AAAA,IACR;AAAA;AAAA;AAAA;AAAA,IAKA,YAAkB;AACjB,gBAAU,MAAM;AAAA,IACjB;AAAA,EACD;AACD;",
6
+ "names": []
7
+ }
@@ -4,7 +4,11 @@ import { unlock } from "../../lock-unlock.mjs";
4
4
  import { Overlay } from "./overlay.mjs";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  var { BlockCanvasCover } = unlock(privateApis);
7
- function CollaboratorsOverlay({ postId, postType }) {
7
+ function CollaboratorsOverlay({
8
+ postId,
9
+ postType,
10
+ cursorRegistry
11
+ }) {
8
12
  return /* @__PURE__ */ jsx(BlockCanvasCover.Fill, { children: ({
9
13
  containerRef
10
14
  }) => /* @__PURE__ */ jsx(
@@ -12,7 +16,8 @@ function CollaboratorsOverlay({ postId, postType }) {
12
16
  {
13
17
  blockEditorDocument: containerRef.current?.ownerDocument,
14
18
  postId,
15
- postType
19
+ postType,
20
+ cursorRegistry
16
21
  }
17
22
  ) });
18
23
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/collaborators-overlay/index.tsx"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\n// @ts-expect-error No exported types\nimport { privateApis } from '@wordpress/block-editor';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from '../../lock-unlock';\nimport { Overlay } from './overlay';\n\nconst { BlockCanvasCover } = unlock( privateApis );\n\ninterface Props {\n\tpostId: number | null;\n\tpostType: string | null;\n}\n\n/**\n * Collaborators Overlay component\n * @param props - The props for the CollaboratorsOverlay component\n * @param props.postId - The ID of the post\n * @param props.postType - The type of the post\n * @return The CollaboratorsOverlay component\n */\nexport function CollaboratorsOverlay( { postId, postType }: Props ) {\n\treturn (\n\t\t<BlockCanvasCover.Fill>\n\t\t\t{ ( {\n\t\t\t\tcontainerRef,\n\t\t\t}: {\n\t\t\t\tcontainerRef: React.MutableRefObject< HTMLElement | null >;\n\t\t\t} ) => (\n\t\t\t\t<Overlay\n\t\t\t\t\tblockEditorDocument={ containerRef.current?.ownerDocument }\n\t\t\t\t\tpostId={ postId }\n\t\t\t\t\tpostType={ postType }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</BlockCanvasCover.Fill>\n\t);\n}\n"],
5
- "mappings": ";AAIA,SAAS,mBAAmB;AAK5B,SAAS,cAAc;AACvB,SAAS,eAAe;AAwBpB;AAtBJ,IAAM,EAAE,iBAAiB,IAAI,OAAQ,WAAY;AAc1C,SAAS,qBAAsB,EAAE,QAAQ,SAAS,GAAW;AACnE,SACC,oBAAC,iBAAiB,MAAjB,EACE,WAAE;AAAA,IACH;AAAA,EACD,MAGC;AAAA,IAAC;AAAA;AAAA,MACA,qBAAsB,aAAa,SAAS;AAAA,MAC5C;AAAA,MACA;AAAA;AAAA,EACD,GAEF;AAEF;",
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\n// @ts-expect-error No exported types\nimport { privateApis } from '@wordpress/block-editor';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from '../../lock-unlock';\nimport { Overlay } from './overlay';\nimport { type CursorRegistry } from './cursor-registry';\n\nconst { BlockCanvasCover } = unlock( privateApis );\n\ninterface Props {\n\tpostId: number | null;\n\tpostType: string | null;\n\tcursorRegistry?: CursorRegistry;\n}\n\n/**\n * Collaborators Overlay component\n * @param props - The props for the CollaboratorsOverlay component\n * @param props.postId - The ID of the post\n * @param props.postType - The type of the post\n * @param props.cursorRegistry - The shared cursor registry\n * @return The CollaboratorsOverlay component\n */\nexport function CollaboratorsOverlay( {\n\tpostId,\n\tpostType,\n\tcursorRegistry,\n}: Props ) {\n\treturn (\n\t\t<BlockCanvasCover.Fill>\n\t\t\t{ ( {\n\t\t\t\tcontainerRef,\n\t\t\t}: {\n\t\t\t\tcontainerRef: React.MutableRefObject< HTMLElement | null >;\n\t\t\t} ) => (\n\t\t\t\t<Overlay\n\t\t\t\t\tblockEditorDocument={ containerRef.current?.ownerDocument }\n\t\t\t\t\tpostId={ postId }\n\t\t\t\t\tpostType={ postType }\n\t\t\t\t\tcursorRegistry={ cursorRegistry }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</BlockCanvasCover.Fill>\n\t);\n}\n"],
5
+ "mappings": ";AAIA,SAAS,mBAAmB;AAK5B,SAAS,cAAc;AACvB,SAAS,eAAe;AA+BpB;AA5BJ,IAAM,EAAE,iBAAiB,IAAI,OAAQ,WAAY;AAgB1C,SAAS,qBAAsB;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AACD,GAAW;AACV,SACC,oBAAC,iBAAiB,MAAjB,EACE,WAAE;AAAA,IACH;AAAA,EACD,MAGC;AAAA,IAAC;AAAA;AAAA,MACA,qBAAsB,aAAa,SAAS;AAAA,MAC5C;AAAA,MACA;AAAA,MACA;AAAA;AAAA,EACD,GAEF;AAEF;",
6
6
  "names": []
7
7
  }
@@ -114,7 +114,7 @@ var OVERLAY_IFRAME_STYLES = `
114
114
  outline-style: solid;
115
115
  outline-width: calc(var(--wp-admin-border-width-focus) / var(--wp-block-editor-iframe-zoom-out-scale, 1));
116
116
  outline-offset: calc(-1 * var(--wp-admin-border-width-focus) / var(--wp-block-editor-iframe-zoom-out-scale, 1));
117
- box-shadow: inset 0 0 0 calc(var(--wp-admin-border-width-focus, ${BORDER_WIDTH_FOCUS_FALLBACK}) + ${BORDER_WIDTH}) ${WHITE}, 0 0 0 ${BORDER_WIDTH} ${WHITE}, ${ELEVATION_X_SMALL};
117
+ box-shadow: inset 0 0 0 calc((var(--wp-admin-border-width-focus) / var(--wp-block-editor-iframe-zoom-out-scale, 1)) + 0.5px) rgba(${WHITE}, 0.7);
118
118
  z-index: 1;
119
119
  }
120
120
  @media (prefers-reduced-motion: reduce) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/collaborators-overlay/overlay-iframe-styles.ts"],
4
- "sourcesContent": ["/**\n * CSS for the collaborators overlay \u2014 cursor indicators, block highlights,\n * and positioning of Avatar labels inside the editor canvas iframe.\n */\n\nimport {\n\tBORDER_WIDTH,\n\tBORDER_WIDTH_FOCUS_FALLBACK,\n\tELEVATION_X_SMALL,\n\tGRID_UNIT_05,\n\tGRID_UNIT_10,\n\tWHITE,\n} from './collaborator-styles';\n\nexport const OVERLAY_IFRAME_STYLES = `\n.block-canvas-cover {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\twidth: 100%;\n\theight: 100%;\n\tpointer-events: none;\n\tz-index: 20000;\n}\n.block-canvas-cover .collaborators-overlay-full {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\twidth: 100%;\n\theight: 100%;\n}\n.block-canvas-cover .collaborators-overlay-fixed {\n\tposition: fixed;\n\twidth: 100%;\n\theight: 100%;\n}\n.collaborators-overlay-user {\n\tposition: absolute;\n}\n/* Cursor lines render below avatar labels across all users. The parent\n .collaborators-overlay-user has no z-index so it does not create a\n stacking context \u2014 children participate in the shared overlay context. */\n.collaborators-overlay-user-cursor {\n\tposition: absolute;\n\tz-index: 0;\n\twidth: ${ BORDER_WIDTH_FOCUS_FALLBACK };\n\tborder-radius: ${ BORDER_WIDTH };\n\toutline: ${ BORDER_WIDTH } solid ${ WHITE };\n\tbox-shadow: ${ ELEVATION_X_SMALL };\n\tanimation: collaborators-overlay-cursor-blink 1s infinite;\n}\n.collaborators-overlay-selection-rect {\n\tposition: absolute;\n\topacity: 0.15;\n\tpointer-events: none;\n\tborder-radius: 2px;\n}\n\n/* Overlay-specific positioning applied to the Avatar cursor label. */\n.collaborators-overlay-user-label.editor-avatar {\n\tposition: absolute;\n\tz-index: 1;\n\ttransform: translate(-11px, -100%);\n\tmargin-top: -${ GRID_UNIT_05 };\n\tpointer-events: auto;\n\toverflow: visible;\n\twidth: max-content;\n}\n/* Avatar positioned above a highlighted block as a label. */\n.collaborators-overlay-block-label.editor-avatar {\n\tposition: absolute;\n\tz-index: 1;\n\ttransform: translateY(calc(-100% - ${ GRID_UNIT_10 }));\n\tpointer-events: auto;\n\toverflow: visible;\n\twidth: max-content;\n}\n\n@keyframes collaborators-overlay-cursor-blink {\n\t0%, 45% { opacity: 1; }\n\t55%, 95% { opacity: 0; }\n\t100% { opacity: 1; }\n}\n.collaborators-overlay-cursor-highlighted .collaborators-overlay-user-cursor {\n\tanimation: collaborators-overlay-cursor-highlight 0.6s ease-in-out 3;\n}\n.collaborators-overlay-cursor-highlighted .collaborators-overlay-user-label {\n\tanimation: collaborators-overlay-label-highlight 0.6s ease-in-out 3;\n}\n@keyframes collaborators-overlay-cursor-highlight {\n\t0%, 100% {\n\t\ttransform: scale(1);\n\t\tfilter: drop-shadow(0 0 0 transparent);\n\t}\n\t50% {\n\t\ttransform: scale(1.2);\n\t\tfilter: drop-shadow(0 0 8px currentColor);\n\t}\n}\n@keyframes collaborators-overlay-label-highlight {\n\t0%, 100% {\n\t\ttransform: translate(-11px, -100%) scale(1);\n\t\tfilter: drop-shadow(0 0 0 transparent);\n\t}\n\t50% {\n\t\ttransform: translate(-11px, -100%) scale(1.1);\n\t\tfilter: drop-shadow(0 0 6px currentColor);\n\t}\n}\n.block-editor-block-list__block.is-collaborator-selected:not(:focus)::after {\n\tcontent: \"\";\n\tposition: absolute;\n\tpointer-events: none;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\toutline-color: var(--collaborator-outline-color);\n\toutline-style: solid;\n\toutline-width: calc(var(--wp-admin-border-width-focus) / var(--wp-block-editor-iframe-zoom-out-scale, 1));\n\toutline-offset: calc(-1 * var(--wp-admin-border-width-focus) / var(--wp-block-editor-iframe-zoom-out-scale, 1));\n\tbox-shadow: inset 0 0 0 calc(var(--wp-admin-border-width-focus, ${ BORDER_WIDTH_FOCUS_FALLBACK }) + ${ BORDER_WIDTH }) ${ WHITE }, 0 0 0 ${ BORDER_WIDTH } ${ WHITE }, ${ ELEVATION_X_SMALL };\n\tz-index: 1;\n}\n@media (prefers-reduced-motion: reduce) {\n\t.collaborators-overlay-user-label,\n\t.collaborators-overlay-user-cursor {\n\t\tanimation: none;\n\t}\n}\n`;\n"],
5
- "mappings": ";AAKA;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AAEA,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UA+B1B,2BAA4B;AAAA,kBACpB,YAAa;AAAA,YACnB,YAAa,UAAW,KAAM;AAAA,eAC3B,iBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAejB,YAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sCASS,YAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mEAiDgB,2BAA4B,OAAQ,YAAa,KAAM,KAAM,WAAY,YAAa,IAAK,KAAM,KAAM,iBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
4
+ "sourcesContent": ["/**\n * CSS for the collaborators overlay \u2014 cursor indicators, block highlights,\n * and positioning of Avatar labels inside the editor canvas iframe.\n */\n\nimport {\n\tBORDER_WIDTH,\n\tBORDER_WIDTH_FOCUS_FALLBACK,\n\tELEVATION_X_SMALL,\n\tGRID_UNIT_05,\n\tGRID_UNIT_10,\n\tWHITE,\n} from './collaborator-styles';\n\nexport const OVERLAY_IFRAME_STYLES = `\n.block-canvas-cover {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\twidth: 100%;\n\theight: 100%;\n\tpointer-events: none;\n\tz-index: 20000;\n}\n.block-canvas-cover .collaborators-overlay-full {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\twidth: 100%;\n\theight: 100%;\n}\n.block-canvas-cover .collaborators-overlay-fixed {\n\tposition: fixed;\n\twidth: 100%;\n\theight: 100%;\n}\n.collaborators-overlay-user {\n\tposition: absolute;\n}\n/* Cursor lines render below avatar labels across all users. The parent\n .collaborators-overlay-user has no z-index so it does not create a\n stacking context \u2014 children participate in the shared overlay context. */\n.collaborators-overlay-user-cursor {\n\tposition: absolute;\n\tz-index: 0;\n\twidth: ${ BORDER_WIDTH_FOCUS_FALLBACK };\n\tborder-radius: ${ BORDER_WIDTH };\n\toutline: ${ BORDER_WIDTH } solid ${ WHITE };\n\tbox-shadow: ${ ELEVATION_X_SMALL };\n\tanimation: collaborators-overlay-cursor-blink 1s infinite;\n}\n.collaborators-overlay-selection-rect {\n\tposition: absolute;\n\topacity: 0.15;\n\tpointer-events: none;\n\tborder-radius: 2px;\n}\n\n/* Overlay-specific positioning applied to the Avatar cursor label. */\n.collaborators-overlay-user-label.editor-avatar {\n\tposition: absolute;\n\tz-index: 1;\n\ttransform: translate(-11px, -100%);\n\tmargin-top: -${ GRID_UNIT_05 };\n\tpointer-events: auto;\n\toverflow: visible;\n\twidth: max-content;\n}\n/* Avatar positioned above a highlighted block as a label. */\n.collaborators-overlay-block-label.editor-avatar {\n\tposition: absolute;\n\tz-index: 1;\n\ttransform: translateY(calc(-100% - ${ GRID_UNIT_10 }));\n\tpointer-events: auto;\n\toverflow: visible;\n\twidth: max-content;\n}\n\n@keyframes collaborators-overlay-cursor-blink {\n\t0%, 45% { opacity: 1; }\n\t55%, 95% { opacity: 0; }\n\t100% { opacity: 1; }\n}\n.collaborators-overlay-cursor-highlighted .collaborators-overlay-user-cursor {\n\tanimation: collaborators-overlay-cursor-highlight 0.6s ease-in-out 3;\n}\n.collaborators-overlay-cursor-highlighted .collaborators-overlay-user-label {\n\tanimation: collaborators-overlay-label-highlight 0.6s ease-in-out 3;\n}\n@keyframes collaborators-overlay-cursor-highlight {\n\t0%, 100% {\n\t\ttransform: scale(1);\n\t\tfilter: drop-shadow(0 0 0 transparent);\n\t}\n\t50% {\n\t\ttransform: scale(1.2);\n\t\tfilter: drop-shadow(0 0 8px currentColor);\n\t}\n}\n@keyframes collaborators-overlay-label-highlight {\n\t0%, 100% {\n\t\ttransform: translate(-11px, -100%) scale(1);\n\t\tfilter: drop-shadow(0 0 0 transparent);\n\t}\n\t50% {\n\t\ttransform: translate(-11px, -100%) scale(1.1);\n\t\tfilter: drop-shadow(0 0 6px currentColor);\n\t}\n}\n.block-editor-block-list__block.is-collaborator-selected:not(:focus)::after {\n\tcontent: \"\";\n\tposition: absolute;\n\tpointer-events: none;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\toutline-color: var(--collaborator-outline-color);\n\toutline-style: solid;\n\toutline-width: calc(var(--wp-admin-border-width-focus) / var(--wp-block-editor-iframe-zoom-out-scale, 1));\n\toutline-offset: calc(-1 * var(--wp-admin-border-width-focus) / var(--wp-block-editor-iframe-zoom-out-scale, 1));\n\tbox-shadow: inset 0 0 0 calc((var(--wp-admin-border-width-focus) / var(--wp-block-editor-iframe-zoom-out-scale, 1)) + 0.5px) rgba(${ WHITE }, 0.7);\n\tz-index: 1;\n}\n@media (prefers-reduced-motion: reduce) {\n\t.collaborators-overlay-user-label,\n\t.collaborators-overlay-user-cursor {\n\t\tanimation: none;\n\t}\n}\n`;\n"],
5
+ "mappings": ";AAKA;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AAEA,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UA+B1B,2BAA4B;AAAA,kBACpB,YAAa;AAAA,YACnB,YAAa,UAAW,KAAM;AAAA,eAC3B,iBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAejB,YAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sCASS,YAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qIAiDkF,KAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,6 @@
1
1
  // packages/editor/src/components/collaborators-overlay/overlay.tsx
2
2
  import { useResizeObserver, useMergeRefs } from "@wordpress/compose";
3
- import { useCallback, useEffect, useState } from "@wordpress/element";
3
+ import { useCallback, useEffect, useRef, useState } from "@wordpress/element";
4
4
  import { __ } from "@wordpress/i18n";
5
5
  import Avatar from "../collaborators-presence/avatar/index.mjs";
6
6
  import { AVATAR_IFRAME_STYLES } from "./avatar-iframe-styles.mjs";
@@ -14,7 +14,8 @@ var CURSOR_REDRAW_INTERVAL_MS = 1e4;
14
14
  function Overlay({
15
15
  blockEditorDocument,
16
16
  postId,
17
- postType
17
+ postType,
18
+ cursorRegistry
18
19
  }) {
19
20
  const [overlayElement, setOverlayElement] = useState(null);
20
21
  const { cursors, rerenderCursorsAfterDelay } = useRenderCursors(
@@ -57,6 +58,34 @@ function Overlay({
57
58
  setOverlayElement,
58
59
  resizeObserverRef
59
60
  ]);
61
+ const cursorRefsMap = useRef(/* @__PURE__ */ new Map());
62
+ useEffect(() => {
63
+ if (!cursorRegistry) {
64
+ return;
65
+ }
66
+ const refs = cursorRefsMap.current;
67
+ const currentIds = new Set(cursors.map((c) => c.clientId));
68
+ for (const id of refs.keys()) {
69
+ if (!currentIds.has(id)) {
70
+ cursorRegistry.unregisterCursor(id);
71
+ refs.delete(id);
72
+ }
73
+ }
74
+ for (const [id, el] of refs.entries()) {
75
+ cursorRegistry.registerCursor(id, el);
76
+ }
77
+ return () => cursorRegistry.removeAll();
78
+ }, [cursors, cursorRegistry]);
79
+ const setCursorRef = useCallback(
80
+ (clientId) => (el) => {
81
+ if (el) {
82
+ cursorRefsMap.current.set(clientId, el);
83
+ } else {
84
+ cursorRefsMap.current.delete(clientId);
85
+ }
86
+ },
87
+ []
88
+ );
60
89
  return /* @__PURE__ */ jsxs("div", { className: "collaborators-overlay-full", ref: mergedRef, children: [
61
90
  /* @__PURE__ */ jsx("style", { children: AVATAR_IFRAME_STYLES + OVERLAY_IFRAME_STYLES }),
62
91
  cursors.map((cursor) => /* @__PURE__ */ jsxs("div", { children: [
@@ -77,6 +106,7 @@ function Overlay({
77
106
  /* @__PURE__ */ jsxs(
78
107
  "div",
79
108
  {
109
+ ref: setCursorRef(cursor.clientId),
80
110
  className: "collaborators-overlay-user",
81
111
  style: {
82
112
  left: `${cursor.x}px`,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/collaborators-overlay/overlay.tsx"],
4
- "sourcesContent": ["import { useResizeObserver, useMergeRefs } from '@wordpress/compose';\nimport { useCallback, useEffect, useState } from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\n\nimport Avatar from '../collaborators-presence/avatar';\nimport { AVATAR_IFRAME_STYLES } from './avatar-iframe-styles';\nimport { OVERLAY_IFRAME_STYLES } from './overlay-iframe-styles';\nimport { setDelayedInterval } from './timing-utils';\nimport { useBlockHighlighting } from './use-block-highlighting';\nimport { useRenderCursors } from './use-render-cursors';\n\n// Milliseconds to wait after a change before recomputing cursor positions.\nconst RERENDER_DELAY_MS = 500;\n\n// Periodically recompute cursor positions to account for DOM layout\n// changes that don't trigger awareness state updates (e.g. a collaborator\n// applying formatting shifts text but the cursor's logical position is\n// unchanged). Only active when remote cursors are visible.\nconst CURSOR_REDRAW_INTERVAL_MS = 10_000;\n\ninterface OverlayProps {\n\tblockEditorDocument?: Document;\n\tpostId: number | null;\n\tpostType: string | null;\n}\n\n/**\n * This component is responsible for rendering the overlay components within the editor iframe.\n *\n * @param props - The overlay props.\n * @param props.blockEditorDocument - The block editor document.\n * @param props.postId - The ID of the post.\n * @param props.postType - The type of the post.\n * @return The Overlay component.\n */\nexport function Overlay( {\n\tblockEditorDocument,\n\tpostId,\n\tpostType,\n}: OverlayProps ) {\n\t// Use state for the overlay element so that the hook re-runs once the ref is attached.\n\tconst [ overlayElement, setOverlayElement ] =\n\t\tuseState< HTMLDivElement | null >( null );\n\n\tconst { cursors, rerenderCursorsAfterDelay } = useRenderCursors(\n\t\toverlayElement,\n\t\tblockEditorDocument ?? null,\n\t\tpostId ?? null,\n\t\tpostType ?? null,\n\t\tRERENDER_DELAY_MS\n\t);\n\n\tconst { highlights, rerenderHighlightsAfterDelay } = useBlockHighlighting(\n\t\toverlayElement,\n\t\tblockEditorDocument ?? null,\n\t\tpostId ?? null,\n\t\tpostType ?? null,\n\t\tRERENDER_DELAY_MS\n\t);\n\n\t// Detect layout changes on overlay (e.g. turning on \"Show Template\") and window\n\t// resizes, and re-render the cursors and block highlights.\n\tconst onResize = useCallback( () => {\n\t\trerenderCursorsAfterDelay();\n\t\trerenderHighlightsAfterDelay();\n\t}, [ rerenderCursorsAfterDelay, rerenderHighlightsAfterDelay ] );\n\tconst resizeObserverRef = useResizeObserver( onResize );\n\n\t// Trigger the initial position computation on mount.\n\tuseEffect( () => {\n\t\tconst cleanupCursors = rerenderCursorsAfterDelay();\n\t\tconst cleanupHighlights = rerenderHighlightsAfterDelay();\n\t\treturn () => {\n\t\t\tcleanupCursors();\n\t\t\tcleanupHighlights();\n\t\t};\n\t}, [ rerenderCursorsAfterDelay, rerenderHighlightsAfterDelay ] );\n\n\tuseEffect( () => {\n\t\tif ( cursors.length === 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn setDelayedInterval(\n\t\t\trerenderCursorsAfterDelay,\n\t\t\tCURSOR_REDRAW_INTERVAL_MS\n\t\t);\n\t}, [ cursors.length, rerenderCursorsAfterDelay ] );\n\n\t// Merge the refs to use the same element for both overlay and resize observation\n\tconst mergedRef = useMergeRefs< HTMLDivElement | null >( [\n\t\tsetOverlayElement,\n\t\tresizeObserverRef,\n\t] );\n\n\t// This is a full overlay that covers the entire iframe document. Good for\n\t// scrollable elements like cursor indicators.\n\treturn (\n\t\t<div className=\"collaborators-overlay-full\" ref={ mergedRef }>\n\t\t\t<style>{ AVATAR_IFRAME_STYLES + OVERLAY_IFRAME_STYLES }</style>\n\t\t\t{ cursors.map( ( cursor ) => (\n\t\t\t\t<div key={ cursor.clientId }>\n\t\t\t\t\t{ ! cursor.isMe &&\n\t\t\t\t\t\tcursor.selectionRects?.map( ( rect, index ) => (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tkey={ `${ cursor.clientId }-sel-${ index }` }\n\t\t\t\t\t\t\t\tclassName=\"collaborators-overlay-selection-rect\"\n\t\t\t\t\t\t\t\tstyle={ {\n\t\t\t\t\t\t\t\t\tleft: `${ rect.x }px`,\n\t\t\t\t\t\t\t\t\ttop: `${ rect.y }px`,\n\t\t\t\t\t\t\t\t\twidth: `${ rect.width }px`,\n\t\t\t\t\t\t\t\t\theight: `${ rect.height }px`,\n\t\t\t\t\t\t\t\t\tbackgroundColor: cursor.color,\n\t\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) ) }\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName=\"collaborators-overlay-user\"\n\t\t\t\t\t\tstyle={ {\n\t\t\t\t\t\t\tleft: `${ cursor.x }px`,\n\t\t\t\t\t\t\ttop: `${ cursor.y }px`,\n\t\t\t\t\t\t} }\n\t\t\t\t\t>\n\t\t\t\t\t\t{ ! cursor.isMe && (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName=\"collaborators-overlay-user-cursor\"\n\t\t\t\t\t\t\t\tstyle={ {\n\t\t\t\t\t\t\t\t\tbackgroundColor: cursor.color,\n\t\t\t\t\t\t\t\t\theight: `${ cursor.height }px`,\n\t\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) }\n\t\t\t\t\t\t<Avatar\n\t\t\t\t\t\t\tclassName=\"collaborators-overlay-user-label\"\n\t\t\t\t\t\t\tvariant=\"badge\"\n\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\tsrc={ cursor.avatarUrl }\n\t\t\t\t\t\t\tname={ cursor.userName }\n\t\t\t\t\t\t\tlabel={ cursor.isMe ? __( 'You' ) : undefined }\n\t\t\t\t\t\t\tborderColor={ cursor.color }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) ) }\n\t\t\t{ highlights.map( ( highlight ) => (\n\t\t\t\t<Avatar\n\t\t\t\t\tkey={ highlight.blockId }\n\t\t\t\t\tclassName=\"collaborators-overlay-block-label\"\n\t\t\t\t\tvariant=\"badge\"\n\t\t\t\t\tsize=\"small\"\n\t\t\t\t\tsrc={ highlight.avatarUrl }\n\t\t\t\t\tname={ highlight.userName }\n\t\t\t\t\tborderColor={ highlight.color }\n\t\t\t\t\tstyle={ {\n\t\t\t\t\t\tleft: `${ highlight.x }px`,\n\t\t\t\t\t\ttop: `${ highlight.y }px`,\n\t\t\t\t\t} }\n\t\t\t\t/>\n\t\t\t) ) }\n\t\t</div>\n\t);\n}\n"],
5
- "mappings": ";AAAA,SAAS,mBAAmB,oBAAoB;AAChD,SAAS,aAAa,WAAW,gBAAgB;AACjD,SAAS,UAAU;AAEnB,OAAO,YAAY;AACnB,SAAS,4BAA4B;AACrC,SAAS,6BAA6B;AACtC,SAAS,0BAA0B;AACnC,SAAS,4BAA4B;AACrC,SAAS,wBAAwB;AA0F9B,cAiBE,YAjBF;AAvFH,IAAM,oBAAoB;AAM1B,IAAM,4BAA4B;AAiB3B,SAAS,QAAS;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AACD,GAAkB;AAEjB,QAAM,CAAE,gBAAgB,iBAAkB,IACzC,SAAmC,IAAK;AAEzC,QAAM,EAAE,SAAS,0BAA0B,IAAI;AAAA,IAC9C;AAAA,IACA,uBAAuB;AAAA,IACvB,UAAU;AAAA,IACV,YAAY;AAAA,IACZ;AAAA,EACD;AAEA,QAAM,EAAE,YAAY,6BAA6B,IAAI;AAAA,IACpD;AAAA,IACA,uBAAuB;AAAA,IACvB,UAAU;AAAA,IACV,YAAY;AAAA,IACZ;AAAA,EACD;AAIA,QAAM,WAAW,YAAa,MAAM;AACnC,8BAA0B;AAC1B,iCAA6B;AAAA,EAC9B,GAAG,CAAE,2BAA2B,4BAA6B,CAAE;AAC/D,QAAM,oBAAoB,kBAAmB,QAAS;AAGtD,YAAW,MAAM;AAChB,UAAM,iBAAiB,0BAA0B;AACjD,UAAM,oBAAoB,6BAA6B;AACvD,WAAO,MAAM;AACZ,qBAAe;AACf,wBAAkB;AAAA,IACnB;AAAA,EACD,GAAG,CAAE,2BAA2B,4BAA6B,CAAE;AAE/D,YAAW,MAAM;AAChB,QAAK,QAAQ,WAAW,GAAI;AAC3B;AAAA,IACD;AAEA,WAAO;AAAA,MACN;AAAA,MACA;AAAA,IACD;AAAA,EACD,GAAG,CAAE,QAAQ,QAAQ,yBAA0B,CAAE;AAGjD,QAAM,YAAY,aAAuC;AAAA,IACxD;AAAA,IACA;AAAA,EACD,CAAE;AAIF,SACC,qBAAC,SAAI,WAAU,8BAA6B,KAAM,WACjD;AAAA,wBAAC,WAAQ,iCAAuB,uBAAuB;AAAA,IACrD,QAAQ,IAAK,CAAE,WAChB,qBAAC,SACE;AAAA,OAAE,OAAO,QACV,OAAO,gBAAgB,IAAK,CAAE,MAAM,UACnC;AAAA,QAAC;AAAA;AAAA,UAEA,WAAU;AAAA,UACV,OAAQ;AAAA,YACP,MAAM,GAAI,KAAK,CAAE;AAAA,YACjB,KAAK,GAAI,KAAK,CAAE;AAAA,YAChB,OAAO,GAAI,KAAK,KAAM;AAAA,YACtB,QAAQ,GAAI,KAAK,MAAO;AAAA,YACxB,iBAAiB,OAAO;AAAA,UACzB;AAAA;AAAA,QARM,GAAI,OAAO,QAAS,QAAS,KAAM;AAAA,MAS1C,CACC;AAAA,MACH;AAAA,QAAC;AAAA;AAAA,UACA,WAAU;AAAA,UACV,OAAQ;AAAA,YACP,MAAM,GAAI,OAAO,CAAE;AAAA,YACnB,KAAK,GAAI,OAAO,CAAE;AAAA,UACnB;AAAA,UAEE;AAAA,aAAE,OAAO,QACV;AAAA,cAAC;AAAA;AAAA,gBACA,WAAU;AAAA,gBACV,OAAQ;AAAA,kBACP,iBAAiB,OAAO;AAAA,kBACxB,QAAQ,GAAI,OAAO,MAAO;AAAA,gBAC3B;AAAA;AAAA,YACD;AAAA,YAED;AAAA,cAAC;AAAA;AAAA,gBACA,WAAU;AAAA,gBACV,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,KAAM,OAAO;AAAA,gBACb,MAAO,OAAO;AAAA,gBACd,OAAQ,OAAO,OAAO,GAAI,KAAM,IAAI;AAAA,gBACpC,aAAc,OAAO;AAAA;AAAA,YACtB;AAAA;AAAA;AAAA,MACD;AAAA,SAxCU,OAAO,QAyClB,CACC;AAAA,IACA,WAAW,IAAK,CAAE,cACnB;AAAA,MAAC;AAAA;AAAA,QAEA,WAAU;AAAA,QACV,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,KAAM,UAAU;AAAA,QAChB,MAAO,UAAU;AAAA,QACjB,aAAc,UAAU;AAAA,QACxB,OAAQ;AAAA,UACP,MAAM,GAAI,UAAU,CAAE;AAAA,UACtB,KAAK,GAAI,UAAU,CAAE;AAAA,QACtB;AAAA;AAAA,MAVM,UAAU;AAAA,IAWjB,CACC;AAAA,KACH;AAEF;",
4
+ "sourcesContent": ["import { useResizeObserver, useMergeRefs } from '@wordpress/compose';\nimport { useCallback, useEffect, useRef, useState } from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\n\nimport Avatar from '../collaborators-presence/avatar';\nimport { AVATAR_IFRAME_STYLES } from './avatar-iframe-styles';\nimport { OVERLAY_IFRAME_STYLES } from './overlay-iframe-styles';\nimport { setDelayedInterval } from './timing-utils';\nimport { useBlockHighlighting } from './use-block-highlighting';\nimport { useRenderCursors } from './use-render-cursors';\nimport { type CursorRegistry } from './cursor-registry';\n\n// Milliseconds to wait after a change before recomputing cursor positions.\nconst RERENDER_DELAY_MS = 500;\n\n// Periodically recompute cursor positions to account for DOM layout\n// changes that don't trigger awareness state updates (e.g. a collaborator\n// applying formatting shifts text but the cursor's logical position is\n// unchanged). Only active when remote cursors are visible.\nconst CURSOR_REDRAW_INTERVAL_MS = 10_000;\n\ninterface OverlayProps {\n\tblockEditorDocument?: Document;\n\tpostId: number | null;\n\tpostType: string | null;\n\tcursorRegistry?: CursorRegistry;\n}\n\n/**\n * This component is responsible for rendering the overlay components within the editor iframe.\n *\n * @param props - The overlay props.\n * @param props.blockEditorDocument - The block editor document.\n * @param props.postId - The ID of the post.\n * @param props.postType - The type of the post.\n * @param props.cursorRegistry - The shared cursor registry.\n * @return The Overlay component.\n */\nexport function Overlay( {\n\tblockEditorDocument,\n\tpostId,\n\tpostType,\n\tcursorRegistry,\n}: OverlayProps ) {\n\t// Use state for the overlay element so that the hook re-runs once the ref is attached.\n\tconst [ overlayElement, setOverlayElement ] =\n\t\tuseState< HTMLDivElement | null >( null );\n\n\tconst { cursors, rerenderCursorsAfterDelay } = useRenderCursors(\n\t\toverlayElement,\n\t\tblockEditorDocument ?? null,\n\t\tpostId ?? null,\n\t\tpostType ?? null,\n\t\tRERENDER_DELAY_MS\n\t);\n\n\tconst { highlights, rerenderHighlightsAfterDelay } = useBlockHighlighting(\n\t\toverlayElement,\n\t\tblockEditorDocument ?? null,\n\t\tpostId ?? null,\n\t\tpostType ?? null,\n\t\tRERENDER_DELAY_MS\n\t);\n\n\t// Detect layout changes on overlay (e.g. turning on \"Show Template\") and window\n\t// resizes, and re-render the cursors and block highlights.\n\tconst onResize = useCallback( () => {\n\t\trerenderCursorsAfterDelay();\n\t\trerenderHighlightsAfterDelay();\n\t}, [ rerenderCursorsAfterDelay, rerenderHighlightsAfterDelay ] );\n\tconst resizeObserverRef = useResizeObserver( onResize );\n\n\t// Trigger the initial position computation on mount.\n\tuseEffect( () => {\n\t\tconst cleanupCursors = rerenderCursorsAfterDelay();\n\t\tconst cleanupHighlights = rerenderHighlightsAfterDelay();\n\t\treturn () => {\n\t\t\tcleanupCursors();\n\t\t\tcleanupHighlights();\n\t\t};\n\t}, [ rerenderCursorsAfterDelay, rerenderHighlightsAfterDelay ] );\n\n\tuseEffect( () => {\n\t\tif ( cursors.length === 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn setDelayedInterval(\n\t\t\trerenderCursorsAfterDelay,\n\t\t\tCURSOR_REDRAW_INTERVAL_MS\n\t\t);\n\t}, [ cursors.length, rerenderCursorsAfterDelay ] );\n\n\t// Merge the refs to use the same element for both overlay and resize observation\n\tconst mergedRef = useMergeRefs< HTMLDivElement | null >( [\n\t\tsetOverlayElement,\n\t\tresizeObserverRef,\n\t] );\n\n\t// Track cursor element refs for registry registration.\n\tconst cursorRefsMap = useRef< Map< number, HTMLElement > >( new Map() );\n\n\t// Keep the registry in sync whenever the rendered cursors change.\n\tuseEffect( () => {\n\t\tif ( ! cursorRegistry ) {\n\t\t\treturn;\n\t\t}\n\t\tconst refs = cursorRefsMap.current;\n\t\tconst currentIds = new Set( cursors.map( ( c ) => c.clientId ) );\n\n\t\t// Unregister cursors that are no longer rendered.\n\t\tfor ( const id of refs.keys() ) {\n\t\t\tif ( ! currentIds.has( id ) ) {\n\t\t\t\tcursorRegistry.unregisterCursor( id );\n\t\t\t\trefs.delete( id );\n\t\t\t}\n\t\t}\n\n\t\t// Register or update cursors that are currently rendered.\n\t\tfor ( const [ id, el ] of refs.entries() ) {\n\t\t\tcursorRegistry.registerCursor( id, el );\n\t\t}\n\n\t\treturn () => cursorRegistry.removeAll();\n\t}, [ cursors, cursorRegistry ] );\n\n\t// Callback ref factory to capture each cursor's DOM element.\n\tconst setCursorRef = useCallback(\n\t\t( clientId: number ) => ( el: HTMLDivElement | null ) => {\n\t\t\tif ( el ) {\n\t\t\t\tcursorRefsMap.current.set( clientId, el );\n\t\t\t} else {\n\t\t\t\tcursorRefsMap.current.delete( clientId );\n\t\t\t}\n\t\t},\n\t\t[]\n\t);\n\n\t// This is a full overlay that covers the entire iframe document. Good for\n\t// scrollable elements like cursor indicators.\n\treturn (\n\t\t<div className=\"collaborators-overlay-full\" ref={ mergedRef }>\n\t\t\t<style>{ AVATAR_IFRAME_STYLES + OVERLAY_IFRAME_STYLES }</style>\n\t\t\t{ cursors.map( ( cursor ) => (\n\t\t\t\t<div key={ cursor.clientId }>\n\t\t\t\t\t{ ! cursor.isMe &&\n\t\t\t\t\t\tcursor.selectionRects?.map( ( rect, index ) => (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tkey={ `${ cursor.clientId }-sel-${ index }` }\n\t\t\t\t\t\t\t\tclassName=\"collaborators-overlay-selection-rect\"\n\t\t\t\t\t\t\t\tstyle={ {\n\t\t\t\t\t\t\t\t\tleft: `${ rect.x }px`,\n\t\t\t\t\t\t\t\t\ttop: `${ rect.y }px`,\n\t\t\t\t\t\t\t\t\twidth: `${ rect.width }px`,\n\t\t\t\t\t\t\t\t\theight: `${ rect.height }px`,\n\t\t\t\t\t\t\t\t\tbackgroundColor: cursor.color,\n\t\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) ) }\n\t\t\t\t\t<div\n\t\t\t\t\t\tref={ setCursorRef( cursor.clientId ) }\n\t\t\t\t\t\tclassName=\"collaborators-overlay-user\"\n\t\t\t\t\t\tstyle={ {\n\t\t\t\t\t\t\tleft: `${ cursor.x }px`,\n\t\t\t\t\t\t\ttop: `${ cursor.y }px`,\n\t\t\t\t\t\t} }\n\t\t\t\t\t>\n\t\t\t\t\t\t{ ! cursor.isMe && (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName=\"collaborators-overlay-user-cursor\"\n\t\t\t\t\t\t\t\tstyle={ {\n\t\t\t\t\t\t\t\t\tbackgroundColor: cursor.color,\n\t\t\t\t\t\t\t\t\theight: `${ cursor.height }px`,\n\t\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) }\n\t\t\t\t\t\t<Avatar\n\t\t\t\t\t\t\tclassName=\"collaborators-overlay-user-label\"\n\t\t\t\t\t\t\tvariant=\"badge\"\n\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\tsrc={ cursor.avatarUrl }\n\t\t\t\t\t\t\tname={ cursor.userName }\n\t\t\t\t\t\t\tlabel={ cursor.isMe ? __( 'You' ) : undefined }\n\t\t\t\t\t\t\tborderColor={ cursor.color }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) ) }\n\t\t\t{ highlights.map( ( highlight ) => (\n\t\t\t\t<Avatar\n\t\t\t\t\tkey={ highlight.blockId }\n\t\t\t\t\tclassName=\"collaborators-overlay-block-label\"\n\t\t\t\t\tvariant=\"badge\"\n\t\t\t\t\tsize=\"small\"\n\t\t\t\t\tsrc={ highlight.avatarUrl }\n\t\t\t\t\tname={ highlight.userName }\n\t\t\t\t\tborderColor={ highlight.color }\n\t\t\t\t\tstyle={ {\n\t\t\t\t\t\tleft: `${ highlight.x }px`,\n\t\t\t\t\t\ttop: `${ highlight.y }px`,\n\t\t\t\t\t} }\n\t\t\t\t/>\n\t\t\t) ) }\n\t\t</div>\n\t);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -11,11 +11,12 @@ import { CollaboratorsList } from "./list.mjs";
11
11
  import { unlock } from "../../lock-unlock.mjs";
12
12
  import { getAvatarUrl } from "../collaborators-overlay/get-avatar-url.mjs";
13
13
  import { getAvatarBorderColor } from "../collab-sidebar/utils.mjs";
14
+ import { createCursorRegistry } from "../collaborators-overlay/cursor-registry.mjs";
14
15
 
15
16
  // packages/editor/src/components/collaborators-presence/styles/collaborators-presence.scss
16
- if (typeof document !== "undefined" && process.env.NODE_ENV !== "test" && !document.head.querySelector("style[data-wp-hash='eee1778bc0']")) {
17
+ if (typeof document !== "undefined" && process.env.NODE_ENV !== "test" && !document.head.querySelector("style[data-wp-hash='5ffe927286']")) {
17
18
  const style = document.createElement("style");
18
- style.setAttribute("data-wp-hash", "eee1778bc0");
19
+ style.setAttribute("data-wp-hash", "5ffe927286");
19
20
  style.appendChild(document.createTextNode(".editor-collaborators-presence{align-items:center;background:#f0f0f0;border-radius:4px;display:flex;flex-shrink:0;height:32px;margin-right:8px}.editor-collaborators-presence:has(.is-pressed),.editor-collaborators-presence:hover{background-color:#e0e0e0}.editor-collaborators-presence__button.editor-collaborators-presence__button.components-button{align-items:center;background:#0000;border-radius:4px;box-sizing:border-box;color:#2f2f2f;cursor:pointer;display:flex;height:100%;padding:4px;position:relative}.editor-collaborators-presence__button.editor-collaborators-presence__button.components-button.is-pressed,.editor-collaborators-presence__button.editor-collaborators-presence__button.components-button.is-pressed:hover,.editor-collaborators-presence__button.editor-collaborators-presence__button.components-button:hover{background:#0000;color:#2f2f2f}.editor-collaborators-presence__button.editor-collaborators-presence__button.components-button:focus:not(:active){box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus,2px) var(--wp-admin-theme-color,#007cba);outline:none}"));
20
21
  document.head.appendChild(style);
21
22
  }
@@ -46,6 +47,7 @@ function CollaboratorsPresence({
46
47
  return 0;
47
48
  });
48
49
  }, [activeCollaborators]);
50
+ const [cursorRegistry] = useState(createCursorRegistry);
49
51
  const [isPopoverVisible, setIsPopoverVisible] = useState(false);
50
52
  const [popoverAnchor, setPopoverAnchor] = useState(
51
53
  null
@@ -106,11 +108,19 @@ function CollaboratorsPresence({
106
108
  {
107
109
  activeCollaborators: collaboratorsForList,
108
110
  popoverAnchor,
109
- setIsPopoverVisible
111
+ setIsPopoverVisible,
112
+ cursorRegistry
110
113
  }
111
114
  )
112
115
  ] }),
113
- /* @__PURE__ */ jsx(CollaboratorsOverlay, { postId, postType })
116
+ /* @__PURE__ */ jsx(
117
+ CollaboratorsOverlay,
118
+ {
119
+ postId,
120
+ postType,
121
+ cursorRegistry
122
+ }
123
+ )
114
124
  ] });
115
125
  }
116
126
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/collaborators-presence/index.tsx", "../../../src/components/collaborators-presence/styles/collaborators-presence.scss"],
4
- "sourcesContent": ["import { Button } from '@wordpress/components';\nimport { useMemo, useState } from '@wordpress/element';\nimport {\n\tprivateApis,\n\ttype PostEditorAwarenessState,\n} from '@wordpress/core-data';\nimport { __, sprintf } from '@wordpress/i18n';\n\nimport Avatar from './avatar';\nimport AvatarGroup from './avatar-group';\nimport { CollaboratorsList } from './list';\nimport { unlock } from '../../lock-unlock';\nimport { getAvatarUrl } from '../collaborators-overlay/get-avatar-url';\nimport { getAvatarBorderColor } from '../collab-sidebar/utils';\n\nimport './styles/collaborators-presence.scss';\nimport { CollaboratorsOverlay } from '../collaborators-overlay';\n\nconst { useActiveCollaborators } = unlock( privateApis );\n\ninterface CollaboratorsPresenceProps {\n\tpostId: number | null;\n\tpostType: string | null;\n}\n\n/**\n * Renders a list of avatars for the active collaborators, with a maximum of 3 visible avatars.\n * Shows a popover with all collaborators on hover.\n *\n * @param props CollaboratorsPresence component props\n * @param props.postId ID of the post\n * @param props.postType Type of the post\n */\nexport function CollaboratorsPresence( {\n\tpostId,\n\tpostType,\n}: CollaboratorsPresenceProps ) {\n\tconst activeCollaborators = useActiveCollaborators(\n\t\tpostId,\n\t\tpostType\n\t) as PostEditorAwarenessState[];\n\n\tconst otherActiveCollaborators = activeCollaborators.filter(\n\t\t( c ) => ! c.isMe\n\t);\n\n\t// Always include self in the list sorted first.\n\tconst collaboratorsForList = useMemo( () => {\n\t\treturn [ ...activeCollaborators ].sort( ( a, b ) => {\n\t\t\tif ( a.isMe && ! b.isMe ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( ! a.isMe && b.isMe ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\treturn 0;\n\t\t} );\n\t}, [ activeCollaborators ] );\n\n\tconst [ isPopoverVisible, setIsPopoverVisible ] = useState( false );\n\tconst [ popoverAnchor, setPopoverAnchor ] = useState< HTMLElement | null >(\n\t\tnull\n\t);\n\n\t// When there are no other collaborators, this component should not render\n\t// at all. This will always be the case when collaboration is not enabled, but\n\t// also when the current user is the only editor with the post open.\n\tif ( otherActiveCollaborators.length === 0 ) {\n\t\treturn null;\n\t}\n\n\tconst me = activeCollaborators.find( ( c ) => c.isMe );\n\n\treturn (\n\t\t<>\n\t\t\t<div className=\"editor-collaborators-presence\">\n\t\t\t\t<Button\n\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\tclassName=\"editor-collaborators-presence__button\"\n\t\t\t\t\tonClick={ () => setIsPopoverVisible( ! isPopoverVisible ) }\n\t\t\t\t\tisPressed={ isPopoverVisible }\n\t\t\t\t\tref={ setPopoverAnchor }\n\t\t\t\t\taria-label={ sprintf(\n\t\t\t\t\t\t// translators: %d: number of online collaborators.\n\t\t\t\t\t\t__( 'Collaborators list, %d online' ),\n\t\t\t\t\t\tcollaboratorsForList.length\n\t\t\t\t\t) }\n\t\t\t\t>\n\t\t\t\t\t<AvatarGroup max={ 4 }>\n\t\t\t\t\t\t{ me && (\n\t\t\t\t\t\t\t<Avatar\n\t\t\t\t\t\t\t\tkey={ me.clientId }\n\t\t\t\t\t\t\t\tsrc={ getAvatarUrl(\n\t\t\t\t\t\t\t\t\tme.collaboratorInfo.avatar_urls\n\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\tname={ me.collaboratorInfo.name }\n\t\t\t\t\t\t\t\tborderColor=\"var(--wp-admin-theme-color)\"\n\t\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) }\n\t\t\t\t\t\t{ otherActiveCollaborators.map(\n\t\t\t\t\t\t\t( collaboratorState ) => (\n\t\t\t\t\t\t\t\t<Avatar\n\t\t\t\t\t\t\t\t\tkey={ collaboratorState.clientId }\n\t\t\t\t\t\t\t\t\tsrc={ getAvatarUrl(\n\t\t\t\t\t\t\t\t\t\tcollaboratorState.collaboratorInfo\n\t\t\t\t\t\t\t\t\t\t\t.avatar_urls\n\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\tname={\n\t\t\t\t\t\t\t\t\t\tcollaboratorState.collaboratorInfo.name\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tborderColor={ getAvatarBorderColor(\n\t\t\t\t\t\t\t\t\t\tcollaboratorState.collaboratorInfo.id\n\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t) }\n\t\t\t\t\t</AvatarGroup>\n\t\t\t\t</Button>\n\t\t\t\t{ isPopoverVisible && (\n\t\t\t\t\t<CollaboratorsList\n\t\t\t\t\t\tactiveCollaborators={ collaboratorsForList }\n\t\t\t\t\t\tpopoverAnchor={ popoverAnchor }\n\t\t\t\t\t\tsetIsPopoverVisible={ setIsPopoverVisible }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t</div>\n\t\t\t<CollaboratorsOverlay postId={ postId } postType={ postType } />\n\t\t</>\n\t);\n}\n", "if (typeof document !== 'undefined' && process.env.NODE_ENV !== 'test' && !document.head.querySelector(\"style[data-wp-hash='eee1778bc0']\")) {\n\tconst style = document.createElement(\"style\");\n\tstyle.setAttribute(\"data-wp-hash\", \"eee1778bc0\");\n\tstyle.appendChild(document.createTextNode(\".editor-collaborators-presence{align-items:center;background:#f0f0f0;border-radius:4px;display:flex;flex-shrink:0;height:32px;margin-right:8px}.editor-collaborators-presence:has(.is-pressed),.editor-collaborators-presence:hover{background-color:#e0e0e0}.editor-collaborators-presence__button.editor-collaborators-presence__button.components-button{align-items:center;background:#0000;border-radius:4px;box-sizing:border-box;color:#2f2f2f;cursor:pointer;display:flex;height:100%;padding:4px;position:relative}.editor-collaborators-presence__button.editor-collaborators-presence__button.components-button.is-pressed,.editor-collaborators-presence__button.editor-collaborators-presence__button.components-button.is-pressed:hover,.editor-collaborators-presence__button.editor-collaborators-presence__button.components-button:hover{background:#0000;color:#2f2f2f}.editor-collaborators-presence__button.editor-collaborators-presence__button.components-button:focus:not(:active){box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus,2px) var(--wp-admin-theme-color,#007cba);outline:none}\"));\n\tdocument.head.appendChild(style);\n}\n"],
5
- "mappings": ";AAAA,SAAS,cAAc;AACvB,SAAS,SAAS,gBAAgB;AAClC;AAAA,EACC;AAAA,OAEM;AACP,SAAS,IAAI,eAAe;AAE5B,OAAO,YAAY;AACnB,OAAO,iBAAiB;AACxB,SAAS,yBAAyB;AAClC,SAAS,cAAc;AACvB,SAAS,oBAAoB;AAC7B,SAAS,4BAA4B;;;ACbrC,IAAI,OAAO,aAAa,eAAe,QAAQ,IAAI,aAAa,UAAU,CAAC,SAAS,KAAK,cAAc,kCAAkC,GAAG;AAC3I,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAM,aAAa,gBAAgB,YAAY;AAC/C,QAAM,YAAY,SAAS,eAAe,6jCAA6jC,CAAC;AACxmC,WAAS,KAAK,YAAY,KAAK;AAChC;;;ADWA,SAAS,4BAA4B;AA0DnC,mBAgBK,KAFF,YAdH;AAxDF,IAAM,EAAE,uBAAuB,IAAI,OAAQ,WAAY;AAehD,SAAS,sBAAuB;AAAA,EACtC;AAAA,EACA;AACD,GAAgC;AAC/B,QAAM,sBAAsB;AAAA,IAC3B;AAAA,IACA;AAAA,EACD;AAEA,QAAM,2BAA2B,oBAAoB;AAAA,IACpD,CAAE,MAAO,CAAE,EAAE;AAAA,EACd;AAGA,QAAM,uBAAuB,QAAS,MAAM;AAC3C,WAAO,CAAE,GAAG,mBAAoB,EAAE,KAAM,CAAE,GAAG,MAAO;AACnD,UAAK,EAAE,QAAQ,CAAE,EAAE,MAAO;AACzB,eAAO;AAAA,MACR;AACA,UAAK,CAAE,EAAE,QAAQ,EAAE,MAAO;AACzB,eAAO;AAAA,MACR;AACA,aAAO;AAAA,IACR,CAAE;AAAA,EACH,GAAG,CAAE,mBAAoB,CAAE;AAE3B,QAAM,CAAE,kBAAkB,mBAAoB,IAAI,SAAU,KAAM;AAClE,QAAM,CAAE,eAAe,gBAAiB,IAAI;AAAA,IAC3C;AAAA,EACD;AAKA,MAAK,yBAAyB,WAAW,GAAI;AAC5C,WAAO;AAAA,EACR;AAEA,QAAM,KAAK,oBAAoB,KAAM,CAAE,MAAO,EAAE,IAAK;AAErD,SACC,iCACC;AAAA,yBAAC,SAAI,WAAU,iCACd;AAAA;AAAA,QAAC;AAAA;AAAA,UACA,uBAAqB;AAAA,UACrB,WAAU;AAAA,UACV,SAAU,MAAM,oBAAqB,CAAE,gBAAiB;AAAA,UACxD,WAAY;AAAA,UACZ,KAAM;AAAA,UACN,cAAa;AAAA;AAAA,YAEZ,GAAI,+BAAgC;AAAA,YACpC,qBAAqB;AAAA,UACtB;AAAA,UAEA,+BAAC,eAAY,KAAM,GAChB;AAAA,kBACD;AAAA,cAAC;AAAA;AAAA,gBAEA,KAAM;AAAA,kBACL,GAAG,iBAAiB;AAAA,gBACrB;AAAA,gBACA,MAAO,GAAG,iBAAiB;AAAA,gBAC3B,aAAY;AAAA,gBACZ,MAAK;AAAA;AAAA,cANC,GAAG;AAAA,YAOV;AAAA,YAEC,yBAAyB;AAAA,cAC1B,CAAE,sBACD;AAAA,gBAAC;AAAA;AAAA,kBAEA,KAAM;AAAA,oBACL,kBAAkB,iBAChB;AAAA,kBACH;AAAA,kBACA,MACC,kBAAkB,iBAAiB;AAAA,kBAEpC,aAAc;AAAA,oBACb,kBAAkB,iBAAiB;AAAA,kBACpC;AAAA,kBACA,MAAK;AAAA;AAAA,gBAXC,kBAAkB;AAAA,cAYzB;AAAA,YAEF;AAAA,aACD;AAAA;AAAA,MACD;AAAA,MACE,oBACD;AAAA,QAAC;AAAA;AAAA,UACA,qBAAsB;AAAA,UACtB;AAAA,UACA;AAAA;AAAA,MACD;AAAA,OAEF;AAAA,IACA,oBAAC,wBAAqB,QAAkB,UAAsB;AAAA,KAC/D;AAEF;",
4
+ "sourcesContent": ["import { Button } from '@wordpress/components';\nimport { useMemo, useState } from '@wordpress/element';\nimport {\n\tprivateApis,\n\ttype PostEditorAwarenessState,\n} from '@wordpress/core-data';\nimport { __, sprintf } from '@wordpress/i18n';\n\nimport Avatar from './avatar';\nimport AvatarGroup from './avatar-group';\nimport { CollaboratorsList } from './list';\nimport { unlock } from '../../lock-unlock';\nimport { getAvatarUrl } from '../collaborators-overlay/get-avatar-url';\nimport { getAvatarBorderColor } from '../collab-sidebar/utils';\nimport { createCursorRegistry } from '../collaborators-overlay/cursor-registry';\n\nimport './styles/collaborators-presence.scss';\nimport { CollaboratorsOverlay } from '../collaborators-overlay';\n\nconst { useActiveCollaborators } = unlock( privateApis );\n\ninterface CollaboratorsPresenceProps {\n\tpostId: number | null;\n\tpostType: string | null;\n}\n\n/**\n * Renders a list of avatars for the active collaborators, with a maximum of 3 visible avatars.\n * Shows a popover with all collaborators on hover.\n *\n * @param props CollaboratorsPresence component props\n * @param props.postId ID of the post\n * @param props.postType Type of the post\n */\nexport function CollaboratorsPresence( {\n\tpostId,\n\tpostType,\n}: CollaboratorsPresenceProps ) {\n\tconst activeCollaborators = useActiveCollaborators(\n\t\tpostId,\n\t\tpostType\n\t) as PostEditorAwarenessState[];\n\n\tconst otherActiveCollaborators = activeCollaborators.filter(\n\t\t( c ) => ! c.isMe\n\t);\n\n\t// Always include self in the list sorted first.\n\tconst collaboratorsForList = useMemo( () => {\n\t\treturn [ ...activeCollaborators ].sort( ( a, b ) => {\n\t\t\tif ( a.isMe && ! b.isMe ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( ! a.isMe && b.isMe ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\treturn 0;\n\t\t} );\n\t}, [ activeCollaborators ] );\n\n\tconst [ cursorRegistry ] = useState( createCursorRegistry );\n\n\tconst [ isPopoverVisible, setIsPopoverVisible ] = useState( false );\n\tconst [ popoverAnchor, setPopoverAnchor ] = useState< HTMLElement | null >(\n\t\tnull\n\t);\n\n\t// When there are no other collaborators, this component should not render\n\t// at all. This will always be the case when collaboration is not enabled, but\n\t// also when the current user is the only editor with the post open.\n\tif ( otherActiveCollaborators.length === 0 ) {\n\t\treturn null;\n\t}\n\n\tconst me = activeCollaborators.find( ( c ) => c.isMe );\n\n\treturn (\n\t\t<>\n\t\t\t<div className=\"editor-collaborators-presence\">\n\t\t\t\t<Button\n\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\tclassName=\"editor-collaborators-presence__button\"\n\t\t\t\t\tonClick={ () => setIsPopoverVisible( ! isPopoverVisible ) }\n\t\t\t\t\tisPressed={ isPopoverVisible }\n\t\t\t\t\tref={ setPopoverAnchor }\n\t\t\t\t\taria-label={ sprintf(\n\t\t\t\t\t\t// translators: %d: number of online collaborators.\n\t\t\t\t\t\t__( 'Collaborators list, %d online' ),\n\t\t\t\t\t\tcollaboratorsForList.length\n\t\t\t\t\t) }\n\t\t\t\t>\n\t\t\t\t\t<AvatarGroup max={ 4 }>\n\t\t\t\t\t\t{ me && (\n\t\t\t\t\t\t\t<Avatar\n\t\t\t\t\t\t\t\tkey={ me.clientId }\n\t\t\t\t\t\t\t\tsrc={ getAvatarUrl(\n\t\t\t\t\t\t\t\t\tme.collaboratorInfo.avatar_urls\n\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\tname={ me.collaboratorInfo.name }\n\t\t\t\t\t\t\t\tborderColor=\"var(--wp-admin-theme-color)\"\n\t\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) }\n\t\t\t\t\t\t{ otherActiveCollaborators.map(\n\t\t\t\t\t\t\t( collaboratorState ) => (\n\t\t\t\t\t\t\t\t<Avatar\n\t\t\t\t\t\t\t\t\tkey={ collaboratorState.clientId }\n\t\t\t\t\t\t\t\t\tsrc={ getAvatarUrl(\n\t\t\t\t\t\t\t\t\t\tcollaboratorState.collaboratorInfo\n\t\t\t\t\t\t\t\t\t\t\t.avatar_urls\n\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\tname={\n\t\t\t\t\t\t\t\t\t\tcollaboratorState.collaboratorInfo.name\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tborderColor={ getAvatarBorderColor(\n\t\t\t\t\t\t\t\t\t\tcollaboratorState.collaboratorInfo.id\n\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t) }\n\t\t\t\t\t</AvatarGroup>\n\t\t\t\t</Button>\n\t\t\t\t{ isPopoverVisible && (\n\t\t\t\t\t<CollaboratorsList\n\t\t\t\t\t\tactiveCollaborators={ collaboratorsForList }\n\t\t\t\t\t\tpopoverAnchor={ popoverAnchor }\n\t\t\t\t\t\tsetIsPopoverVisible={ setIsPopoverVisible }\n\t\t\t\t\t\tcursorRegistry={ cursorRegistry }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t</div>\n\t\t\t<CollaboratorsOverlay\n\t\t\t\tpostId={ postId }\n\t\t\t\tpostType={ postType }\n\t\t\t\tcursorRegistry={ cursorRegistry }\n\t\t\t/>\n\t\t</>\n\t);\n}\n", "if (typeof document !== 'undefined' && process.env.NODE_ENV !== 'test' && !document.head.querySelector(\"style[data-wp-hash='5ffe927286']\")) {\n\tconst style = document.createElement(\"style\");\n\tstyle.setAttribute(\"data-wp-hash\", \"5ffe927286\");\n\tstyle.appendChild(document.createTextNode(\".editor-collaborators-presence{align-items:center;background:#f0f0f0;border-radius:4px;display:flex;flex-shrink:0;height:32px;margin-right:8px}.editor-collaborators-presence:has(.is-pressed),.editor-collaborators-presence:hover{background-color:#e0e0e0}.editor-collaborators-presence__button.editor-collaborators-presence__button.components-button{align-items:center;background:#0000;border-radius:4px;box-sizing:border-box;color:#2f2f2f;cursor:pointer;display:flex;height:100%;padding:4px;position:relative}.editor-collaborators-presence__button.editor-collaborators-presence__button.components-button.is-pressed,.editor-collaborators-presence__button.editor-collaborators-presence__button.components-button.is-pressed:hover,.editor-collaborators-presence__button.editor-collaborators-presence__button.components-button:hover{background:#0000;color:#2f2f2f}.editor-collaborators-presence__button.editor-collaborators-presence__button.components-button:focus:not(:active){box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus,2px) var(--wp-admin-theme-color,#007cba);outline:none}\"));\n\tdocument.head.appendChild(style);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -2,14 +2,15 @@
2
2
  import { __ } from "@wordpress/i18n";
3
3
  import { Popover, Button } from "@wordpress/components";
4
4
  import { closeSmall } from "@wordpress/icons";
5
+ import { speak } from "@wordpress/a11y";
5
6
  import Avatar from "./avatar/index.mjs";
6
7
  import { getAvatarUrl } from "../collaborators-overlay/get-avatar-url.mjs";
7
8
  import { getAvatarBorderColor } from "../collab-sidebar/utils.mjs";
8
9
 
9
10
  // packages/editor/src/components/collaborators-presence/styles/collaborators-list.scss
10
- if (typeof document !== "undefined" && process.env.NODE_ENV !== "test" && !document.head.querySelector("style[data-wp-hash='9537a5e604']")) {
11
+ if (typeof document !== "undefined" && process.env.NODE_ENV !== "test" && !document.head.querySelector("style[data-wp-hash='0f8400f482']")) {
11
12
  const style = document.createElement("style");
12
- style.setAttribute("data-wp-hash", "9537a5e604");
13
+ style.setAttribute("data-wp-hash", "0f8400f482");
13
14
  style.appendChild(document.createTextNode(".editor-collaborators-presence__list.components-popover .components-popover__content{background:#fff;border:1px solid #ddd;border-radius:8px;border-width:1px 0 0 1px;box-shadow:0 1px 2px #0000000d,0 2px 3px #0000000a,0 6px 6px #00000008,0 8px 8px #00000005}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-content{min-width:280px}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-header{align-items:center;display:flex;justify-content:space-between;padding:8px 16px}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-header-title{display:flex;font-size:13px;font-weight:499;gap:4px;line-height:20px}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-header-title span{color:#757575}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-header-action{padding:0}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-header-action button{color:#1e1e1e;height:32px;padding:0;width:32px}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-items{display:flex;flex-direction:column;padding-bottom:16px}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item{all:unset;align-items:center;box-sizing:border-box;cursor:pointer;display:flex;gap:8px;padding:12px 16px;transition:background-color .2s ease;width:100%}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item:hover:not(:disabled){background-color:rgba(var(--wp-admin-theme-color--rgb),.04)}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item:active:not(:disabled){background-color:rgba(var(--wp-admin-theme-color--rgb),.08)}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item:focus-visible{outline:2px solid var(--wp-admin-theme-color,#3858e9);outline-offset:-2px}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item:disabled{cursor:default}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item-info{display:flex;flex:1;flex-direction:column;min-width:0}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item-name{color:#1e1e1e;font-size:13px;font-weight:499;line-height:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}"));
14
15
  document.head.appendChild(style);
15
16
  }
@@ -19,8 +20,20 @@ import { jsx, jsxs } from "react/jsx-runtime";
19
20
  function CollaboratorsList({
20
21
  activeCollaborators,
21
22
  popoverAnchor,
22
- setIsPopoverVisible
23
+ setIsPopoverVisible,
24
+ cursorRegistry
23
25
  }) {
26
+ const handleCollaboratorClick = (clientId) => {
27
+ const success = cursorRegistry.scrollToCursor(clientId, {
28
+ behavior: "smooth",
29
+ block: "center",
30
+ highlightDuration: 2e3
31
+ });
32
+ if (success) {
33
+ speak(__("Scrolled to cursor"), "polite");
34
+ setIsPopoverVisible(false);
35
+ }
36
+ };
24
37
  return /* @__PURE__ */ jsx(
25
38
  Popover,
26
39
  {
@@ -52,7 +65,10 @@ function CollaboratorsList({
52
65
  "button",
53
66
  {
54
67
  className: "editor-collaborators-presence__list-item",
55
- disabled: true,
68
+ disabled: isCurrentUser,
69
+ onClick: () => handleCollaboratorClick(
70
+ collaboratorState.clientId
71
+ ),
56
72
  children: [
57
73
  /* @__PURE__ */ jsx(
58
74
  Avatar,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/collaborators-presence/list.tsx", "../../../src/components/collaborators-presence/styles/collaborators-list.scss"],
4
- "sourcesContent": ["import { __ } from '@wordpress/i18n';\nimport { Popover, Button } from '@wordpress/components';\nimport { closeSmall } from '@wordpress/icons';\nimport { type PostEditorAwarenessState } from '@wordpress/core-data';\n\nimport Avatar from './avatar';\nimport { getAvatarUrl } from '../collaborators-overlay/get-avatar-url';\nimport { getAvatarBorderColor } from '../collab-sidebar/utils';\n\nimport './styles/collaborators-list.scss';\n\ninterface CollaboratorsListProps {\n\tactiveCollaborators: PostEditorAwarenessState[];\n\tpopoverAnchor?: HTMLElement | null;\n\tsetIsPopoverVisible: ( isVisible: boolean ) => void;\n}\n\n/**\n * Renders a list showing all active collaborators with their details.\n * When the showCollaborationCursor preference is enabled, the current user\n * is included and expected to be first in the list.\n * @param props Component props\n * @param props.activeCollaborators List of active collaborators\n * @param props.popoverAnchor Anchor element for the popover\n * @param props.setIsPopoverVisible Callback to set the visibility of the popover\n */\nexport function CollaboratorsList( {\n\tactiveCollaborators,\n\tpopoverAnchor,\n\tsetIsPopoverVisible,\n}: CollaboratorsListProps ) {\n\treturn (\n\t\t<Popover\n\t\t\tanchor={ popoverAnchor }\n\t\t\tplacement=\"bottom\"\n\t\t\toffset={ 8 }\n\t\t\tclassName=\"editor-collaborators-presence__list\"\n\t\t\tonClose={ () => setIsPopoverVisible( false ) }\n\t\t>\n\t\t\t<div className=\"editor-collaborators-presence__list-content\">\n\t\t\t\t<div className=\"editor-collaborators-presence__list-header\">\n\t\t\t\t\t<div className=\"editor-collaborators-presence__list-header-title\">\n\t\t\t\t\t\t{ __( 'Collaborators' ) }\n\t\t\t\t\t\t<span>{ activeCollaborators.length }</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"editor-collaborators-presence__list-header-action\">\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t\ticon={ closeSmall }\n\t\t\t\t\t\t\ticonSize={ 24 }\n\t\t\t\t\t\t\tlabel={ __( 'Close Collaborators List' ) }\n\t\t\t\t\t\t\tonClick={ () => setIsPopoverVisible( false ) }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"editor-collaborators-presence__list-items\">\n\t\t\t\t\t{ activeCollaborators.map( ( collaboratorState ) => {\n\t\t\t\t\t\tconst isCurrentUser = collaboratorState.isMe;\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\tkey={ collaboratorState.clientId }\n\t\t\t\t\t\t\t\tclassName=\"editor-collaborators-presence__list-item\"\n\t\t\t\t\t\t\t\tdisabled\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Avatar\n\t\t\t\t\t\t\t\t\tsrc={ getAvatarUrl(\n\t\t\t\t\t\t\t\t\t\tcollaboratorState.collaboratorInfo\n\t\t\t\t\t\t\t\t\t\t\t.avatar_urls\n\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\tname={\n\t\t\t\t\t\t\t\t\t\tcollaboratorState.collaboratorInfo.name\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tborderColor={\n\t\t\t\t\t\t\t\t\t\tisCurrentUser\n\t\t\t\t\t\t\t\t\t\t\t? 'var(--wp-admin-theme-color)'\n\t\t\t\t\t\t\t\t\t\t\t: getAvatarBorderColor(\n\t\t\t\t\t\t\t\t\t\t\t\t\tcollaboratorState\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.collaboratorInfo.id\n\t\t\t\t\t\t\t\t\t\t\t )\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tdimmed={ ! collaboratorState.isConnected }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<div className=\"editor-collaborators-presence__list-item-info\">\n\t\t\t\t\t\t\t\t\t<div className=\"editor-collaborators-presence__list-item-name\">\n\t\t\t\t\t\t\t\t\t\t{ isCurrentUser\n\t\t\t\t\t\t\t\t\t\t\t? __( 'You' )\n\t\t\t\t\t\t\t\t\t\t\t: collaboratorState.collaboratorInfo\n\t\t\t\t\t\t\t\t\t\t\t\t\t.name }\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t);\n\t\t\t\t\t} ) }\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</Popover>\n\t);\n}\n", "if (typeof document !== 'undefined' && process.env.NODE_ENV !== 'test' && !document.head.querySelector(\"style[data-wp-hash='9537a5e604']\")) {\n\tconst style = document.createElement(\"style\");\n\tstyle.setAttribute(\"data-wp-hash\", \"9537a5e604\");\n\tstyle.appendChild(document.createTextNode(\".editor-collaborators-presence__list.components-popover .components-popover__content{background:#fff;border:1px solid #ddd;border-radius:8px;border-width:1px 0 0 1px;box-shadow:0 1px 2px #0000000d,0 2px 3px #0000000a,0 6px 6px #00000008,0 8px 8px #00000005}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-content{min-width:280px}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-header{align-items:center;display:flex;justify-content:space-between;padding:8px 16px}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-header-title{display:flex;font-size:13px;font-weight:499;gap:4px;line-height:20px}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-header-title span{color:#757575}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-header-action{padding:0}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-header-action button{color:#1e1e1e;height:32px;padding:0;width:32px}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-items{display:flex;flex-direction:column;padding-bottom:16px}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item{all:unset;align-items:center;box-sizing:border-box;cursor:pointer;display:flex;gap:8px;padding:12px 16px;transition:background-color .2s ease;width:100%}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item:hover:not(:disabled){background-color:rgba(var(--wp-admin-theme-color--rgb),.04)}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item:active:not(:disabled){background-color:rgba(var(--wp-admin-theme-color--rgb),.08)}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item:focus-visible{outline:2px solid var(--wp-admin-theme-color,#3858e9);outline-offset:-2px}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item:disabled{cursor:default}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item-info{display:flex;flex:1;flex-direction:column;min-width:0}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item-name{color:#1e1e1e;font-size:13px;font-weight:499;line-height:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\"));\n\tdocument.head.appendChild(style);\n}\n"],
5
- "mappings": ";AAAA,SAAS,UAAU;AACnB,SAAS,SAAS,cAAc;AAChC,SAAS,kBAAkB;AAG3B,OAAO,YAAY;AACnB,SAAS,oBAAoB;AAC7B,SAAS,4BAA4B;;;ACPrC,IAAI,OAAO,aAAa,eAAe,QAAQ,IAAI,aAAa,UAAU,CAAC,SAAS,KAAK,cAAc,kCAAkC,GAAG;AAC3I,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAM,aAAa,gBAAgB,YAAY;AAC/C,QAAM,YAAY,SAAS,eAAe,yhFAAyhF,CAAC;AACpkF,WAAS,KAAK,YAAY,KAAK;AAChC;;;ADoCK,SAEC,KAFD;AAfE,SAAS,kBAAmB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACD,GAA4B;AAC3B,SACC;AAAA,IAAC;AAAA;AAAA,MACA,QAAS;AAAA,MACT,WAAU;AAAA,MACV,QAAS;AAAA,MACT,WAAU;AAAA,MACV,SAAU,MAAM,oBAAqB,KAAM;AAAA,MAE3C,+BAAC,SAAI,WAAU,+CACd;AAAA,6BAAC,SAAI,WAAU,8CACd;AAAA,+BAAC,SAAI,WAAU,oDACZ;AAAA,eAAI,eAAgB;AAAA,YACtB,oBAAC,UAAO,8BAAoB,QAAQ;AAAA,aACrC;AAAA,UACA,oBAAC,SAAI,WAAU,qDACd;AAAA,YAAC;AAAA;AAAA,cACA,uBAAqB;AAAA,cACrB,MAAO;AAAA,cACP,UAAW;AAAA,cACX,OAAQ,GAAI,0BAA2B;AAAA,cACvC,SAAU,MAAM,oBAAqB,KAAM;AAAA;AAAA,UAC5C,GACD;AAAA,WACD;AAAA,QACA,oBAAC,SAAI,WAAU,6CACZ,8BAAoB,IAAK,CAAE,sBAAuB;AACnD,gBAAM,gBAAgB,kBAAkB;AACxC,iBACC;AAAA,YAAC;AAAA;AAAA,cAEA,WAAU;AAAA,cACV,UAAQ;AAAA,cAER;AAAA;AAAA,kBAAC;AAAA;AAAA,oBACA,KAAM;AAAA,sBACL,kBAAkB,iBAChB;AAAA,oBACH;AAAA,oBACA,MACC,kBAAkB,iBAAiB;AAAA,oBAEpC,aACC,gBACG,gCACA;AAAA,sBACA,kBACE,iBAAiB;AAAA,oBACnB;AAAA,oBAEJ,QAAS,CAAE,kBAAkB;AAAA;AAAA,gBAC9B;AAAA,gBACA,oBAAC,SAAI,WAAU,iDACd,8BAAC,SAAI,WAAU,iDACZ,0BACC,GAAI,KAAM,IACV,kBAAkB,iBACjB,MACL,GACD;AAAA;AAAA;AAAA,YA7BM,kBAAkB;AAAA,UA8BzB;AAAA,QAEF,CAAE,GACH;AAAA,SACD;AAAA;AAAA,EACD;AAEF;",
4
+ "sourcesContent": ["import { __ } from '@wordpress/i18n';\nimport { Popover, Button } from '@wordpress/components';\nimport { closeSmall } from '@wordpress/icons';\nimport { type PostEditorAwarenessState } from '@wordpress/core-data';\nimport { speak } from '@wordpress/a11y';\n\nimport Avatar from './avatar';\nimport { getAvatarUrl } from '../collaborators-overlay/get-avatar-url';\nimport { getAvatarBorderColor } from '../collab-sidebar/utils';\nimport { type CursorRegistry } from '../collaborators-overlay/cursor-registry';\n\nimport './styles/collaborators-list.scss';\n\ninterface CollaboratorsListProps {\n\tactiveCollaborators: PostEditorAwarenessState[];\n\tpopoverAnchor?: HTMLElement | null;\n\tsetIsPopoverVisible: ( isVisible: boolean ) => void;\n\tcursorRegistry: CursorRegistry;\n}\n\n/**\n * Renders a list showing all active collaborators with their details.\n * When the showCollaborationCursor preference is enabled, the current user\n * is included and expected to be first in the list.\n * @param props Component props\n * @param props.activeCollaborators List of active collaborators\n * @param props.popoverAnchor Anchor element for the popover\n * @param props.setIsPopoverVisible Callback to set the visibility of the popover\n * @param props.cursorRegistry Shared registry for scroll-to-cursor support\n */\nexport function CollaboratorsList( {\n\tactiveCollaborators,\n\tpopoverAnchor,\n\tsetIsPopoverVisible,\n\tcursorRegistry,\n}: CollaboratorsListProps ) {\n\tconst handleCollaboratorClick = ( clientId: number ) => {\n\t\tconst success = cursorRegistry.scrollToCursor( clientId, {\n\t\t\tbehavior: 'smooth',\n\t\t\tblock: 'center',\n\t\t\thighlightDuration: 2000,\n\t\t} );\n\n\t\tif ( success ) {\n\t\t\tspeak( __( 'Scrolled to cursor' ), 'polite' );\n\n\t\t\tsetIsPopoverVisible( false );\n\t\t}\n\t};\n\n\treturn (\n\t\t<Popover\n\t\t\tanchor={ popoverAnchor }\n\t\t\tplacement=\"bottom\"\n\t\t\toffset={ 8 }\n\t\t\tclassName=\"editor-collaborators-presence__list\"\n\t\t\tonClose={ () => setIsPopoverVisible( false ) }\n\t\t>\n\t\t\t<div className=\"editor-collaborators-presence__list-content\">\n\t\t\t\t<div className=\"editor-collaborators-presence__list-header\">\n\t\t\t\t\t<div className=\"editor-collaborators-presence__list-header-title\">\n\t\t\t\t\t\t{ __( 'Collaborators' ) }\n\t\t\t\t\t\t<span>{ activeCollaborators.length }</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"editor-collaborators-presence__list-header-action\">\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t\ticon={ closeSmall }\n\t\t\t\t\t\t\ticonSize={ 24 }\n\t\t\t\t\t\t\tlabel={ __( 'Close Collaborators List' ) }\n\t\t\t\t\t\t\tonClick={ () => setIsPopoverVisible( false ) }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"editor-collaborators-presence__list-items\">\n\t\t\t\t\t{ activeCollaborators.map( ( collaboratorState ) => {\n\t\t\t\t\t\tconst isCurrentUser = collaboratorState.isMe;\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\tkey={ collaboratorState.clientId }\n\t\t\t\t\t\t\t\tclassName=\"editor-collaborators-presence__list-item\"\n\t\t\t\t\t\t\t\tdisabled={ isCurrentUser }\n\t\t\t\t\t\t\t\tonClick={ () =>\n\t\t\t\t\t\t\t\t\thandleCollaboratorClick(\n\t\t\t\t\t\t\t\t\t\tcollaboratorState.clientId\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Avatar\n\t\t\t\t\t\t\t\t\tsrc={ getAvatarUrl(\n\t\t\t\t\t\t\t\t\t\tcollaboratorState.collaboratorInfo\n\t\t\t\t\t\t\t\t\t\t\t.avatar_urls\n\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\tname={\n\t\t\t\t\t\t\t\t\t\tcollaboratorState.collaboratorInfo.name\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tborderColor={\n\t\t\t\t\t\t\t\t\t\tisCurrentUser\n\t\t\t\t\t\t\t\t\t\t\t? 'var(--wp-admin-theme-color)'\n\t\t\t\t\t\t\t\t\t\t\t: getAvatarBorderColor(\n\t\t\t\t\t\t\t\t\t\t\t\t\tcollaboratorState\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.collaboratorInfo.id\n\t\t\t\t\t\t\t\t\t\t\t )\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tdimmed={ ! collaboratorState.isConnected }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<div className=\"editor-collaborators-presence__list-item-info\">\n\t\t\t\t\t\t\t\t\t<div className=\"editor-collaborators-presence__list-item-name\">\n\t\t\t\t\t\t\t\t\t\t{ isCurrentUser\n\t\t\t\t\t\t\t\t\t\t\t? __( 'You' )\n\t\t\t\t\t\t\t\t\t\t\t: collaboratorState.collaboratorInfo\n\t\t\t\t\t\t\t\t\t\t\t\t\t.name }\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t);\n\t\t\t\t\t} ) }\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</Popover>\n\t);\n}\n", "if (typeof document !== 'undefined' && process.env.NODE_ENV !== 'test' && !document.head.querySelector(\"style[data-wp-hash='0f8400f482']\")) {\n\tconst style = document.createElement(\"style\");\n\tstyle.setAttribute(\"data-wp-hash\", \"0f8400f482\");\n\tstyle.appendChild(document.createTextNode(\".editor-collaborators-presence__list.components-popover .components-popover__content{background:#fff;border:1px solid #ddd;border-radius:8px;border-width:1px 0 0 1px;box-shadow:0 1px 2px #0000000d,0 2px 3px #0000000a,0 6px 6px #00000008,0 8px 8px #00000005}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-content{min-width:280px}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-header{align-items:center;display:flex;justify-content:space-between;padding:8px 16px}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-header-title{display:flex;font-size:13px;font-weight:499;gap:4px;line-height:20px}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-header-title span{color:#757575}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-header-action{padding:0}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-header-action button{color:#1e1e1e;height:32px;padding:0;width:32px}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-items{display:flex;flex-direction:column;padding-bottom:16px}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item{all:unset;align-items:center;box-sizing:border-box;cursor:pointer;display:flex;gap:8px;padding:12px 16px;transition:background-color .2s ease;width:100%}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item:hover:not(:disabled){background-color:rgba(var(--wp-admin-theme-color--rgb),.04)}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item:active:not(:disabled){background-color:rgba(var(--wp-admin-theme-color--rgb),.08)}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item:focus-visible{outline:2px solid var(--wp-admin-theme-color,#3858e9);outline-offset:-2px}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item:disabled{cursor:default}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item-info{display:flex;flex:1;flex-direction:column;min-width:0}.editor-collaborators-presence__list.components-popover .editor-collaborators-presence__list-item-name{color:#1e1e1e;font-size:13px;font-weight:499;line-height:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\"));\n\tdocument.head.appendChild(style);\n}\n"],
5
+ "mappings": ";AAAA,SAAS,UAAU;AACnB,SAAS,SAAS,cAAc;AAChC,SAAS,kBAAkB;AAE3B,SAAS,aAAa;AAEtB,OAAO,YAAY;AACnB,SAAS,oBAAoB;AAC7B,SAAS,4BAA4B;;;ACRrC,IAAI,OAAO,aAAa,eAAe,QAAQ,IAAI,aAAa,UAAU,CAAC,SAAS,KAAK,cAAc,kCAAkC,GAAG;AAC3I,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAM,aAAa,gBAAgB,YAAY;AAC/C,QAAM,YAAY,SAAS,eAAe,yhFAAyhF,CAAC;AACpkF,WAAS,KAAK,YAAY,KAAK;AAChC;;;ADuDK,SAEC,KAFD;AA9BE,SAAS,kBAAmB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAA4B;AAC3B,QAAM,0BAA0B,CAAE,aAAsB;AACvD,UAAM,UAAU,eAAe,eAAgB,UAAU;AAAA,MACxD,UAAU;AAAA,MACV,OAAO;AAAA,MACP,mBAAmB;AAAA,IACpB,CAAE;AAEF,QAAK,SAAU;AACd,YAAO,GAAI,oBAAqB,GAAG,QAAS;AAE5C,0BAAqB,KAAM;AAAA,IAC5B;AAAA,EACD;AAEA,SACC;AAAA,IAAC;AAAA;AAAA,MACA,QAAS;AAAA,MACT,WAAU;AAAA,MACV,QAAS;AAAA,MACT,WAAU;AAAA,MACV,SAAU,MAAM,oBAAqB,KAAM;AAAA,MAE3C,+BAAC,SAAI,WAAU,+CACd;AAAA,6BAAC,SAAI,WAAU,8CACd;AAAA,+BAAC,SAAI,WAAU,oDACZ;AAAA,eAAI,eAAgB;AAAA,YACtB,oBAAC,UAAO,8BAAoB,QAAQ;AAAA,aACrC;AAAA,UACA,oBAAC,SAAI,WAAU,qDACd;AAAA,YAAC;AAAA;AAAA,cACA,uBAAqB;AAAA,cACrB,MAAO;AAAA,cACP,UAAW;AAAA,cACX,OAAQ,GAAI,0BAA2B;AAAA,cACvC,SAAU,MAAM,oBAAqB,KAAM;AAAA;AAAA,UAC5C,GACD;AAAA,WACD;AAAA,QACA,oBAAC,SAAI,WAAU,6CACZ,8BAAoB,IAAK,CAAE,sBAAuB;AACnD,gBAAM,gBAAgB,kBAAkB;AACxC,iBACC;AAAA,YAAC;AAAA;AAAA,cAEA,WAAU;AAAA,cACV,UAAW;AAAA,cACX,SAAU,MACT;AAAA,gBACC,kBAAkB;AAAA,cACnB;AAAA,cAGD;AAAA;AAAA,kBAAC;AAAA;AAAA,oBACA,KAAM;AAAA,sBACL,kBAAkB,iBAChB;AAAA,oBACH;AAAA,oBACA,MACC,kBAAkB,iBAAiB;AAAA,oBAEpC,aACC,gBACG,gCACA;AAAA,sBACA,kBACE,iBAAiB;AAAA,oBACnB;AAAA,oBAEJ,QAAS,CAAE,kBAAkB;AAAA;AAAA,gBAC9B;AAAA,gBACA,oBAAC,SAAI,WAAU,iDACd,8BAAC,SAAI,WAAU,iDACZ,0BACC,GAAI,KAAM,IACV,kBAAkB,iBACjB,MACL,GACD;AAAA;AAAA;AAAA,YAlCM,kBAAkB;AAAA,UAmCzB;AAAA,QAEF,CAAE,GACH;AAAA,SACD;AAAA;AAAA,EACD;AAEF;",
6
6
  "names": []
7
7
  }
@@ -7,7 +7,7 @@ import {
7
7
  __experimentalText as Text,
8
8
  privateApis as componentsPrivateApis
9
9
  } from "@wordpress/components";
10
- import { moreVertical, close } from "@wordpress/icons";
10
+ import { close } from "@wordpress/icons";
11
11
  import { store as coreStore } from "@wordpress/core-data";
12
12
  import { useSelect } from "@wordpress/data";
13
13
  import { useMemo } from "@wordpress/element";
@@ -22,7 +22,7 @@ import { unlock } from "../../lock-unlock.mjs";
22
22
  import PostActions from "../post-actions/index.mjs";
23
23
  import usePageTypeBadge from "../../utils/pageTypeBadge.mjs";
24
24
  import { getTemplateInfo } from "../../utils/get-template-info.mjs";
25
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
25
+ import { jsx, jsxs } from "react/jsx-runtime";
26
26
  var { Badge } = unlock(componentsPrivateApis);
27
27
  function PostCardPanel({
28
28
  postType,
@@ -35,7 +35,7 @@ function PostCardPanel({
35
35
  () => Array.isArray(postId) ? postId : [postId],
36
36
  [postId]
37
37
  );
38
- const { postTitle, icon, labels, isRevision } = useSelect(
38
+ const { postTitle, icon, labels } = useSelect(
39
39
  (select) => {
40
40
  const { getEditedEntityRecord, getCurrentTheme, getPostType } = select(coreStore);
41
41
  const {
@@ -54,8 +54,7 @@ function PostCardPanel({
54
54
  icon: getPostIcon(parentPostType, {
55
55
  area: _record2?.area
56
56
  }),
57
- labels: getPostType(parentPostType)?.labels,
58
- isRevision: true
57
+ labels: getPostType(parentPostType)?.labels
59
58
  };
60
59
  }
61
60
  const _record = getEditedEntityRecord(
@@ -118,24 +117,14 @@ function PostCardPanel({
118
117
  ]
119
118
  }
120
119
  ),
121
- !hideActions && postIds.length === 1 && /* @__PURE__ */ jsx(Fragment, { children: isRevision ? /* @__PURE__ */ jsx(
122
- Button,
123
- {
124
- size: "small",
125
- icon: moreVertical,
126
- label: __("Actions"),
127
- disabled: true,
128
- accessibleWhenDisabled: true,
129
- className: "editor-all-actions-button"
130
- }
131
- ) : /* @__PURE__ */ jsx(
120
+ !hideActions && postIds.length === 1 && /* @__PURE__ */ jsx(
132
121
  PostActions,
133
122
  {
134
123
  postType,
135
124
  postId: postIds[0],
136
125
  onActionPerformed
137
126
  }
138
- ) }),
127
+ ),
139
128
  onClose && /* @__PURE__ */ jsx(
140
129
  Button,
141
130
  {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/post-card-panel/index.js"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport {\n\tIcon,\n\tButton,\n\t__experimentalHStack as HStack,\n\t__experimentalVStack as VStack,\n\t__experimentalText as Text,\n\tprivateApis as componentsPrivateApis,\n} from '@wordpress/components';\nimport { moreVertical, close } from '@wordpress/icons';\nimport { store as coreStore } from '@wordpress/core-data';\nimport { useSelect } from '@wordpress/data';\nimport { useMemo } from '@wordpress/element';\nimport { __, sprintf } from '@wordpress/i18n';\nimport { __unstableStripHTML as stripHTML } from '@wordpress/dom';\n\n/**\n * Internal dependencies\n */\nimport { store as editorStore } from '../../store';\nimport {\n\tTEMPLATE_POST_TYPE,\n\tTEMPLATE_PART_POST_TYPE,\n} from '../../store/constants';\nimport { unlock } from '../../lock-unlock';\nimport PostActions from '../post-actions';\nimport usePageTypeBadge from '../../utils/pageTypeBadge';\nimport { getTemplateInfo } from '../../utils/get-template-info';\nconst { Badge } = unlock( componentsPrivateApis );\n\n/**\n * Renders a title of the post type and the available quick actions available within a 3-dot dropdown.\n *\n * @param {Object} props - Component props.\n * @param {string} [props.postType] - The post type string.\n * @param {string|string[]} [props.postId] - The post id or list of post ids.\n * @param {boolean} [props.hideActions] - Whether to hide the actions. False by default.\n * @param {Function} [props.onActionPerformed] - A callback function for when a quick action is performed.\n * @param {Function} [props.onClose] - A callback function for when the close button is clicked.\n * @return {React.ReactNode} The rendered component.\n */\nexport default function PostCardPanel( {\n\tpostType,\n\tpostId,\n\thideActions = false,\n\tonActionPerformed,\n\tonClose,\n} ) {\n\tconst postIds = useMemo(\n\t\t() => ( Array.isArray( postId ) ? postId : [ postId ] ),\n\t\t[ postId ]\n\t);\n\tconst { postTitle, icon, labels, isRevision } = useSelect(\n\t\t( select ) => {\n\t\t\tconst { getEditedEntityRecord, getCurrentTheme, getPostType } =\n\t\t\t\tselect( coreStore );\n\t\t\tconst {\n\t\t\t\tgetPostIcon,\n\t\t\t\tgetCurrentPostType,\n\t\t\t\tisRevisionsMode,\n\t\t\t\tgetCurrentRevision,\n\t\t\t} = unlock( select( editorStore ) );\n\t\t\tlet _title = '';\n\n\t\t\t// In revisions mode, use the current revision.\n\t\t\tif ( isRevisionsMode() ) {\n\t\t\t\tconst parentPostType = getCurrentPostType();\n\t\t\t\tconst _record = getCurrentRevision();\n\t\t\t\t_title = _record?.title?.rendered || _record?.title?.raw || '';\n\t\t\t\treturn {\n\t\t\t\t\tpostTitle: _title,\n\t\t\t\t\ticon: getPostIcon( parentPostType, {\n\t\t\t\t\t\tarea: _record?.area,\n\t\t\t\t\t} ),\n\t\t\t\t\tlabels: getPostType( parentPostType )?.labels,\n\t\t\t\t\tisRevision: true,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst _record = getEditedEntityRecord(\n\t\t\t\t'postType',\n\t\t\t\tpostType,\n\t\t\t\tpostIds[ 0 ]\n\t\t\t);\n\t\t\tif ( postIds.length === 1 ) {\n\t\t\t\tconst { default_template_types: templateTypes = [] } =\n\t\t\t\t\tgetCurrentTheme() ?? {};\n\n\t\t\t\tconst _templateInfo = [\n\t\t\t\t\tTEMPLATE_POST_TYPE,\n\t\t\t\t\tTEMPLATE_PART_POST_TYPE,\n\t\t\t\t].includes( postType )\n\t\t\t\t\t? getTemplateInfo( {\n\t\t\t\t\t\t\ttemplate: _record,\n\t\t\t\t\t\t\ttemplateTypes,\n\t\t\t\t\t } )\n\t\t\t\t\t: {};\n\t\t\t\t_title = _templateInfo?.title || _record?.title;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tpostTitle: _title,\n\t\t\t\ticon: getPostIcon( postType, {\n\t\t\t\t\tarea: _record?.area,\n\t\t\t\t} ),\n\t\t\t\tlabels: getPostType( postType )?.labels,\n\t\t\t};\n\t\t},\n\t\t[ postIds, postType ]\n\t);\n\n\tconst pageTypeBadge = usePageTypeBadge( postId );\n\tlet title = __( 'No title' );\n\tif ( labels?.name && postIds.length > 1 ) {\n\t\ttitle = sprintf(\n\t\t\t// translators: %1$d number of selected items %2$s: Name of the plural post type e.g: \"Posts\".\n\t\t\t__( '%1$d %2$s' ),\n\t\t\tpostIds.length,\n\t\t\tlabels?.name\n\t\t);\n\t} else if ( postTitle ) {\n\t\ttitle = stripHTML( postTitle );\n\t}\n\n\treturn (\n\t\t<VStack spacing={ 1 } className=\"editor-post-card-panel\">\n\t\t\t<HStack\n\t\t\t\tspacing={ 2 }\n\t\t\t\tclassName=\"editor-post-card-panel__header\"\n\t\t\t\talignment=\"flex-start\"\n\t\t\t>\n\t\t\t\t<Icon className=\"editor-post-card-panel__icon\" icon={ icon } />\n\t\t\t\t<Text\n\t\t\t\t\tnumberOfLines={ 2 }\n\t\t\t\t\ttruncate\n\t\t\t\t\tclassName=\"editor-post-card-panel__title\"\n\t\t\t\t\tas=\"h2\"\n\t\t\t\t>\n\t\t\t\t\t<span className=\"editor-post-card-panel__title-name\">\n\t\t\t\t\t\t{ title }\n\t\t\t\t\t</span>\n\t\t\t\t\t{ pageTypeBadge && postIds.length === 1 && (\n\t\t\t\t\t\t<Badge>{ pageTypeBadge }</Badge>\n\t\t\t\t\t) }\n\t\t\t\t</Text>\n\t\t\t\t{ ! hideActions && postIds.length === 1 && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{ isRevision ? (\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\t\ticon={ moreVertical }\n\t\t\t\t\t\t\t\tlabel={ __( 'Actions' ) }\n\t\t\t\t\t\t\t\tdisabled\n\t\t\t\t\t\t\t\taccessibleWhenDisabled\n\t\t\t\t\t\t\t\tclassName=\"editor-all-actions-button\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<PostActions\n\t\t\t\t\t\t\t\tpostType={ postType }\n\t\t\t\t\t\t\t\tpostId={ postIds[ 0 ] }\n\t\t\t\t\t\t\t\tonActionPerformed={ onActionPerformed }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) }\n\t\t\t\t\t</>\n\t\t\t\t) }\n\t\t\t\t{ onClose && (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\ticon={ close }\n\t\t\t\t\t\tlabel={ __( 'Close' ) }\n\t\t\t\t\t\tonClick={ onClose }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t</HStack>\n\t\t\t{ postIds.length > 1 && (\n\t\t\t\t<Text className=\"editor-post-card-panel__description\">\n\t\t\t\t\t{ sprintf(\n\t\t\t\t\t\t// translators: %s: Name of the plural post type e.g: \"Posts\".\n\t\t\t\t\t\t__( 'Changes will be applied to all selected %s.' ),\n\t\t\t\t\t\tlabels?.name.toLowerCase()\n\t\t\t\t\t) }\n\t\t\t\t</Text>\n\t\t\t) }\n\t\t</VStack>\n\t);\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport {\n\tIcon,\n\tButton,\n\t__experimentalHStack as HStack,\n\t__experimentalVStack as VStack,\n\t__experimentalText as Text,\n\tprivateApis as componentsPrivateApis,\n} from '@wordpress/components';\nimport { close } from '@wordpress/icons';\nimport { store as coreStore } from '@wordpress/core-data';\nimport { useSelect } from '@wordpress/data';\nimport { useMemo } from '@wordpress/element';\nimport { __, sprintf } from '@wordpress/i18n';\nimport { __unstableStripHTML as stripHTML } from '@wordpress/dom';\n\n/**\n * Internal dependencies\n */\nimport { store as editorStore } from '../../store';\nimport {\n\tTEMPLATE_POST_TYPE,\n\tTEMPLATE_PART_POST_TYPE,\n} from '../../store/constants';\nimport { unlock } from '../../lock-unlock';\nimport PostActions from '../post-actions';\nimport usePageTypeBadge from '../../utils/pageTypeBadge';\nimport { getTemplateInfo } from '../../utils/get-template-info';\nconst { Badge } = unlock( componentsPrivateApis );\n\n/**\n * Renders a title of the post type and the available quick actions available within a 3-dot dropdown.\n *\n * @param {Object} props - Component props.\n * @param {string} [props.postType] - The post type string.\n * @param {string|string[]} [props.postId] - The post id or list of post ids.\n * @param {boolean} [props.hideActions] - Whether to hide the actions. False by default.\n * @param {Function} [props.onActionPerformed] - A callback function for when a quick action is performed.\n * @param {Function} [props.onClose] - A callback function for when the close button is clicked.\n * @return {React.ReactNode} The rendered component.\n */\nexport default function PostCardPanel( {\n\tpostType,\n\tpostId,\n\thideActions = false,\n\tonActionPerformed,\n\tonClose,\n} ) {\n\tconst postIds = useMemo(\n\t\t() => ( Array.isArray( postId ) ? postId : [ postId ] ),\n\t\t[ postId ]\n\t);\n\tconst { postTitle, icon, labels } = useSelect(\n\t\t( select ) => {\n\t\t\tconst { getEditedEntityRecord, getCurrentTheme, getPostType } =\n\t\t\t\tselect( coreStore );\n\t\t\tconst {\n\t\t\t\tgetPostIcon,\n\t\t\t\tgetCurrentPostType,\n\t\t\t\tisRevisionsMode,\n\t\t\t\tgetCurrentRevision,\n\t\t\t} = unlock( select( editorStore ) );\n\t\t\tlet _title = '';\n\n\t\t\t// In revisions mode, use the current revision.\n\t\t\tif ( isRevisionsMode() ) {\n\t\t\t\tconst parentPostType = getCurrentPostType();\n\t\t\t\tconst _record = getCurrentRevision();\n\t\t\t\t_title = _record?.title?.rendered || _record?.title?.raw || '';\n\t\t\t\treturn {\n\t\t\t\t\tpostTitle: _title,\n\t\t\t\t\ticon: getPostIcon( parentPostType, {\n\t\t\t\t\t\tarea: _record?.area,\n\t\t\t\t\t} ),\n\t\t\t\t\tlabels: getPostType( parentPostType )?.labels,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst _record = getEditedEntityRecord(\n\t\t\t\t'postType',\n\t\t\t\tpostType,\n\t\t\t\tpostIds[ 0 ]\n\t\t\t);\n\t\t\tif ( postIds.length === 1 ) {\n\t\t\t\tconst { default_template_types: templateTypes = [] } =\n\t\t\t\t\tgetCurrentTheme() ?? {};\n\n\t\t\t\tconst _templateInfo = [\n\t\t\t\t\tTEMPLATE_POST_TYPE,\n\t\t\t\t\tTEMPLATE_PART_POST_TYPE,\n\t\t\t\t].includes( postType )\n\t\t\t\t\t? getTemplateInfo( {\n\t\t\t\t\t\t\ttemplate: _record,\n\t\t\t\t\t\t\ttemplateTypes,\n\t\t\t\t\t } )\n\t\t\t\t\t: {};\n\t\t\t\t_title = _templateInfo?.title || _record?.title;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tpostTitle: _title,\n\t\t\t\ticon: getPostIcon( postType, {\n\t\t\t\t\tarea: _record?.area,\n\t\t\t\t} ),\n\t\t\t\tlabels: getPostType( postType )?.labels,\n\t\t\t};\n\t\t},\n\t\t[ postIds, postType ]\n\t);\n\n\tconst pageTypeBadge = usePageTypeBadge( postId );\n\tlet title = __( 'No title' );\n\tif ( labels?.name && postIds.length > 1 ) {\n\t\ttitle = sprintf(\n\t\t\t// translators: %1$d number of selected items %2$s: Name of the plural post type e.g: \"Posts\".\n\t\t\t__( '%1$d %2$s' ),\n\t\t\tpostIds.length,\n\t\t\tlabels?.name\n\t\t);\n\t} else if ( postTitle ) {\n\t\ttitle = stripHTML( postTitle );\n\t}\n\n\treturn (\n\t\t<VStack spacing={ 1 } className=\"editor-post-card-panel\">\n\t\t\t<HStack\n\t\t\t\tspacing={ 2 }\n\t\t\t\tclassName=\"editor-post-card-panel__header\"\n\t\t\t\talignment=\"flex-start\"\n\t\t\t>\n\t\t\t\t<Icon className=\"editor-post-card-panel__icon\" icon={ icon } />\n\t\t\t\t<Text\n\t\t\t\t\tnumberOfLines={ 2 }\n\t\t\t\t\ttruncate\n\t\t\t\t\tclassName=\"editor-post-card-panel__title\"\n\t\t\t\t\tas=\"h2\"\n\t\t\t\t>\n\t\t\t\t\t<span className=\"editor-post-card-panel__title-name\">\n\t\t\t\t\t\t{ title }\n\t\t\t\t\t</span>\n\t\t\t\t\t{ pageTypeBadge && postIds.length === 1 && (\n\t\t\t\t\t\t<Badge>{ pageTypeBadge }</Badge>\n\t\t\t\t\t) }\n\t\t\t\t</Text>\n\t\t\t\t{ ! hideActions && postIds.length === 1 && (\n\t\t\t\t\t<PostActions\n\t\t\t\t\t\tpostType={ postType }\n\t\t\t\t\t\tpostId={ postIds[ 0 ] }\n\t\t\t\t\t\tonActionPerformed={ onActionPerformed }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t\t{ onClose && (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\ticon={ close }\n\t\t\t\t\t\tlabel={ __( 'Close' ) }\n\t\t\t\t\t\tonClick={ onClose }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t</HStack>\n\t\t\t{ postIds.length > 1 && (\n\t\t\t\t<Text className=\"editor-post-card-panel__description\">\n\t\t\t\t\t{ sprintf(\n\t\t\t\t\t\t// translators: %s: Name of the plural post type e.g: \"Posts\".\n\t\t\t\t\t\t__( 'Changes will be applied to all selected %s.' ),\n\t\t\t\t\t\tlabels?.name.toLowerCase()\n\t\t\t\t\t) }\n\t\t\t\t</Text>\n\t\t\t) }\n\t\t</VStack>\n\t);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["_record"]
7
7
  }