@wordpress/editor 14.33.3-next.36001005c.0 → 14.33.3

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 (104) hide show
  1. package/build/bindings/post-data.js +10 -17
  2. package/build/bindings/post-data.js.map +2 -2
  3. package/build/bindings/post-meta.js +7 -14
  4. package/build/bindings/post-meta.js.map +2 -2
  5. package/build/bindings/term-data.js +6 -16
  6. package/build/bindings/term-data.js.map +2 -2
  7. package/build/components/block-settings-menu/content-only-settings-menu.js +186 -0
  8. package/build/components/block-settings-menu/content-only-settings-menu.js.map +7 -0
  9. package/build/components/collab-sidebar/add-comment.js +26 -3
  10. package/build/components/collab-sidebar/add-comment.js.map +3 -3
  11. package/build/components/collab-sidebar/comment-indicator-toolbar.js +6 -22
  12. package/build/components/collab-sidebar/comment-indicator-toolbar.js.map +3 -3
  13. package/build/components/collab-sidebar/comments.js +105 -28
  14. package/build/components/collab-sidebar/comments.js.map +3 -3
  15. package/build/components/collab-sidebar/hooks.js +3 -4
  16. package/build/components/collab-sidebar/hooks.js.map +2 -2
  17. package/build/components/collab-sidebar/index.js +42 -57
  18. package/build/components/collab-sidebar/index.js.map +3 -3
  19. package/build/components/editor/index.js +2 -0
  20. package/build/components/editor/index.js.map +3 -3
  21. package/build/components/header/index.js +0 -3
  22. package/build/components/header/index.js.map +3 -3
  23. package/build/components/post-template/hooks.js +7 -38
  24. package/build/components/post-template/hooks.js.map +2 -2
  25. package/build/components/provider/index.js +3 -1
  26. package/build/components/provider/index.js.map +3 -3
  27. package/build/store/actions.js +1 -1
  28. package/build/store/actions.js.map +2 -2
  29. package/build-module/bindings/post-data.js +10 -17
  30. package/build-module/bindings/post-data.js.map +2 -2
  31. package/build-module/bindings/post-meta.js +7 -14
  32. package/build-module/bindings/post-meta.js.map +2 -2
  33. package/build-module/bindings/term-data.js +6 -16
  34. package/build-module/bindings/term-data.js.map +2 -2
  35. package/build-module/components/block-settings-menu/content-only-settings-menu.js +161 -0
  36. package/build-module/components/block-settings-menu/content-only-settings-menu.js.map +7 -0
  37. package/build-module/components/collab-sidebar/add-comment.js +27 -4
  38. package/build-module/components/collab-sidebar/add-comment.js.map +2 -2
  39. package/build-module/components/collab-sidebar/comment-indicator-toolbar.js +6 -12
  40. package/build-module/components/collab-sidebar/comment-indicator-toolbar.js.map +2 -2
  41. package/build-module/components/collab-sidebar/comments.js +114 -31
  42. package/build-module/components/collab-sidebar/comments.js.map +2 -2
  43. package/build-module/components/collab-sidebar/hooks.js +3 -4
  44. package/build-module/components/collab-sidebar/hooks.js.map +2 -2
  45. package/build-module/components/collab-sidebar/index.js +42 -57
  46. package/build-module/components/collab-sidebar/index.js.map +2 -2
  47. package/build-module/components/editor/index.js +2 -0
  48. package/build-module/components/editor/index.js.map +2 -2
  49. package/build-module/components/header/index.js +0 -3
  50. package/build-module/components/header/index.js.map +2 -2
  51. package/build-module/components/post-template/hooks.js +7 -38
  52. package/build-module/components/post-template/hooks.js.map +2 -2
  53. package/build-module/components/provider/index.js +3 -1
  54. package/build-module/components/provider/index.js.map +2 -2
  55. package/build-module/store/actions.js +1 -1
  56. package/build-module/store/actions.js.map +2 -2
  57. package/build-style/style-rtl.css +12 -23
  58. package/build-style/style.css +12 -23
  59. package/build-types/bindings/post-data.d.ts +6 -16
  60. package/build-types/bindings/post-meta.d.ts +6 -13
  61. package/build-types/bindings/term-data.d.ts +6 -16
  62. package/build-types/components/block-settings-menu/content-only-settings-menu.d.ts +2 -0
  63. package/build-types/components/block-settings-menu/content-only-settings-menu.d.ts.map +1 -0
  64. package/build-types/components/collab-sidebar/add-comment.d.ts +6 -1
  65. package/build-types/components/collab-sidebar/add-comment.d.ts.map +1 -1
  66. package/build-types/components/collab-sidebar/comment-indicator-toolbar.d.ts +1 -2
  67. package/build-types/components/collab-sidebar/comment-indicator-toolbar.d.ts.map +1 -1
  68. package/build-types/components/collab-sidebar/comments.d.ts +12 -26
  69. package/build-types/components/collab-sidebar/comments.d.ts.map +1 -1
  70. package/build-types/components/collab-sidebar/hooks.d.ts +0 -1
  71. package/build-types/components/collab-sidebar/hooks.d.ts.map +1 -1
  72. package/build-types/components/collab-sidebar/index.d.ts +1 -4
  73. package/build-types/components/collab-sidebar/index.d.ts.map +1 -1
  74. package/build-types/components/editor/index.d.ts.map +1 -1
  75. package/build-types/components/header/index.d.ts.map +1 -1
  76. package/build-types/components/post-template/hooks.d.ts +1 -1
  77. package/build-types/components/post-template/hooks.d.ts.map +1 -1
  78. package/build-types/components/provider/index.d.ts.map +1 -1
  79. package/build-types/store/actions.d.ts.map +1 -1
  80. package/package.json +38 -38
  81. package/src/bindings/post-data.js +9 -20
  82. package/src/bindings/post-meta.js +6 -17
  83. package/src/bindings/term-data.js +6 -21
  84. package/src/components/block-settings-menu/content-only-settings-menu.js +185 -0
  85. package/src/components/block-settings-menu/content-only-settings-menu.native.js +4 -0
  86. package/src/components/block-settings-menu/style.scss +6 -0
  87. package/src/components/collab-sidebar/add-comment.js +31 -3
  88. package/src/components/collab-sidebar/comment-indicator-toolbar.js +6 -22
  89. package/src/components/collab-sidebar/comments.js +108 -35
  90. package/src/components/collab-sidebar/hooks.js +3 -4
  91. package/src/components/collab-sidebar/index.js +34 -42
  92. package/src/components/collab-sidebar/style.scss +2 -23
  93. package/src/components/editor/index.js +2 -0
  94. package/src/components/editor-help/style.scss +1 -1
  95. package/src/components/header/index.js +0 -7
  96. package/src/components/post-last-revision/style.scss +1 -1
  97. package/src/components/post-panel-row/style.scss +0 -1
  98. package/src/components/post-publish-panel/style.scss +1 -1
  99. package/src/components/post-publish-panel/test/__snapshots__/index.js.snap +2 -2
  100. package/src/components/post-template/hooks.js +10 -51
  101. package/src/components/provider/index.js +3 -4
  102. package/src/store/actions.js +4 -1
  103. package/src/style.scss +1 -0
  104. package/tsconfig.tsbuildinfo +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/bindings/term-data.js"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { __ } from '@wordpress/i18n';\nimport { store as coreDataStore } from '@wordpress/core-data';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\n\n// Navigation block types that use special handling for backwards compatibility\nconst NAVIGATION_BLOCK_TYPES = [\n\t'core/navigation-link',\n\t'core/navigation-submenu',\n];\n\n/**\n * Creates the data fields object with the given term data values and ID value.\n *\n * @param {Object} termDataValues The term data values.\n * @param {string|number} idValue The ID value to use.\n * @return {Object} The data fields object.\n */\nfunction createDataFields( termDataValues, idValue ) {\n\treturn {\n\t\tid: {\n\t\t\tlabel: __( 'Term ID' ),\n\t\t\tvalue: idValue,\n\t\t\ttype: 'string',\n\t\t},\n\t\tname: {\n\t\t\tlabel: __( 'Name' ),\n\t\t\tvalue: termDataValues?.name,\n\t\t\ttype: 'string',\n\t\t},\n\t\tslug: {\n\t\t\tlabel: __( 'Slug' ),\n\t\t\tvalue: termDataValues?.slug,\n\t\t\ttype: 'string',\n\t\t},\n\t\tlink: {\n\t\t\tlabel: __( 'Link' ),\n\t\t\tvalue: termDataValues?.link,\n\t\t\ttype: 'string',\n\t\t},\n\t\tdescription: {\n\t\t\tlabel: __( 'Description' ),\n\t\t\tvalue: termDataValues?.description,\n\t\t\ttype: 'string',\n\t\t},\n\t\tparent: {\n\t\t\tlabel: __( 'Parent ID' ),\n\t\t\tvalue: termDataValues?.parent,\n\t\t\ttype: 'string',\n\t\t},\n\t\tcount: {\n\t\t\tlabel: __( 'Count' ),\n\t\t\tvalue: `(${ termDataValues?.count ?? 0 })`,\n\t\t\ttype: 'string',\n\t\t},\n\t};\n}\n\n/**\n * Gets a list of term data fields with their values and labels\n * to be consumed in the needed callbacks.\n * If the value is not available based on context, like in templates,\n * it falls back to the default value, label, or key.\n *\n * @param {Object} select The select function from the data store.\n * @param {Object} context The context provided.\n * @param {string} clientId The block client ID used to read attributes.\n * @return {Object} List of term data fields with their value and label.\n *\n * @example\n * ```js\n * {\n * name: {\n * label: 'Term Name',\n * value: 'Category Name',\n * },\n * count: {\n * label: 'Term Count',\n * value: 5,\n * },\n * ...\n * }\n * ```\n */\nfunction getTermDataFields( select, context, clientId ) {\n\tconst { getEntityRecord } = select( coreDataStore );\n\tconst { getBlockAttributes, getBlockName } = select( blockEditorStore );\n\n\tlet termDataValues, dataFields;\n\n\t/*\n\t * BACKWARDS COMPATIBILITY: Hardcoded exception for navigation blocks.\n\t * Required for WordPress 6.9+ navigation blocks. DO NOT REMOVE.\n\t */\n\tconst blockName = getBlockName?.( clientId );\n\tconst isNavigationBlock = NAVIGATION_BLOCK_TYPES.includes( blockName );\n\n\tlet termId, taxonomy;\n\n\tif ( isNavigationBlock ) {\n\t\t// Navigation blocks: read from block attributes\n\t\tconst blockAttributes = getBlockAttributes?.( clientId );\n\t\ttermId = blockAttributes?.id;\n\t\tconst typeFromAttributes = blockAttributes?.type;\n\t\ttaxonomy =\n\t\t\ttypeFromAttributes === 'tag' ? 'post_tag' : typeFromAttributes;\n\t} else {\n\t\t// All other blocks: use context\n\t\ttermId = context?.termId;\n\t\ttaxonomy = context?.taxonomy;\n\t}\n\n\tif ( taxonomy && termId ) {\n\t\ttermDataValues = getEntityRecord( 'taxonomy', taxonomy, termId );\n\n\t\tif ( ! termDataValues && context?.termData ) {\n\t\t\ttermDataValues = context.termData;\n\t\t}\n\n\t\tif ( termDataValues ) {\n\t\t\tdataFields = createDataFields( termDataValues, termId );\n\t\t}\n\t} else if ( context?.termData ) {\n\t\ttermDataValues = context.termData;\n\t\tdataFields = createDataFields(\n\t\t\ttermDataValues,\n\t\t\ttermDataValues?.term_id\n\t\t);\n\t}\n\n\tif ( ! dataFields || ! Object.keys( dataFields ).length ) {\n\t\treturn null;\n\t}\n\n\treturn dataFields;\n}\n\n/**\n * @type {WPBlockBindingsSource}\n */\nexport default {\n\tname: 'core/term-data',\n\tusesContext: [ 'taxonomy', 'termId', 'termData' ],\n\tgetValues( { select, context, bindings, clientId } ) {\n\t\tconst dataFields = getTermDataFields( select, context, clientId );\n\n\t\tconst newValues = {};\n\t\tfor ( const [ attributeName, source ] of Object.entries( bindings ) ) {\n\t\t\t// Use the value, the field label, or the field key.\n\t\t\tconst fieldKey = source.args.field;\n\t\t\tconst { value: fieldValue, label: fieldLabel } =\n\t\t\t\tdataFields?.[ fieldKey ] || {};\n\t\t\tnewValues[ attributeName ] = fieldValue ?? fieldLabel ?? fieldKey;\n\t\t}\n\t\treturn newValues;\n\t},\n\t// eslint-disable-next-line no-unused-vars\n\tsetValues( { dispatch, context, bindings } ) {\n\t\t// Terms are typically not editable through block bindings in most contexts.\n\t\treturn false;\n\t},\n\tcanUserEditValue( { select, context, args } ) {\n\t\tconst { getBlockName, getSelectedBlockClientId } =\n\t\t\tselect( blockEditorStore );\n\n\t\tconst clientId = getSelectedBlockClientId();\n\t\tconst blockName = getBlockName?.( clientId );\n\n\t\t// Navigaton block types are read-only.\n\t\t// See https://github.com/WordPress/gutenberg/pull/72165.\n\t\tif ( NAVIGATION_BLOCK_TYPES.includes( blockName ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Terms are typically read-only when displayed.\n\t\tif ( context?.termQuery ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Lock editing when `taxonomy` or `termId` is not defined.\n\t\tif ( ! context?.taxonomy || ! context?.termId ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst fieldValue = getTermDataFields( select, context, undefined )?.[\n\t\t\targs.field\n\t\t]?.value;\n\t\t// Empty string or `false` could be a valid value, so we need to check if the field value is undefined.\n\t\tif ( fieldValue === undefined ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn false;\n\t},\n\tgetFieldsList( { select, context } ) {\n\t\t// Deprecated, will be removed after 6.9.\n\t\treturn getTermDataFields( select, context );\n\t},\n\teditorUI( { select, context } ) {\n\t\tconst selectedBlock = select( blockEditorStore ).getSelectedBlock();\n\t\t// Exit early for navigation blocks (read-only)\n\t\tif ( NAVIGATION_BLOCK_TYPES.includes( selectedBlock?.name ) ) {\n\t\t\treturn {};\n\t\t}\n\t\tconst termDataFields = Object.entries(\n\t\t\tgetTermDataFields( select, context ) || {}\n\t\t).map( ( [ key, field ] ) => ( {\n\t\t\tlabel: field.label,\n\t\t\ttype: field.type,\n\t\t\targs: {\n\t\t\t\tfield: key,\n\t\t\t},\n\t\t} ) );\n\t\t/*\n\t\t * We need to define the data as [{ label: string, value: any, type: https://developer.wordpress.org/block-editor/reference-guides/block-api/block-attributes/#type-validation }]\n\t\t */\n\t\treturn {\n\t\t\tmode: 'dropdown',\n\t\t\tdata: termDataFields,\n\t\t};\n\t},\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { __ } from '@wordpress/i18n';\nimport { store as coreDataStore } from '@wordpress/core-data';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\n\n// Navigation block types that use special handling for backwards compatibility\nconst NAVIGATION_BLOCK_TYPES = [\n\t'core/navigation-link',\n\t'core/navigation-submenu',\n];\n\n/**\n * Creates the data fields object with the given term data values and ID value.\n *\n * @param {Object} termDataValues The term data values.\n * @param {string|number} idValue The ID value to use.\n * @return {Object} The data fields object.\n */\nfunction createDataFields( termDataValues, idValue ) {\n\treturn {\n\t\tid: {\n\t\t\tlabel: __( 'Term ID' ),\n\t\t\tvalue: idValue,\n\t\t\ttype: 'string',\n\t\t},\n\t\tname: {\n\t\t\tlabel: __( 'Name' ),\n\t\t\tvalue: termDataValues?.name,\n\t\t\ttype: 'string',\n\t\t},\n\t\tslug: {\n\t\t\tlabel: __( 'Slug' ),\n\t\t\tvalue: termDataValues?.slug,\n\t\t\ttype: 'string',\n\t\t},\n\t\tlink: {\n\t\t\tlabel: __( 'Link' ),\n\t\t\tvalue: termDataValues?.link,\n\t\t\ttype: 'string',\n\t\t},\n\t\tdescription: {\n\t\t\tlabel: __( 'Description' ),\n\t\t\tvalue: termDataValues?.description,\n\t\t\ttype: 'string',\n\t\t},\n\t\tparent: {\n\t\t\tlabel: __( 'Parent ID' ),\n\t\t\tvalue: termDataValues?.parent,\n\t\t\ttype: 'string',\n\t\t},\n\t\tcount: {\n\t\t\tlabel: __( 'Count' ),\n\t\t\tvalue: `(${ termDataValues?.count ?? 0 })`,\n\t\t\ttype: 'string',\n\t\t},\n\t};\n}\n\n/**\n * Gets a list of term data fields with their values and labels\n * to be consumed in the needed callbacks.\n * If the value is not available based on context, like in templates,\n * it falls back to the default value, label, or key.\n *\n * @param {Object} select The select function from the data store.\n * @param {Object} context The context provided.\n * @param {string} clientId The block client ID used to read attributes.\n * @return {Object} List of term data fields with their value and label.\n *\n * @example\n * ```js\n * {\n * name: {\n * label: 'Term Name',\n * value: 'Category Name',\n * },\n * count: {\n * label: 'Term Count',\n * value: 5,\n * },\n * ...\n * }\n * ```\n */\nfunction getTermDataFields( select, context, clientId ) {\n\tconst { getEntityRecord } = select( coreDataStore );\n\tconst { getBlockAttributes, getBlockName } = select( blockEditorStore );\n\n\tlet termDataValues, dataFields;\n\n\t/*\n\t * BACKWARDS COMPATIBILITY: Hardcoded exception for navigation blocks.\n\t * Required for WordPress 6.9+ navigation blocks. DO NOT REMOVE.\n\t */\n\tconst blockName = getBlockName?.( clientId );\n\tconst isNavigationBlock = NAVIGATION_BLOCK_TYPES.includes( blockName );\n\n\tlet termId, taxonomy;\n\n\tif ( isNavigationBlock ) {\n\t\t// Navigation blocks: read from block attributes\n\t\tconst blockAttributes = getBlockAttributes?.( clientId );\n\t\ttermId = blockAttributes?.id;\n\t\tconst typeFromAttributes = blockAttributes?.type;\n\t\ttaxonomy =\n\t\t\ttypeFromAttributes === 'tag' ? 'post_tag' : typeFromAttributes;\n\t} else {\n\t\t// All other blocks: use context\n\t\ttermId = context?.termId;\n\t\ttaxonomy = context?.taxonomy;\n\t}\n\n\tif ( taxonomy && termId ) {\n\t\ttermDataValues = getEntityRecord( 'taxonomy', taxonomy, termId );\n\n\t\tif ( ! termDataValues && context?.termData ) {\n\t\t\ttermDataValues = context.termData;\n\t\t}\n\n\t\tif ( termDataValues ) {\n\t\t\tdataFields = createDataFields( termDataValues, termId );\n\t\t}\n\t} else if ( context?.termData ) {\n\t\ttermDataValues = context.termData;\n\t\tdataFields = createDataFields(\n\t\t\ttermDataValues,\n\t\t\ttermDataValues?.term_id\n\t\t);\n\t}\n\n\tif ( ! dataFields || ! Object.keys( dataFields ).length ) {\n\t\treturn null;\n\t}\n\n\treturn dataFields;\n}\n\n/**\n * @type {WPBlockBindingsSource}\n */\nexport default {\n\tname: 'core/term-data',\n\tusesContext: [ 'taxonomy', 'termId', 'termData' ],\n\tgetValues( { select, context, bindings, clientId } ) {\n\t\tconst dataFields = getTermDataFields( select, context, clientId );\n\n\t\tconst newValues = {};\n\t\tfor ( const [ attributeName, source ] of Object.entries( bindings ) ) {\n\t\t\t// Use the value, the field label, or the field key.\n\t\t\tconst fieldKey = source.args.field;\n\t\t\tconst { value: fieldValue, label: fieldLabel } =\n\t\t\t\tdataFields?.[ fieldKey ] || {};\n\t\t\tnewValues[ attributeName ] = fieldValue ?? fieldLabel ?? fieldKey;\n\t\t}\n\t\treturn newValues;\n\t},\n\t// eslint-disable-next-line no-unused-vars\n\tsetValues( { dispatch, context, bindings } ) {\n\t\t// Terms are typically not editable through block bindings in most contexts.\n\t\treturn false;\n\t},\n\tcanUserEditValue( { select, context, args } ) {\n\t\tconst { getBlockName, getSelectedBlockClientId } =\n\t\t\tselect( blockEditorStore );\n\n\t\tconst clientId = getSelectedBlockClientId();\n\t\tconst blockName = getBlockName?.( clientId );\n\n\t\t// Navigaton block types are read-only.\n\t\t// See https://github.com/WordPress/gutenberg/pull/72165.\n\t\tif ( NAVIGATION_BLOCK_TYPES.includes( blockName ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Terms are typically read-only when displayed.\n\t\tif ( context?.termQuery ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Lock editing when `taxonomy` or `termId` is not defined.\n\t\tif ( ! context?.taxonomy || ! context?.termId ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst fieldValue = getTermDataFields( select, context, undefined )?.[\n\t\t\targs.field\n\t\t]?.value;\n\t\t// Empty string or `false` could be a valid value, so we need to check if the field value is undefined.\n\t\tif ( fieldValue === undefined ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn false;\n\t},\n\tgetFieldsList( { select, context } ) {\n\t\tconst clientId = select( blockEditorStore ).getSelectedBlockClientId();\n\t\tconst termDataFields = getTermDataFields( select, context, clientId );\n\t\tif ( ! termDataFields ) {\n\t\t\treturn [];\n\t\t}\n\t\treturn Object.entries( termDataFields ).map( ( [ key, field ] ) => ( {\n\t\t\tlabel: field.label,\n\t\t\ttype: field.type,\n\t\t\targs: { field: key },\n\t\t} ) );\n\t},\n};\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,161 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import {
3
+ BlockSettingsMenuControls,
4
+ __unstableBlockSettingsMenuFirstItem as BlockSettingsMenuFirstItem,
5
+ store as blockEditorStore,
6
+ useBlockDisplayInformation
7
+ } from "@wordpress/block-editor";
8
+ import { store as coreStore } from "@wordpress/core-data";
9
+ import { __experimentalText as Text, MenuItem } from "@wordpress/components";
10
+ import { useSelect, useDispatch } from "@wordpress/data";
11
+ import { __, _x } from "@wordpress/i18n";
12
+ import { store as editorStore } from "../../store";
13
+ import { unlock } from "../../lock-unlock";
14
+ import usePostContentBlocks from "../provider/use-post-content-blocks";
15
+ function ContentOnlySettingsMenuItems({ clientId, onClose }) {
16
+ const postContentBlocks = usePostContentBlocks();
17
+ const { entity, onNavigateToEntityRecord, canEditTemplates } = useSelect(
18
+ (select) => {
19
+ const {
20
+ getBlockParentsByBlockName,
21
+ getSettings,
22
+ getBlockAttributes,
23
+ getBlockParents
24
+ } = select(blockEditorStore);
25
+ const { getCurrentTemplateId, getRenderingMode } = select(editorStore);
26
+ const patternParent = getBlockParentsByBlockName(
27
+ clientId,
28
+ "core/block",
29
+ true
30
+ )[0];
31
+ let record;
32
+ if (patternParent) {
33
+ record = select(coreStore).getEntityRecord(
34
+ "postType",
35
+ "wp_block",
36
+ getBlockAttributes(patternParent).ref
37
+ );
38
+ } else if (getRenderingMode() === "template-locked" && !getBlockParents(clientId).some(
39
+ (parent) => postContentBlocks.includes(parent)
40
+ )) {
41
+ record = select(coreStore).getEntityRecord(
42
+ "postType",
43
+ "wp_template",
44
+ getCurrentTemplateId()
45
+ );
46
+ }
47
+ if (!record) {
48
+ return {};
49
+ }
50
+ const _canEditTemplates = select(coreStore).canUser("create", {
51
+ kind: "postType",
52
+ name: "wp_template"
53
+ });
54
+ return {
55
+ canEditTemplates: _canEditTemplates,
56
+ entity: record,
57
+ onNavigateToEntityRecord: getSettings().onNavigateToEntityRecord
58
+ };
59
+ },
60
+ [clientId, postContentBlocks]
61
+ );
62
+ if (!entity) {
63
+ return /* @__PURE__ */ jsx(
64
+ TemplateLockContentOnlyMenuItems,
65
+ {
66
+ clientId,
67
+ onClose
68
+ }
69
+ );
70
+ }
71
+ const isPattern = entity.type === "wp_block";
72
+ let helpText = isPattern ? __(
73
+ "Edit the pattern to move, delete, or make further changes to this block."
74
+ ) : __(
75
+ "Edit the template to move, delete, or make further changes to this block."
76
+ );
77
+ if (!canEditTemplates) {
78
+ helpText = __(
79
+ "Only users with permissions to edit the template can move or delete this block"
80
+ );
81
+ }
82
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
83
+ /* @__PURE__ */ jsx(BlockSettingsMenuFirstItem, { children: /* @__PURE__ */ jsx(
84
+ MenuItem,
85
+ {
86
+ onClick: () => {
87
+ onNavigateToEntityRecord({
88
+ postId: entity.id,
89
+ postType: entity.type
90
+ });
91
+ },
92
+ disabled: !canEditTemplates,
93
+ children: isPattern ? __("Edit pattern") : __("Edit template")
94
+ }
95
+ ) }),
96
+ /* @__PURE__ */ jsx(
97
+ Text,
98
+ {
99
+ variant: "muted",
100
+ as: "p",
101
+ className: "editor-content-only-settings-menu__description",
102
+ children: helpText
103
+ }
104
+ )
105
+ ] });
106
+ }
107
+ function TemplateLockContentOnlyMenuItems({ clientId, onClose }) {
108
+ const { contentLockingParent } = useSelect(
109
+ (select) => {
110
+ const { getContentLockingParent } = unlock(
111
+ select(blockEditorStore)
112
+ );
113
+ return {
114
+ contentLockingParent: getContentLockingParent(clientId)
115
+ };
116
+ },
117
+ [clientId]
118
+ );
119
+ const blockDisplayInformation = useBlockDisplayInformation(contentLockingParent);
120
+ const blockEditorActions = useDispatch(blockEditorStore);
121
+ if (!blockDisplayInformation?.title) {
122
+ return null;
123
+ }
124
+ const { modifyContentLockBlock } = unlock(blockEditorActions);
125
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
126
+ /* @__PURE__ */ jsx(BlockSettingsMenuFirstItem, { children: /* @__PURE__ */ jsx(
127
+ MenuItem,
128
+ {
129
+ onClick: () => {
130
+ modifyContentLockBlock(contentLockingParent);
131
+ onClose();
132
+ },
133
+ children: _x("Unlock", "Unlock content locked blocks")
134
+ }
135
+ ) }),
136
+ /* @__PURE__ */ jsx(
137
+ Text,
138
+ {
139
+ variant: "muted",
140
+ as: "p",
141
+ className: "editor-content-only-settings-menu__description",
142
+ children: __(
143
+ "Temporarily unlock the parent block to edit, delete or make further changes to this block."
144
+ )
145
+ }
146
+ )
147
+ ] });
148
+ }
149
+ function ContentOnlySettingsMenu() {
150
+ return /* @__PURE__ */ jsx(BlockSettingsMenuControls, { children: ({ selectedClientIds, onClose }) => selectedClientIds.length === 1 && /* @__PURE__ */ jsx(
151
+ ContentOnlySettingsMenuItems,
152
+ {
153
+ clientId: selectedClientIds[0],
154
+ onClose
155
+ }
156
+ ) });
157
+ }
158
+ export {
159
+ ContentOnlySettingsMenu as default
160
+ };
161
+ //# sourceMappingURL=content-only-settings-menu.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/components/block-settings-menu/content-only-settings-menu.js"],
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport {\n\tBlockSettingsMenuControls,\n\t__unstableBlockSettingsMenuFirstItem as BlockSettingsMenuFirstItem,\n\tstore as blockEditorStore,\n\tuseBlockDisplayInformation,\n} from '@wordpress/block-editor';\nimport { store as coreStore } from '@wordpress/core-data';\nimport { __experimentalText as Text, MenuItem } from '@wordpress/components';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { __, _x } from '@wordpress/i18n';\n\n/**\n * Internal dependencies\n */\nimport { store as editorStore } from '../../store';\nimport { unlock } from '../../lock-unlock';\nimport usePostContentBlocks from '../provider/use-post-content-blocks';\n\nfunction ContentOnlySettingsMenuItems( { clientId, onClose } ) {\n\tconst postContentBlocks = usePostContentBlocks();\n\tconst { entity, onNavigateToEntityRecord, canEditTemplates } = useSelect(\n\t\t( select ) => {\n\t\t\tconst {\n\t\t\t\tgetBlockParentsByBlockName,\n\t\t\t\tgetSettings,\n\t\t\t\tgetBlockAttributes,\n\t\t\t\tgetBlockParents,\n\t\t\t} = select( blockEditorStore );\n\t\t\tconst { getCurrentTemplateId, getRenderingMode } =\n\t\t\t\tselect( editorStore );\n\t\t\tconst patternParent = getBlockParentsByBlockName(\n\t\t\t\tclientId,\n\t\t\t\t'core/block',\n\t\t\t\ttrue\n\t\t\t)[ 0 ];\n\n\t\t\tlet record;\n\t\t\tif ( patternParent ) {\n\t\t\t\trecord = select( coreStore ).getEntityRecord(\n\t\t\t\t\t'postType',\n\t\t\t\t\t'wp_block',\n\t\t\t\t\tgetBlockAttributes( patternParent ).ref\n\t\t\t\t);\n\t\t\t} else if (\n\t\t\t\tgetRenderingMode() === 'template-locked' &&\n\t\t\t\t! getBlockParents( clientId ).some( ( parent ) =>\n\t\t\t\t\tpostContentBlocks.includes( parent )\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\trecord = select( coreStore ).getEntityRecord(\n\t\t\t\t\t'postType',\n\t\t\t\t\t'wp_template',\n\t\t\t\t\tgetCurrentTemplateId()\n\t\t\t\t);\n\t\t\t}\n\t\t\tif ( ! record ) {\n\t\t\t\treturn {};\n\t\t\t}\n\t\t\tconst _canEditTemplates = select( coreStore ).canUser( 'create', {\n\t\t\t\tkind: 'postType',\n\t\t\t\tname: 'wp_template',\n\t\t\t} );\n\t\t\treturn {\n\t\t\t\tcanEditTemplates: _canEditTemplates,\n\t\t\t\tentity: record,\n\t\t\t\tonNavigateToEntityRecord:\n\t\t\t\t\tgetSettings().onNavigateToEntityRecord,\n\t\t\t};\n\t\t},\n\t\t[ clientId, postContentBlocks ]\n\t);\n\n\tif ( ! entity ) {\n\t\treturn (\n\t\t\t<TemplateLockContentOnlyMenuItems\n\t\t\t\tclientId={ clientId }\n\t\t\t\tonClose={ onClose }\n\t\t\t/>\n\t\t);\n\t}\n\n\tconst isPattern = entity.type === 'wp_block';\n\tlet helpText = isPattern\n\t\t? __(\n\t\t\t\t'Edit the pattern to move, delete, or make further changes to this block.'\n\t\t )\n\t\t: __(\n\t\t\t\t'Edit the template to move, delete, or make further changes to this block.'\n\t\t );\n\n\tif ( ! canEditTemplates ) {\n\t\thelpText = __(\n\t\t\t'Only users with permissions to edit the template can move or delete this block'\n\t\t);\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<BlockSettingsMenuFirstItem>\n\t\t\t\t<MenuItem\n\t\t\t\t\tonClick={ () => {\n\t\t\t\t\t\tonNavigateToEntityRecord( {\n\t\t\t\t\t\t\tpostId: entity.id,\n\t\t\t\t\t\t\tpostType: entity.type,\n\t\t\t\t\t\t} );\n\t\t\t\t\t} }\n\t\t\t\t\tdisabled={ ! canEditTemplates }\n\t\t\t\t>\n\t\t\t\t\t{ isPattern ? __( 'Edit pattern' ) : __( 'Edit template' ) }\n\t\t\t\t</MenuItem>\n\t\t\t</BlockSettingsMenuFirstItem>\n\t\t\t<Text\n\t\t\t\tvariant=\"muted\"\n\t\t\t\tas=\"p\"\n\t\t\t\tclassName=\"editor-content-only-settings-menu__description\"\n\t\t\t>\n\t\t\t\t{ helpText }\n\t\t\t</Text>\n\t\t</>\n\t);\n}\n\nfunction TemplateLockContentOnlyMenuItems( { clientId, onClose } ) {\n\tconst { contentLockingParent } = useSelect(\n\t\t( select ) => {\n\t\t\tconst { getContentLockingParent } = unlock(\n\t\t\t\tselect( blockEditorStore )\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tcontentLockingParent: getContentLockingParent( clientId ),\n\t\t\t};\n\t\t},\n\t\t[ clientId ]\n\t);\n\tconst blockDisplayInformation =\n\t\tuseBlockDisplayInformation( contentLockingParent );\n\tconst blockEditorActions = useDispatch( blockEditorStore );\n\tif ( ! blockDisplayInformation?.title ) {\n\t\treturn null;\n\t}\n\n\tconst { modifyContentLockBlock } = unlock( blockEditorActions );\n\n\treturn (\n\t\t<>\n\t\t\t<BlockSettingsMenuFirstItem>\n\t\t\t\t<MenuItem\n\t\t\t\t\tonClick={ () => {\n\t\t\t\t\t\tmodifyContentLockBlock( contentLockingParent );\n\t\t\t\t\t\tonClose();\n\t\t\t\t\t} }\n\t\t\t\t>\n\t\t\t\t\t{ _x( 'Unlock', 'Unlock content locked blocks' ) }\n\t\t\t\t</MenuItem>\n\t\t\t</BlockSettingsMenuFirstItem>\n\t\t\t<Text\n\t\t\t\tvariant=\"muted\"\n\t\t\t\tas=\"p\"\n\t\t\t\tclassName=\"editor-content-only-settings-menu__description\"\n\t\t\t>\n\t\t\t\t{ __(\n\t\t\t\t\t'Temporarily unlock the parent block to edit, delete or make further changes to this block.'\n\t\t\t\t) }\n\t\t\t</Text>\n\t\t</>\n\t);\n}\n\nexport default function ContentOnlySettingsMenu() {\n\treturn (\n\t\t<BlockSettingsMenuControls>\n\t\t\t{ ( { selectedClientIds, onClose } ) =>\n\t\t\t\tselectedClientIds.length === 1 && (\n\t\t\t\t\t<ContentOnlySettingsMenuItems\n\t\t\t\t\t\tclientId={ selectedClientIds[ 0 ] }\n\t\t\t\t\t\tonClose={ onClose }\n\t\t\t\t\t/>\n\t\t\t\t)\n\t\t\t}\n\t\t</BlockSettingsMenuControls>\n\t);\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -1,4 +1,5 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
+ import clsx from "clsx";
2
3
  import { __ } from "@wordpress/i18n";
3
4
  import { useSelect } from "@wordpress/data";
4
5
  import {
@@ -12,13 +13,17 @@ import {
12
13
  import { unlock } from "../../lock-unlock";
13
14
  import CommentAuthorInfo from "./comment-author-info";
14
15
  import CommentForm from "./comment-form";
15
- import { focusCommentThread } from "./utils";
16
+ import { focusCommentThread, noop } from "./utils";
16
17
  const { useBlockElement } = unlock(blockEditorPrivateApis);
17
18
  function AddComment({
18
19
  onSubmit,
19
20
  showCommentBoard,
20
21
  setShowCommentBoard,
21
- commentSidebarRef
22
+ commentSidebarRef,
23
+ reflowComments = noop,
24
+ isFloating = false,
25
+ y,
26
+ refs
22
27
  }) {
23
28
  const { clientId, blockCommentId } = useSelect((select) => {
24
29
  const { getSelectedBlock } = select(blockEditorStore);
@@ -35,10 +40,27 @@ function AddComment({
35
40
  return /* @__PURE__ */ jsxs(
36
41
  VStack,
37
42
  {
38
- className: "editor-collab-sidebar-panel__thread is-selected",
43
+ className: clsx(
44
+ "editor-collab-sidebar-panel__thread is-selected",
45
+ {
46
+ "is-floating": isFloating
47
+ }
48
+ ),
39
49
  spacing: "3",
40
50
  tabIndex: 0,
51
+ "aria-label": __("New note"),
41
52
  role: "listitem",
53
+ ref: isFloating ? refs.setFloating : void 0,
54
+ style: isFloating ? (
55
+ // Delay showing the floating note box until a Y position is known to prevent blink.
56
+ { top: y, opacity: !y ? 0 : void 0 }
57
+ ) : void 0,
58
+ onBlur: (event) => {
59
+ if (event.currentTarget.contains(event.relatedTarget)) {
60
+ return;
61
+ }
62
+ setShowCommentBoard(false);
63
+ },
42
64
  children: [
43
65
  /* @__PURE__ */ jsx(HStack, { alignment: "left", spacing: "3", children: /* @__PURE__ */ jsx(CommentAuthorInfo, {}) }),
44
66
  /* @__PURE__ */ jsx(
@@ -53,8 +75,9 @@ function AddComment({
53
75
  setShowCommentBoard(false);
54
76
  blockElement?.focus();
55
77
  },
78
+ reflowComments,
56
79
  submitButtonText: __("Add note"),
57
- labelText: __("New Note")
80
+ labelText: __("New note")
58
81
  }
59
82
  )
60
83
  ]
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/collab-sidebar/add-comment.js"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { __ } from '@wordpress/i18n';\nimport { useSelect } from '@wordpress/data';\nimport {\n\t__experimentalHStack as HStack,\n\t__experimentalVStack as VStack,\n} from '@wordpress/components';\nimport {\n\tstore as blockEditorStore,\n\tprivateApis as blockEditorPrivateApis,\n} from '@wordpress/block-editor';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from '../../lock-unlock';\nimport CommentAuthorInfo from './comment-author-info';\nimport CommentForm from './comment-form';\nimport { focusCommentThread } from './utils';\n\nconst { useBlockElement } = unlock( blockEditorPrivateApis );\n\nexport function AddComment( {\n\tonSubmit,\n\tshowCommentBoard,\n\tsetShowCommentBoard,\n\tcommentSidebarRef,\n} ) {\n\tconst { clientId, blockCommentId } = useSelect( ( select ) => {\n\t\tconst { getSelectedBlock } = select( blockEditorStore );\n\t\tconst selectedBlock = getSelectedBlock();\n\t\treturn {\n\t\t\tclientId: selectedBlock?.clientId,\n\t\t\tblockCommentId: selectedBlock?.attributes?.metadata?.noteId,\n\t\t};\n\t}, [] );\n\tconst blockElement = useBlockElement( clientId );\n\n\tif ( ! showCommentBoard || ! clientId || undefined !== blockCommentId ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<VStack\n\t\t\tclassName=\"editor-collab-sidebar-panel__thread is-selected\"\n\t\t\tspacing=\"3\"\n\t\t\ttabIndex={ 0 }\n\t\t\trole=\"listitem\"\n\t\t>\n\t\t\t<HStack alignment=\"left\" spacing=\"3\">\n\t\t\t\t<CommentAuthorInfo />\n\t\t\t</HStack>\n\t\t\t<CommentForm\n\t\t\t\tonSubmit={ async ( inputComment ) => {\n\t\t\t\t\tconst { id } = await onSubmit( { content: inputComment } );\n\t\t\t\t\tfocusCommentThread( id, commentSidebarRef.current );\n\t\t\t\t\tsetShowCommentBoard( false );\n\t\t\t\t} }\n\t\t\t\tonCancel={ () => {\n\t\t\t\t\tsetShowCommentBoard( false );\n\t\t\t\t\tblockElement?.focus();\n\t\t\t\t} }\n\t\t\t\tsubmitButtonText={ __( 'Add note' ) }\n\t\t\t\tlabelText={ __( 'New Note' ) }\n\t\t\t/>\n\t\t</VStack>\n\t);\n}\n"],
5
- "mappings": "AA6CE,SAOE,KAPF;AA1CF,SAAS,UAAU;AACnB,SAAS,iBAAiB;AAC1B;AAAA,EACC,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,OAClB;AACP;AAAA,EACC,SAAS;AAAA,EACT,eAAe;AAAA,OACT;AAKP,SAAS,cAAc;AACvB,OAAO,uBAAuB;AAC9B,OAAO,iBAAiB;AACxB,SAAS,0BAA0B;AAEnC,MAAM,EAAE,gBAAgB,IAAI,OAAQ,sBAAuB;AAEpD,SAAS,WAAY;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAAI;AACH,QAAM,EAAE,UAAU,eAAe,IAAI,UAAW,CAAE,WAAY;AAC7D,UAAM,EAAE,iBAAiB,IAAI,OAAQ,gBAAiB;AACtD,UAAM,gBAAgB,iBAAiB;AACvC,WAAO;AAAA,MACN,UAAU,eAAe;AAAA,MACzB,gBAAgB,eAAe,YAAY,UAAU;AAAA,IACtD;AAAA,EACD,GAAG,CAAC,CAAE;AACN,QAAM,eAAe,gBAAiB,QAAS;AAE/C,MAAK,CAAE,oBAAoB,CAAE,YAAY,WAAc,gBAAiB;AACvE,WAAO;AAAA,EACR;AAEA,SACC;AAAA,IAAC;AAAA;AAAA,MACA,WAAU;AAAA,MACV,SAAQ;AAAA,MACR,UAAW;AAAA,MACX,MAAK;AAAA,MAEL;AAAA,4BAAC,UAAO,WAAU,QAAO,SAAQ,KAChC,8BAAC,qBAAkB,GACpB;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACA,UAAW,OAAQ,iBAAkB;AACpC,oBAAM,EAAE,GAAG,IAAI,MAAM,SAAU,EAAE,SAAS,aAAa,CAAE;AACzD,iCAAoB,IAAI,kBAAkB,OAAQ;AAClD,kCAAqB,KAAM;AAAA,YAC5B;AAAA,YACA,UAAW,MAAM;AAChB,kCAAqB,KAAM;AAC3B,4BAAc,MAAM;AAAA,YACrB;AAAA,YACA,kBAAmB,GAAI,UAAW;AAAA,YAClC,WAAY,GAAI,UAAW;AAAA;AAAA,QAC5B;AAAA;AAAA;AAAA,EACD;AAEF;",
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n/**\n * WordPress dependencies\n */\nimport { __ } from '@wordpress/i18n';\nimport { useSelect } from '@wordpress/data';\nimport {\n\t__experimentalHStack as HStack,\n\t__experimentalVStack as VStack,\n} from '@wordpress/components';\nimport {\n\tstore as blockEditorStore,\n\tprivateApis as blockEditorPrivateApis,\n} from '@wordpress/block-editor';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from '../../lock-unlock';\nimport CommentAuthorInfo from './comment-author-info';\nimport CommentForm from './comment-form';\nimport { focusCommentThread, noop } from './utils';\n\nconst { useBlockElement } = unlock( blockEditorPrivateApis );\n\nexport function AddComment( {\n\tonSubmit,\n\tshowCommentBoard,\n\tsetShowCommentBoard,\n\tcommentSidebarRef,\n\treflowComments = noop,\n\tisFloating = false,\n\ty,\n\trefs,\n} ) {\n\tconst { clientId, blockCommentId } = useSelect( ( select ) => {\n\t\tconst { getSelectedBlock } = select( blockEditorStore );\n\t\tconst selectedBlock = getSelectedBlock();\n\t\treturn {\n\t\t\tclientId: selectedBlock?.clientId,\n\t\t\tblockCommentId: selectedBlock?.attributes?.metadata?.noteId,\n\t\t};\n\t}, [] );\n\tconst blockElement = useBlockElement( clientId );\n\n\tif ( ! showCommentBoard || ! clientId || undefined !== blockCommentId ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<VStack\n\t\t\tclassName={ clsx(\n\t\t\t\t'editor-collab-sidebar-panel__thread is-selected',\n\t\t\t\t{\n\t\t\t\t\t'is-floating': isFloating,\n\t\t\t\t}\n\t\t\t) }\n\t\t\tspacing=\"3\"\n\t\t\ttabIndex={ 0 }\n\t\t\taria-label={ __( 'New note' ) }\n\t\t\trole=\"listitem\"\n\t\t\tref={ isFloating ? refs.setFloating : undefined }\n\t\t\tstyle={\n\t\t\t\tisFloating\n\t\t\t\t\t? // Delay showing the floating note box until a Y position is known to prevent blink.\n\t\t\t\t\t { top: y, opacity: ! y ? 0 : undefined }\n\t\t\t\t\t: undefined\n\t\t\t}\n\t\t\tonBlur={ ( event ) => {\n\t\t\t\tif ( event.currentTarget.contains( event.relatedTarget ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsetShowCommentBoard( false );\n\t\t\t} }\n\t\t>\n\t\t\t<HStack alignment=\"left\" spacing=\"3\">\n\t\t\t\t<CommentAuthorInfo />\n\t\t\t</HStack>\n\t\t\t<CommentForm\n\t\t\t\tonSubmit={ async ( inputComment ) => {\n\t\t\t\t\tconst { id } = await onSubmit( { content: inputComment } );\n\t\t\t\t\tfocusCommentThread( id, commentSidebarRef.current );\n\t\t\t\t\tsetShowCommentBoard( false );\n\t\t\t\t} }\n\t\t\t\tonCancel={ () => {\n\t\t\t\t\tsetShowCommentBoard( false );\n\t\t\t\t\tblockElement?.focus();\n\t\t\t\t} }\n\t\t\t\treflowComments={ reflowComments }\n\t\t\t\tsubmitButtonText={ __( 'Add note' ) }\n\t\t\t\tlabelText={ __( 'New note' ) }\n\t\t\t/>\n\t\t</VStack>\n\t);\n}\n"],
5
+ "mappings": "AAqDE,SA0BE,KA1BF;AAlDF,OAAO,UAAU;AAIjB,SAAS,UAAU;AACnB,SAAS,iBAAiB;AAC1B;AAAA,EACC,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,OAClB;AACP;AAAA,EACC,SAAS;AAAA,EACT,eAAe;AAAA,OACT;AAKP,SAAS,cAAc;AACvB,OAAO,uBAAuB;AAC9B,OAAO,iBAAiB;AACxB,SAAS,oBAAoB,YAAY;AAEzC,MAAM,EAAE,gBAAgB,IAAI,OAAQ,sBAAuB;AAEpD,SAAS,WAAY;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb;AAAA,EACA;AACD,GAAI;AACH,QAAM,EAAE,UAAU,eAAe,IAAI,UAAW,CAAE,WAAY;AAC7D,UAAM,EAAE,iBAAiB,IAAI,OAAQ,gBAAiB;AACtD,UAAM,gBAAgB,iBAAiB;AACvC,WAAO;AAAA,MACN,UAAU,eAAe;AAAA,MACzB,gBAAgB,eAAe,YAAY,UAAU;AAAA,IACtD;AAAA,EACD,GAAG,CAAC,CAAE;AACN,QAAM,eAAe,gBAAiB,QAAS;AAE/C,MAAK,CAAE,oBAAoB,CAAE,YAAY,WAAc,gBAAiB;AACvE,WAAO;AAAA,EACR;AAEA,SACC;AAAA,IAAC;AAAA;AAAA,MACA,WAAY;AAAA,QACX;AAAA,QACA;AAAA,UACC,eAAe;AAAA,QAChB;AAAA,MACD;AAAA,MACA,SAAQ;AAAA,MACR,UAAW;AAAA,MACX,cAAa,GAAI,UAAW;AAAA,MAC5B,MAAK;AAAA,MACL,KAAM,aAAa,KAAK,cAAc;AAAA,MACtC,OACC;AAAA;AAAA,QAEG,EAAE,KAAK,GAAG,SAAS,CAAE,IAAI,IAAI,OAAU;AAAA,UACvC;AAAA,MAEJ,QAAS,CAAE,UAAW;AACrB,YAAK,MAAM,cAAc,SAAU,MAAM,aAAc,GAAI;AAC1D;AAAA,QACD;AACA,4BAAqB,KAAM;AAAA,MAC5B;AAAA,MAEA;AAAA,4BAAC,UAAO,WAAU,QAAO,SAAQ,KAChC,8BAAC,qBAAkB,GACpB;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACA,UAAW,OAAQ,iBAAkB;AACpC,oBAAM,EAAE,GAAG,IAAI,MAAM,SAAU,EAAE,SAAS,aAAa,CAAE;AACzD,iCAAoB,IAAI,kBAAkB,OAAQ;AAClD,kCAAqB,KAAM;AAAA,YAC5B;AAAA,YACA,UAAW,MAAM;AAChB,kCAAqB,KAAM;AAC3B,4BAAc,MAAM;AAAA,YACrB;AAAA,YACA;AAAA,YACA,kBAAmB,GAAI,UAAW;AAAA,YAClC,WAAY,GAAI,UAAW;AAAA;AAAA,QAC5B;AAAA;AAAA;AAAA,EACD;AAEF;",
6
6
  "names": []
7
7
  }
@@ -3,11 +3,10 @@ import { ToolbarButton } from "@wordpress/components";
3
3
  import { __, _n, sprintf } from "@wordpress/i18n";
4
4
  import { useMemo } from "@wordpress/element";
5
5
  import { privateApis as blockEditorPrivateApis } from "@wordpress/block-editor";
6
- import clsx from "clsx";
7
6
  import { unlock } from "../../lock-unlock";
8
7
  import { getAvatarBorderColor } from "./utils";
9
8
  const { CommentIconToolbarSlotFill } = unlock(blockEditorPrivateApis);
10
- const CommentAvatarIndicator = ({ onClick, thread, hasMoreComments }) => {
9
+ const CommentAvatarIndicator = ({ onClick, thread }) => {
11
10
  const threadParticipants = useMemo(() => {
12
11
  if (!thread) {
13
12
  return [];
@@ -17,13 +16,11 @@ const CommentAvatarIndicator = ({ onClick, thread, hasMoreComments }) => {
17
16
  allComments.sort((a, b) => new Date(a.date) - new Date(b.date));
18
17
  allComments.forEach((comment) => {
19
18
  if (comment.author_name && comment.author_avatar_urls) {
20
- const authorKey = `${comment.author}-${comment.author_name}`;
21
- if (!participantsMap.has(authorKey)) {
22
- participantsMap.set(authorKey, {
19
+ if (!participantsMap.has(comment.author)) {
20
+ participantsMap.set(comment.author, {
23
21
  name: comment.author_name,
24
22
  avatar: comment.author_avatar_urls?.["48"] || comment.author_avatar_urls?.["96"],
25
23
  id: comment.author,
26
- isOriginalCommenter: comment.id === thread.id,
27
24
  date: comment.date
28
25
  });
29
26
  }
@@ -31,14 +28,13 @@ const CommentAvatarIndicator = ({ onClick, thread, hasMoreComments }) => {
31
28
  });
32
29
  return Array.from(participantsMap.values());
33
30
  }, [thread]);
34
- const hasUnresolved = thread?.status !== "approved";
35
- const threadHasMoreParticipants = hasMoreComments && thread?.reply && 1 + thread.reply.length >= 100;
36
31
  if (!threadParticipants.length) {
37
32
  return null;
38
33
  }
39
34
  const maxAvatars = 3;
40
35
  const visibleParticipants = threadParticipants.slice(0, maxAvatars);
41
36
  const overflowCount = Math.max(0, threadParticipants.length - maxAvatars);
37
+ const threadHasMoreParticipants = threadParticipants.length > 100;
42
38
  const overflowText = threadHasMoreParticipants && overflowCount > 0 ? __("100+") : sprintf(
43
39
  // translators: %s: Number of participants.
44
40
  __("+%s"),
@@ -56,9 +52,7 @@ const CommentAvatarIndicator = ({ onClick, thread, hasMoreComments }) => {
56
52
  return /* @__PURE__ */ jsx(CommentIconToolbarSlotFill.Fill, { children: /* @__PURE__ */ jsx(
57
53
  ToolbarButton,
58
54
  {
59
- className: clsx("comment-avatar-indicator", {
60
- "has-unresolved": hasUnresolved
61
- }),
55
+ className: "comment-avatar-indicator",
62
56
  label: __("View notes"),
63
57
  onClick,
64
58
  showTooltip: true,
@@ -76,7 +70,7 @@ const CommentAvatarIndicator = ({ onClick, thread, hasMoreComments }) => {
76
70
  )
77
71
  }
78
72
  },
79
- participant.name + index
73
+ participant.id
80
74
  )),
81
75
  overflowCount > 0 && /* @__PURE__ */ jsx(
82
76
  "div",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/collab-sidebar/comment-indicator-toolbar.js"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { ToolbarButton } from '@wordpress/components';\nimport { __, _n, sprintf } from '@wordpress/i18n';\nimport { useMemo } from '@wordpress/element';\nimport { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';\n\n/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from '../../lock-unlock';\nimport { getAvatarBorderColor } from './utils';\n\nconst { CommentIconToolbarSlotFill } = unlock( blockEditorPrivateApis );\n\nconst CommentAvatarIndicator = ( { onClick, thread, hasMoreComments } ) => {\n\tconst threadParticipants = useMemo( () => {\n\t\tif ( ! thread ) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst participantsMap = new Map();\n\t\tconst allComments = [ thread, ...thread.reply ];\n\n\t\t// Sort by date to show participants in chronological order.\n\t\tallComments.sort( ( a, b ) => new Date( a.date ) - new Date( b.date ) );\n\n\t\tallComments.forEach( ( comment ) => {\n\t\t\t// Track thread participants (original commenter + repliers).\n\t\t\tif ( comment.author_name && comment.author_avatar_urls ) {\n\t\t\t\tconst authorKey = `${ comment.author }-${ comment.author_name }`;\n\t\t\t\tif ( ! participantsMap.has( authorKey ) ) {\n\t\t\t\t\tparticipantsMap.set( authorKey, {\n\t\t\t\t\t\tname: comment.author_name,\n\t\t\t\t\t\tavatar:\n\t\t\t\t\t\t\tcomment.author_avatar_urls?.[ '48' ] ||\n\t\t\t\t\t\t\tcomment.author_avatar_urls?.[ '96' ],\n\t\t\t\t\t\tid: comment.author,\n\t\t\t\t\t\tisOriginalCommenter: comment.id === thread.id,\n\t\t\t\t\t\tdate: comment.date,\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\treturn Array.from( participantsMap.values() );\n\t}, [ thread ] );\n\n\tconst hasUnresolved = thread?.status !== 'approved';\n\n\t// Check if this specific thread has more participants due to pagination.\n\t// If we have pagination AND this thread + its replies equals or exceeds the API limit,\n\t// then this thread likely has more participants that weren't loaded.\n\tconst threadHasMoreParticipants =\n\t\thasMoreComments && thread?.reply && 1 + thread.reply.length >= 100;\n\n\tif ( ! threadParticipants.length ) {\n\t\treturn null;\n\t}\n\n\t// Show up to 3 avatars, with overflow indicator.\n\tconst maxAvatars = 3;\n\tconst visibleParticipants = threadParticipants.slice( 0, maxAvatars );\n\tconst overflowCount = Math.max( 0, threadParticipants.length - maxAvatars );\n\n\t// If we hit the comment limit, show \"100+\" instead of exact overflow count.\n\tconst overflowText =\n\t\tthreadHasMoreParticipants && overflowCount > 0\n\t\t\t? __( '100+' )\n\t\t\t: sprintf(\n\t\t\t\t\t// translators: %s: Number of participants.\n\t\t\t\t\t__( '+%s' ),\n\t\t\t\t\toverflowCount\n\t\t\t );\n\n\tconst overflowTitle =\n\t\tthreadHasMoreParticipants && overflowCount > 0\n\t\t\t? __( '100+ participants' )\n\t\t\t: sprintf(\n\t\t\t\t\t// translators: %s: Number of participants.\n\t\t\t\t\t_n(\n\t\t\t\t\t\t'+%s more participant',\n\t\t\t\t\t\t'+%s more participants',\n\t\t\t\t\t\toverflowCount\n\t\t\t\t\t),\n\t\t\t\t\toverflowCount\n\t\t\t );\n\n\treturn (\n\t\t<CommentIconToolbarSlotFill.Fill>\n\t\t\t<ToolbarButton\n\t\t\t\tclassName={ clsx( 'comment-avatar-indicator', {\n\t\t\t\t\t'has-unresolved': hasUnresolved,\n\t\t\t\t} ) }\n\t\t\t\tlabel={ __( 'View notes' ) }\n\t\t\t\tonClick={ onClick }\n\t\t\t\tshowTooltip\n\t\t\t>\n\t\t\t\t<div className=\"comment-avatar-stack\">\n\t\t\t\t\t{ visibleParticipants.map( ( participant, index ) => (\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\tkey={ participant.name + index }\n\t\t\t\t\t\t\tsrc={ participant.avatar }\n\t\t\t\t\t\t\talt={ participant.name }\n\t\t\t\t\t\t\tclassName=\"comment-avatar\"\n\t\t\t\t\t\t\tstyle={ {\n\t\t\t\t\t\t\t\tzIndex: maxAvatars - index,\n\t\t\t\t\t\t\t\tborderColor: getAvatarBorderColor(\n\t\t\t\t\t\t\t\t\tparticipant.id\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) ) }\n\t\t\t\t\t{ overflowCount > 0 && (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName=\"comment-avatar-overflow\"\n\t\t\t\t\t\t\tstyle={ { zIndex: 0 } }\n\t\t\t\t\t\t\ttitle={ overflowTitle }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{ overflowText }\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) }\n\t\t\t\t</div>\n\t\t\t</ToolbarButton>\n\t\t</CommentIconToolbarSlotFill.Fill>\n\t);\n};\n\nexport default CommentAvatarIndicator;\n"],
5
- "mappings": "AAwGI,SAEE,KAFF;AArGJ,SAAS,qBAAqB;AAC9B,SAAS,IAAI,IAAI,eAAe;AAChC,SAAS,eAAe;AACxB,SAAS,eAAe,8BAA8B;AAKtD,OAAO,UAAU;AAKjB,SAAS,cAAc;AACvB,SAAS,4BAA4B;AAErC,MAAM,EAAE,2BAA2B,IAAI,OAAQ,sBAAuB;AAEtE,MAAM,yBAAyB,CAAE,EAAE,SAAS,QAAQ,gBAAgB,MAAO;AAC1E,QAAM,qBAAqB,QAAS,MAAM;AACzC,QAAK,CAAE,QAAS;AACf,aAAO,CAAC;AAAA,IACT;AAEA,UAAM,kBAAkB,oBAAI,IAAI;AAChC,UAAM,cAAc,CAAE,QAAQ,GAAG,OAAO,KAAM;AAG9C,gBAAY,KAAM,CAAE,GAAG,MAAO,IAAI,KAAM,EAAE,IAAK,IAAI,IAAI,KAAM,EAAE,IAAK,CAAE;AAEtE,gBAAY,QAAS,CAAE,YAAa;AAEnC,UAAK,QAAQ,eAAe,QAAQ,oBAAqB;AACxD,cAAM,YAAY,GAAI,QAAQ,MAAO,IAAK,QAAQ,WAAY;AAC9D,YAAK,CAAE,gBAAgB,IAAK,SAAU,GAAI;AACzC,0BAAgB,IAAK,WAAW;AAAA,YAC/B,MAAM,QAAQ;AAAA,YACd,QACC,QAAQ,qBAAsB,IAAK,KACnC,QAAQ,qBAAsB,IAAK;AAAA,YACpC,IAAI,QAAQ;AAAA,YACZ,qBAAqB,QAAQ,OAAO,OAAO;AAAA,YAC3C,MAAM,QAAQ;AAAA,UACf,CAAE;AAAA,QACH;AAAA,MACD;AAAA,IACD,CAAE;AAEF,WAAO,MAAM,KAAM,gBAAgB,OAAO,CAAE;AAAA,EAC7C,GAAG,CAAE,MAAO,CAAE;AAEd,QAAM,gBAAgB,QAAQ,WAAW;AAKzC,QAAM,4BACL,mBAAmB,QAAQ,SAAS,IAAI,OAAO,MAAM,UAAU;AAEhE,MAAK,CAAE,mBAAmB,QAAS;AAClC,WAAO;AAAA,EACR;AAGA,QAAM,aAAa;AACnB,QAAM,sBAAsB,mBAAmB,MAAO,GAAG,UAAW;AACpE,QAAM,gBAAgB,KAAK,IAAK,GAAG,mBAAmB,SAAS,UAAW;AAG1E,QAAM,eACL,6BAA6B,gBAAgB,IAC1C,GAAI,MAAO,IACX;AAAA;AAAA,IAEA,GAAI,KAAM;AAAA,IACV;AAAA,EACA;AAEJ,QAAM,gBACL,6BAA6B,gBAAgB,IAC1C,GAAI,mBAAoB,IACxB;AAAA;AAAA,IAEA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,IACA;AAAA,EACA;AAEJ,SACC,oBAAC,2BAA2B,MAA3B,EACA;AAAA,IAAC;AAAA;AAAA,MACA,WAAY,KAAM,4BAA4B;AAAA,QAC7C,kBAAkB;AAAA,MACnB,CAAE;AAAA,MACF,OAAQ,GAAI,YAAa;AAAA,MACzB;AAAA,MACA,aAAW;AAAA,MAEX,+BAAC,SAAI,WAAU,wBACZ;AAAA,4BAAoB,IAAK,CAAE,aAAa,UACzC;AAAA,UAAC;AAAA;AAAA,YAEA,KAAM,YAAY;AAAA,YAClB,KAAM,YAAY;AAAA,YAClB,WAAU;AAAA,YACV,OAAQ;AAAA,cACP,QAAQ,aAAa;AAAA,cACrB,aAAa;AAAA,gBACZ,YAAY;AAAA,cACb;AAAA,YACD;AAAA;AAAA,UATM,YAAY,OAAO;AAAA,QAU1B,CACC;AAAA,QACA,gBAAgB,KACjB;AAAA,UAAC;AAAA;AAAA,YACA,WAAU;AAAA,YACV,OAAQ,EAAE,QAAQ,EAAE;AAAA,YACpB,OAAQ;AAAA,YAEN;AAAA;AAAA,QACH;AAAA,SAEF;AAAA;AAAA,EACD,GACD;AAEF;AAEA,IAAO,oCAAQ;",
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { ToolbarButton } from '@wordpress/components';\nimport { __, _n, sprintf } from '@wordpress/i18n';\nimport { useMemo } from '@wordpress/element';\nimport { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from '../../lock-unlock';\nimport { getAvatarBorderColor } from './utils';\n\nconst { CommentIconToolbarSlotFill } = unlock( blockEditorPrivateApis );\n\nconst CommentAvatarIndicator = ( { onClick, thread } ) => {\n\tconst threadParticipants = useMemo( () => {\n\t\tif ( ! thread ) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst participantsMap = new Map();\n\t\tconst allComments = [ thread, ...thread.reply ];\n\n\t\t// Sort by date to show participants in chronological order.\n\t\tallComments.sort( ( a, b ) => new Date( a.date ) - new Date( b.date ) );\n\n\t\tallComments.forEach( ( comment ) => {\n\t\t\t// Track thread participants (original commenter + repliers).\n\t\t\tif ( comment.author_name && comment.author_avatar_urls ) {\n\t\t\t\tif ( ! participantsMap.has( comment.author ) ) {\n\t\t\t\t\tparticipantsMap.set( comment.author, {\n\t\t\t\t\t\tname: comment.author_name,\n\t\t\t\t\t\tavatar:\n\t\t\t\t\t\t\tcomment.author_avatar_urls?.[ '48' ] ||\n\t\t\t\t\t\t\tcomment.author_avatar_urls?.[ '96' ],\n\t\t\t\t\t\tid: comment.author,\n\t\t\t\t\t\tdate: comment.date,\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\treturn Array.from( participantsMap.values() );\n\t}, [ thread ] );\n\n\tif ( ! threadParticipants.length ) {\n\t\treturn null;\n\t}\n\n\t// Show up to 3 avatars, with overflow indicator.\n\tconst maxAvatars = 3;\n\tconst visibleParticipants = threadParticipants.slice( 0, maxAvatars );\n\tconst overflowCount = Math.max( 0, threadParticipants.length - maxAvatars );\n\tconst threadHasMoreParticipants = threadParticipants.length > 100;\n\n\t// If we hit the comment limit, show \"100+\" instead of exact overflow count.\n\tconst overflowText =\n\t\tthreadHasMoreParticipants && overflowCount > 0\n\t\t\t? __( '100+' )\n\t\t\t: sprintf(\n\t\t\t\t\t// translators: %s: Number of participants.\n\t\t\t\t\t__( '+%s' ),\n\t\t\t\t\toverflowCount\n\t\t\t );\n\n\tconst overflowTitle =\n\t\tthreadHasMoreParticipants && overflowCount > 0\n\t\t\t? __( '100+ participants' )\n\t\t\t: sprintf(\n\t\t\t\t\t// translators: %s: Number of participants.\n\t\t\t\t\t_n(\n\t\t\t\t\t\t'+%s more participant',\n\t\t\t\t\t\t'+%s more participants',\n\t\t\t\t\t\toverflowCount\n\t\t\t\t\t),\n\t\t\t\t\toverflowCount\n\t\t\t );\n\n\treturn (\n\t\t<CommentIconToolbarSlotFill.Fill>\n\t\t\t<ToolbarButton\n\t\t\t\tclassName=\"comment-avatar-indicator\"\n\t\t\t\tlabel={ __( 'View notes' ) }\n\t\t\t\tonClick={ onClick }\n\t\t\t\tshowTooltip\n\t\t\t>\n\t\t\t\t<div className=\"comment-avatar-stack\">\n\t\t\t\t\t{ visibleParticipants.map( ( participant, index ) => (\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\tkey={ participant.id }\n\t\t\t\t\t\t\tsrc={ participant.avatar }\n\t\t\t\t\t\t\talt={ participant.name }\n\t\t\t\t\t\t\tclassName=\"comment-avatar\"\n\t\t\t\t\t\t\tstyle={ {\n\t\t\t\t\t\t\t\tzIndex: maxAvatars - index,\n\t\t\t\t\t\t\t\tborderColor: getAvatarBorderColor(\n\t\t\t\t\t\t\t\t\tparticipant.id\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) ) }\n\t\t\t\t\t{ overflowCount > 0 && (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName=\"comment-avatar-overflow\"\n\t\t\t\t\t\t\tstyle={ { zIndex: 0 } }\n\t\t\t\t\t\t\ttitle={ overflowTitle }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{ overflowText }\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) }\n\t\t\t\t</div>\n\t\t\t</ToolbarButton>\n\t\t</CommentIconToolbarSlotFill.Fill>\n\t);\n};\n\nexport default CommentAvatarIndicator;\n"],
5
+ "mappings": "AAwFI,SAEE,KAFF;AArFJ,SAAS,qBAAqB;AAC9B,SAAS,IAAI,IAAI,eAAe;AAChC,SAAS,eAAe;AACxB,SAAS,eAAe,8BAA8B;AAKtD,SAAS,cAAc;AACvB,SAAS,4BAA4B;AAErC,MAAM,EAAE,2BAA2B,IAAI,OAAQ,sBAAuB;AAEtE,MAAM,yBAAyB,CAAE,EAAE,SAAS,OAAO,MAAO;AACzD,QAAM,qBAAqB,QAAS,MAAM;AACzC,QAAK,CAAE,QAAS;AACf,aAAO,CAAC;AAAA,IACT;AAEA,UAAM,kBAAkB,oBAAI,IAAI;AAChC,UAAM,cAAc,CAAE,QAAQ,GAAG,OAAO,KAAM;AAG9C,gBAAY,KAAM,CAAE,GAAG,MAAO,IAAI,KAAM,EAAE,IAAK,IAAI,IAAI,KAAM,EAAE,IAAK,CAAE;AAEtE,gBAAY,QAAS,CAAE,YAAa;AAEnC,UAAK,QAAQ,eAAe,QAAQ,oBAAqB;AACxD,YAAK,CAAE,gBAAgB,IAAK,QAAQ,MAAO,GAAI;AAC9C,0BAAgB,IAAK,QAAQ,QAAQ;AAAA,YACpC,MAAM,QAAQ;AAAA,YACd,QACC,QAAQ,qBAAsB,IAAK,KACnC,QAAQ,qBAAsB,IAAK;AAAA,YACpC,IAAI,QAAQ;AAAA,YACZ,MAAM,QAAQ;AAAA,UACf,CAAE;AAAA,QACH;AAAA,MACD;AAAA,IACD,CAAE;AAEF,WAAO,MAAM,KAAM,gBAAgB,OAAO,CAAE;AAAA,EAC7C,GAAG,CAAE,MAAO,CAAE;AAEd,MAAK,CAAE,mBAAmB,QAAS;AAClC,WAAO;AAAA,EACR;AAGA,QAAM,aAAa;AACnB,QAAM,sBAAsB,mBAAmB,MAAO,GAAG,UAAW;AACpE,QAAM,gBAAgB,KAAK,IAAK,GAAG,mBAAmB,SAAS,UAAW;AAC1E,QAAM,4BAA4B,mBAAmB,SAAS;AAG9D,QAAM,eACL,6BAA6B,gBAAgB,IAC1C,GAAI,MAAO,IACX;AAAA;AAAA,IAEA,GAAI,KAAM;AAAA,IACV;AAAA,EACA;AAEJ,QAAM,gBACL,6BAA6B,gBAAgB,IAC1C,GAAI,mBAAoB,IACxB;AAAA;AAAA,IAEA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,IACA;AAAA,EACA;AAEJ,SACC,oBAAC,2BAA2B,MAA3B,EACA;AAAA,IAAC;AAAA;AAAA,MACA,WAAU;AAAA,MACV,OAAQ,GAAI,YAAa;AAAA,MACzB;AAAA,MACA,aAAW;AAAA,MAEX,+BAAC,SAAI,WAAU,wBACZ;AAAA,4BAAoB,IAAK,CAAE,aAAa,UACzC;AAAA,UAAC;AAAA;AAAA,YAEA,KAAM,YAAY;AAAA,YAClB,KAAM,YAAY;AAAA,YAClB,WAAU;AAAA,YACV,OAAQ;AAAA,cACP,QAAQ,aAAa;AAAA,cACrB,aAAa;AAAA,gBACZ,YAAY;AAAA,cACb;AAAA,YACD;AAAA;AAAA,UATM,YAAY;AAAA,QAUnB,CACC;AAAA,QACA,gBAAgB,KACjB;AAAA,UAAC;AAAA;AAAA,YACA,WAAU;AAAA,YACV,OAAQ,EAAE,QAAQ,EAAE;AAAA,YACpB,OAAQ;AAAA,YAEN;AAAA;AAAA,QACH;AAAA,SAEF;AAAA;AAAA,EACD,GACD;AAEF;AAEA,IAAO,oCAAQ;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,12 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import clsx from "clsx";
3
- import { useState, RawHTML, useEffect, useCallback } from "@wordpress/element";
3
+ import {
4
+ useState,
5
+ RawHTML,
6
+ useEffect,
7
+ useCallback,
8
+ useMemo
9
+ } from "@wordpress/element";
4
10
  import {
5
11
  __experimentalText as Text,
6
12
  __experimentalHStack as HStack,
@@ -22,15 +28,17 @@ import {
22
28
  import { unlock } from "../../lock-unlock";
23
29
  import CommentAuthorInfo from "./comment-author-info";
24
30
  import CommentForm from "./comment-form";
25
- import { getCommentExcerpt, focusCommentThread } from "./utils";
31
+ import { focusCommentThread, getCommentExcerpt } from "./utils";
26
32
  import { useFloatingThread } from "./hooks";
33
+ import { AddComment } from "./add-comment";
27
34
  const { useBlockElement } = unlock(blockEditorPrivateApis);
28
35
  const { Menu } = unlock(componentsPrivateApis);
29
36
  function Comments({
30
- threads,
37
+ threads: noteThreads,
31
38
  onEditComment,
32
39
  onAddReply,
33
40
  onCommentDelete,
41
+ showCommentBoard,
34
42
  setShowCommentBoard,
35
43
  commentSidebarRef,
36
44
  reflowComments,
@@ -41,15 +49,48 @@ function Comments({
41
49
  const [selectedThread, setSelectedThread] = useState(null);
42
50
  const [boardOffsets, setBoardOffsets] = useState({});
43
51
  const [blockRefs, setBlockRefs] = useState({});
44
- const { blockCommentId, selectedBlockClientId } = useSelect((select) => {
52
+ const { blockCommentId, selectedBlockClientId, orderedBlockIds } = useSelect((select) => {
45
53
  const { getBlockAttributes, getSelectedBlockClientId } = select(blockEditorStore);
46
54
  const clientId = getSelectedBlockClientId();
47
55
  return {
48
56
  blockCommentId: clientId ? getBlockAttributes(clientId)?.metadata?.noteId : null,
49
- selectedBlockClientId: clientId
57
+ selectedBlockClientId: clientId,
58
+ orderedBlockIds: select(blockEditorStore).getBlockOrder()
50
59
  };
51
60
  }, []);
52
61
  const relatedBlockElement = useBlockElement(selectedBlockClientId);
62
+ const threads = useMemo(() => {
63
+ const t = [...noteThreads];
64
+ const orderedThreads = [];
65
+ if (isFloating && showCommentBoard && void 0 === blockCommentId) {
66
+ const newNoteThread = {
67
+ id: "new-note-thread",
68
+ blockClientId: selectedBlockClientId,
69
+ content: { rendered: "" }
70
+ };
71
+ orderedBlockIds.forEach((blockId) => {
72
+ if (blockId === selectedBlockClientId) {
73
+ orderedThreads.push(newNoteThread);
74
+ } else {
75
+ const threadForBlock = t.find(
76
+ (thread) => thread.blockClientId === blockId
77
+ );
78
+ if (threadForBlock) {
79
+ orderedThreads.push(threadForBlock);
80
+ }
81
+ }
82
+ });
83
+ return orderedThreads;
84
+ }
85
+ return t;
86
+ }, [
87
+ noteThreads,
88
+ isFloating,
89
+ showCommentBoard,
90
+ blockCommentId,
91
+ selectedBlockClientId,
92
+ orderedBlockIds
93
+ ]);
53
94
  const handleDelete = async (comment) => {
54
95
  const currentIndex = threads.findIndex((t) => t.id === comment.id);
55
96
  const nextThread = threads[currentIndex + 1];
@@ -152,32 +193,53 @@ function Comments({
152
193
  }, [heights, blockRefs, isFloating, threads, selectedThread]);
153
194
  const hasThreads = Array.isArray(threads) && threads.length > 0;
154
195
  if (!hasThreads && !isFloating) {
155
- return /* @__PURE__ */ jsxs(VStack, { alignment: "left", justify: "flex-start", spacing: "2", children: [
196
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
197
+ /* @__PURE__ */ jsx(
198
+ AddComment,
199
+ {
200
+ onSubmit: onAddReply,
201
+ showCommentBoard,
202
+ setShowCommentBoard,
203
+ commentSidebarRef
204
+ }
205
+ ),
156
206
  /* @__PURE__ */ jsx(Text, { as: "p", children: __("No notes available.") }),
157
207
  /* @__PURE__ */ jsx(Text, { as: "p", variant: "muted", children: __("Only logged in users can see Notes.") })
158
208
  ] });
159
209
  }
160
- return /* @__PURE__ */ jsx(VStack, { spacing: "3", children: threads.map((thread) => /* @__PURE__ */ jsx(
161
- Thread,
162
- {
163
- thread,
164
- onAddReply,
165
- onCommentDelete: handleDelete,
166
- onEditComment,
167
- isSelected: selectedThread === thread.id,
168
- setSelectedThread,
169
- setShowCommentBoard,
170
- commentSidebarRef,
171
- reflowComments,
172
- isFloating,
173
- calculatedOffset: boardOffsets[thread.id] ?? 0,
174
- setHeights,
175
- setBlockRef,
176
- selectedThread,
177
- commentLastUpdated
178
- },
179
- thread.id
180
- )) });
210
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
211
+ !isFloating && showCommentBoard && void 0 === blockCommentId && /* @__PURE__ */ jsx(
212
+ AddComment,
213
+ {
214
+ onSubmit: onAddReply,
215
+ showCommentBoard,
216
+ setShowCommentBoard,
217
+ commentSidebarRef
218
+ }
219
+ ),
220
+ threads.map((thread) => /* @__PURE__ */ jsx(
221
+ Thread,
222
+ {
223
+ thread,
224
+ onAddReply,
225
+ onCommentDelete: handleDelete,
226
+ onEditComment,
227
+ isSelected: selectedThread === thread.id,
228
+ setSelectedThread,
229
+ setShowCommentBoard,
230
+ commentSidebarRef,
231
+ reflowComments,
232
+ isFloating,
233
+ calculatedOffset: boardOffsets[thread.id] ?? 0,
234
+ setHeights,
235
+ setBlockRef,
236
+ selectedThread,
237
+ commentLastUpdated,
238
+ showCommentBoard
239
+ },
240
+ thread.id
241
+ ))
242
+ ] });
181
243
  }
182
244
  function Thread({
183
245
  thread,
@@ -194,7 +256,8 @@ function Thread({
194
256
  setBlockRef,
195
257
  setSelectedThread,
196
258
  selectedThread,
197
- commentLastUpdated
259
+ commentLastUpdated,
260
+ showCommentBoard
198
261
  }) {
199
262
  const { toggleBlockHighlight, selectBlock, toggleBlockSpotlight } = unlock(
200
263
  useDispatch(blockEditorStore)
@@ -235,7 +298,7 @@ function Thread({
235
298
  const lastReply = allReplies.length > 0 ? allReplies[allReplies.length - 1] : void 0;
236
299
  const restReplies = allReplies.length > 0 ? allReplies.slice(0, -1) : [];
237
300
  const commentExcerpt = getCommentExcerpt(
238
- stripHTML(thread.content.rendered),
301
+ stripHTML(thread.content?.rendered),
239
302
  10
240
303
  );
241
304
  const ariaLabel = !!thread.blockClientId ? sprintf(
@@ -247,6 +310,21 @@ function Thread({
247
310
  __("Original block deleted. Note: %s"),
248
311
  commentExcerpt
249
312
  );
313
+ if ("new-note-thread" === thread.id && showCommentBoard && isFloating) {
314
+ return /* @__PURE__ */ jsx(
315
+ AddComment,
316
+ {
317
+ onSubmit: onAddReply,
318
+ showCommentBoard,
319
+ setShowCommentBoard,
320
+ commentSidebarRef,
321
+ reflowComments,
322
+ isFloating,
323
+ y,
324
+ refs
325
+ }
326
+ );
327
+ }
250
328
  return (
251
329
  // Disable reason: role="listitem" does in fact support aria-expanded.
252
330
  // eslint-disable-next-line jsx-a11y/role-supports-aria-props
@@ -265,6 +343,9 @@ function Thread({
265
343
  onFocus: onMouseEnter,
266
344
  onBlur: onMouseLeave,
267
345
  onKeyDown: (event) => {
346
+ if (event.defaultPrevented) {
347
+ return;
348
+ }
268
349
  if (event.key === "Enter" && event.currentTarget === event.target) {
269
350
  if (isSelected) {
270
351
  unselectThread();
@@ -593,7 +674,9 @@ const CommentBoard = ({
593
674
  onConfirm: handleConfirmDelete,
594
675
  onCancel: handleCancel,
595
676
  confirmButtonText: __("Delete"),
596
- children: __("Are you sure you want to delete this note?")
677
+ children: __(
678
+ "Are you sure you want to delete this note? This will also delete all of this note's replies."
679
+ )
597
680
  }
598
681
  )
599
682
  ] });