@wordpress/block-library 7.3.0 → 7.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/archives/edit.js +1 -1
  3. package/build/archives/edit.js.map +1 -1
  4. package/build/audio/edit.js +2 -2
  5. package/build/audio/edit.js.map +1 -1
  6. package/build/audio/edit.native.js +1 -1
  7. package/build/audio/edit.native.js.map +1 -1
  8. package/build/categories/edit.js +8 -3
  9. package/build/categories/edit.js.map +1 -1
  10. package/build/categories/index.js +4 -0
  11. package/build/categories/index.js.map +1 -1
  12. package/build/column/index.js +10 -0
  13. package/build/column/index.js.map +1 -1
  14. package/build/comment-template/edit.js +3 -1
  15. package/build/comment-template/edit.js.map +1 -1
  16. package/build/comment-template/hooks.js +14 -4
  17. package/build/comment-template/hooks.js.map +1 -1
  18. package/build/comments-pagination/edit.js +18 -1
  19. package/build/comments-pagination/edit.js.map +1 -1
  20. package/build/comments-query-loop/edit.js +1 -1
  21. package/build/comments-query-loop/edit.js.map +1 -1
  22. package/build/comments-title/edit.js +149 -0
  23. package/build/comments-title/edit.js.map +1 -0
  24. package/build/comments-title/index.js +101 -0
  25. package/build/comments-title/index.js.map +1 -0
  26. package/build/cover/transforms.js +33 -32
  27. package/build/cover/transforms.js.map +1 -1
  28. package/build/embed/edit.js +12 -18
  29. package/build/embed/edit.js.map +1 -1
  30. package/build/embed/edit.native.js +1 -7
  31. package/build/embed/edit.native.js.map +1 -1
  32. package/build/embed/util.js +29 -4
  33. package/build/embed/util.js.map +1 -1
  34. package/build/file/inspector.js +2 -4
  35. package/build/file/inspector.js.map +1 -1
  36. package/build/gallery/edit.js +1 -1
  37. package/build/gallery/edit.js.map +1 -1
  38. package/build/gallery/v1/edit.js +1 -1
  39. package/build/gallery/v1/edit.js.map +1 -1
  40. package/build/html/edit.js +2 -2
  41. package/build/html/edit.js.map +1 -1
  42. package/build/image/edit.js +4 -6
  43. package/build/image/edit.js.map +1 -1
  44. package/build/image/edit.native.js +1 -1
  45. package/build/image/edit.native.js.map +1 -1
  46. package/build/image/image.js +1 -1
  47. package/build/image/image.js.map +1 -1
  48. package/build/index.js +5 -3
  49. package/build/index.js.map +1 -1
  50. package/build/index.native.js +14 -3
  51. package/build/index.native.js.map +1 -1
  52. package/build/latest-comments/edit.js +1 -1
  53. package/build/latest-comments/edit.js.map +1 -1
  54. package/build/list/index.js +13 -2
  55. package/build/list/index.js.map +1 -1
  56. package/build/loginout/edit.js +1 -1
  57. package/build/loginout/edit.js.map +1 -1
  58. package/build/media-text/edit.js +1 -2
  59. package/build/media-text/edit.js.map +1 -1
  60. package/build/media-text/edit.native.js +1 -1
  61. package/build/media-text/edit.native.js.map +1 -1
  62. package/build/navigation/edit/index.js +17 -1
  63. package/build/navigation/edit/index.js.map +1 -1
  64. package/build/navigation/edit/navigation-menu-selector.js +7 -2
  65. package/build/navigation/edit/navigation-menu-selector.js.map +1 -1
  66. package/build/navigation/edit/unsaved-inner-blocks.js +5 -4
  67. package/build/navigation/edit/unsaved-inner-blocks.js.map +1 -1
  68. package/build/navigation/index.js +1 -1
  69. package/build/navigation/view-modal.js +37 -0
  70. package/build/navigation/view-modal.js.map +1 -0
  71. package/build/navigation/view.js +1 -34
  72. package/build/navigation/view.js.map +1 -1
  73. package/build/paragraph/edit.native.js +6 -2
  74. package/build/paragraph/edit.native.js.map +1 -1
  75. package/build/post-author/edit.js +1 -1
  76. package/build/post-author/edit.js.map +1 -1
  77. package/build/post-comments/index.js +4 -3
  78. package/build/post-comments/index.js.map +1 -1
  79. package/build/post-excerpt/edit.js +1 -1
  80. package/build/post-excerpt/edit.js.map +1 -1
  81. package/build/post-featured-image/edit.js +19 -7
  82. package/build/post-featured-image/edit.js.map +1 -1
  83. package/build/query/edit/index.js +84 -22
  84. package/build/query/edit/index.js.map +1 -1
  85. package/build/query/edit/query-placeholder.js +7 -14
  86. package/build/query/edit/query-placeholder.js.map +1 -1
  87. package/build/query/edit/query-toolbar.js +6 -1
  88. package/build/query/edit/query-toolbar.js.map +1 -1
  89. package/build/quote/index.js +19 -2
  90. package/build/quote/index.js.map +1 -1
  91. package/build/quote/v2/edit.js +11 -3
  92. package/build/quote/v2/edit.js.map +1 -1
  93. package/build/rss/edit.js +1 -1
  94. package/build/rss/edit.js.map +1 -1
  95. package/build/search/edit.js +11 -9
  96. package/build/search/edit.js.map +1 -1
  97. package/build/spacer/constants.js +9 -0
  98. package/build/spacer/constants.js.map +1 -0
  99. package/build/spacer/controls.js +3 -3
  100. package/build/spacer/controls.js.map +1 -1
  101. package/build/spacer/controls.native.js +2 -2
  102. package/build/spacer/controls.native.js.map +1 -1
  103. package/build/spacer/edit.js +5 -6
  104. package/build/spacer/edit.js.map +1 -1
  105. package/build/table/edit.js +8 -2
  106. package/build/table/edit.js.map +1 -1
  107. package/build/tag-cloud/edit.js +1 -1
  108. package/build/tag-cloud/edit.js.map +1 -1
  109. package/build/video/edit.js +1 -1
  110. package/build/video/edit.js.map +1 -1
  111. package/build/video/edit.native.js +1 -1
  112. package/build/video/edit.native.js.map +1 -1
  113. package/build-module/archives/edit.js +1 -1
  114. package/build-module/archives/edit.js.map +1 -1
  115. package/build-module/audio/edit.js +2 -2
  116. package/build-module/audio/edit.js.map +1 -1
  117. package/build-module/audio/edit.native.js +1 -1
  118. package/build-module/audio/edit.native.js.map +1 -1
  119. package/build-module/categories/edit.js +8 -3
  120. package/build-module/categories/edit.js.map +1 -1
  121. package/build-module/categories/index.js +4 -0
  122. package/build-module/categories/index.js.map +1 -1
  123. package/build-module/column/index.js +10 -0
  124. package/build-module/column/index.js.map +1 -1
  125. package/build-module/comment-template/edit.js +3 -1
  126. package/build-module/comment-template/edit.js.map +1 -1
  127. package/build-module/comment-template/hooks.js +14 -4
  128. package/build-module/comment-template/hooks.js.map +1 -1
  129. package/build-module/comments-pagination/edit.js +19 -2
  130. package/build-module/comments-pagination/edit.js.map +1 -1
  131. package/build-module/comments-query-loop/edit.js +1 -1
  132. package/build-module/comments-query-loop/edit.js.map +1 -1
  133. package/build-module/comments-title/edit.js +133 -0
  134. package/build-module/comments-title/edit.js.map +1 -0
  135. package/build-module/comments-title/index.js +88 -0
  136. package/build-module/comments-title/index.js.map +1 -0
  137. package/build-module/cover/transforms.js +33 -32
  138. package/build-module/cover/transforms.js.map +1 -1
  139. package/build-module/embed/edit.js +13 -19
  140. package/build-module/embed/edit.js.map +1 -1
  141. package/build-module/embed/edit.native.js +2 -8
  142. package/build-module/embed/edit.native.js.map +1 -1
  143. package/build-module/embed/util.js +25 -3
  144. package/build-module/embed/util.js.map +1 -1
  145. package/build-module/file/inspector.js +2 -4
  146. package/build-module/file/inspector.js.map +1 -1
  147. package/build-module/gallery/edit.js +1 -1
  148. package/build-module/gallery/edit.js.map +1 -1
  149. package/build-module/gallery/v1/edit.js +1 -1
  150. package/build-module/gallery/v1/edit.js.map +1 -1
  151. package/build-module/html/edit.js +2 -2
  152. package/build-module/html/edit.js.map +1 -1
  153. package/build-module/image/edit.js +4 -6
  154. package/build-module/image/edit.js.map +1 -1
  155. package/build-module/image/edit.native.js +1 -1
  156. package/build-module/image/edit.native.js.map +1 -1
  157. package/build-module/image/image.js +1 -1
  158. package/build-module/image/image.js.map +1 -1
  159. package/build-module/index.js +4 -3
  160. package/build-module/index.js.map +1 -1
  161. package/build-module/index.native.js +14 -3
  162. package/build-module/index.native.js.map +1 -1
  163. package/build-module/latest-comments/edit.js +1 -1
  164. package/build-module/latest-comments/edit.js.map +1 -1
  165. package/build-module/list/index.js +9 -3
  166. package/build-module/list/index.js.map +1 -1
  167. package/build-module/loginout/edit.js +1 -1
  168. package/build-module/loginout/edit.js.map +1 -1
  169. package/build-module/media-text/edit.js +1 -2
  170. package/build-module/media-text/edit.js.map +1 -1
  171. package/build-module/media-text/edit.native.js +1 -1
  172. package/build-module/media-text/edit.native.js.map +1 -1
  173. package/build-module/navigation/edit/index.js +17 -1
  174. package/build-module/navigation/edit/index.js.map +1 -1
  175. package/build-module/navigation/edit/navigation-menu-selector.js +6 -2
  176. package/build-module/navigation/edit/navigation-menu-selector.js.map +1 -1
  177. package/build-module/navigation/edit/unsaved-inner-blocks.js +5 -4
  178. package/build-module/navigation/edit/unsaved-inner-blocks.js.map +1 -1
  179. package/build-module/navigation/index.js +1 -1
  180. package/build-module/navigation/view-modal.js +32 -0
  181. package/build-module/navigation/view-modal.js.map +1 -0
  182. package/build-module/navigation/view.js +1 -30
  183. package/build-module/navigation/view.js.map +1 -1
  184. package/build-module/paragraph/edit.native.js +6 -2
  185. package/build-module/paragraph/edit.native.js.map +1 -1
  186. package/build-module/post-author/edit.js +1 -1
  187. package/build-module/post-author/edit.js.map +1 -1
  188. package/build-module/post-comments/index.js +4 -3
  189. package/build-module/post-comments/index.js.map +1 -1
  190. package/build-module/post-excerpt/edit.js +1 -1
  191. package/build-module/post-excerpt/edit.js.map +1 -1
  192. package/build-module/post-featured-image/edit.js +19 -7
  193. package/build-module/post-featured-image/edit.js.map +1 -1
  194. package/build-module/query/edit/index.js +87 -26
  195. package/build-module/query/edit/index.js.map +1 -1
  196. package/build-module/query/edit/query-placeholder.js +8 -15
  197. package/build-module/query/edit/query-placeholder.js.map +1 -1
  198. package/build-module/query/edit/query-toolbar.js +6 -1
  199. package/build-module/query/edit/query-toolbar.js.map +1 -1
  200. package/build-module/quote/index.js +10 -4
  201. package/build-module/quote/index.js.map +1 -1
  202. package/build-module/quote/v2/edit.js +10 -3
  203. package/build-module/quote/v2/edit.js.map +1 -1
  204. package/build-module/rss/edit.js +1 -1
  205. package/build-module/rss/edit.js.map +1 -1
  206. package/build-module/search/edit.js +11 -9
  207. package/build-module/search/edit.js.map +1 -1
  208. package/build-module/spacer/constants.js +2 -0
  209. package/build-module/spacer/constants.js.map +1 -0
  210. package/build-module/spacer/controls.js +2 -2
  211. package/build-module/spacer/controls.js.map +1 -1
  212. package/build-module/spacer/controls.native.js +1 -1
  213. package/build-module/spacer/controls.native.js.map +1 -1
  214. package/build-module/spacer/edit.js +1 -1
  215. package/build-module/spacer/edit.js.map +1 -1
  216. package/build-module/table/edit.js +9 -3
  217. package/build-module/table/edit.js.map +1 -1
  218. package/build-module/tag-cloud/edit.js +1 -1
  219. package/build-module/tag-cloud/edit.js.map +1 -1
  220. package/build-module/video/edit.js +1 -1
  221. package/build-module/video/edit.js.map +1 -1
  222. package/build-module/video/edit.native.js +1 -1
  223. package/build-module/video/edit.native.js.map +1 -1
  224. package/build-style/comments-title/editor-rtl.css +79 -0
  225. package/build-style/comments-title/editor.css +79 -0
  226. package/build-style/common-rtl.css +32 -0
  227. package/build-style/common.css +32 -0
  228. package/build-style/editor-rtl.css +51 -0
  229. package/build-style/editor.css +51 -0
  230. package/build-style/post-comments-form/style-rtl.css +9 -0
  231. package/build-style/post-comments-form/style.css +9 -0
  232. package/build-style/query/editor-rtl.css +39 -0
  233. package/build-style/query/editor.css +39 -0
  234. package/build-style/style-rtl.css +79 -0
  235. package/build-style/style.css +79 -0
  236. package/build-style/table/editor-rtl.css +8 -0
  237. package/build-style/table/editor.css +8 -0
  238. package/build-style/table/style-rtl.css +38 -0
  239. package/build-style/table/style.css +38 -0
  240. package/package.json +28 -28
  241. package/src/archives/edit.js +1 -1
  242. package/src/audio/edit.js +2 -2
  243. package/src/audio/edit.native.js +1 -1
  244. package/src/categories/block.json +4 -0
  245. package/src/categories/edit.js +8 -2
  246. package/src/categories/index.php +1 -0
  247. package/src/column/block.json +10 -0
  248. package/src/comment-template/edit.js +5 -2
  249. package/src/comment-template/hooks.js +15 -2
  250. package/src/comment-template/index.php +23 -2
  251. package/src/comments-pagination/edit.js +23 -0
  252. package/src/comments-query-loop/edit.js +1 -0
  253. package/src/comments-title/block.json +70 -0
  254. package/src/comments-title/edit.js +197 -0
  255. package/src/comments-title/editor.scss +4 -0
  256. package/src/comments-title/index.js +18 -0
  257. package/src/comments-title/index.php +68 -0
  258. package/src/common.scss +24 -1
  259. package/src/cover/transforms.js +51 -28
  260. package/src/editor.scss +1 -0
  261. package/src/embed/edit.js +19 -24
  262. package/src/embed/edit.native.js +9 -14
  263. package/src/embed/util.js +34 -2
  264. package/src/file/inspector.js +1 -3
  265. package/src/gallery/edit.js +1 -1
  266. package/src/gallery/v1/edit.js +1 -1
  267. package/src/html/edit.js +2 -2
  268. package/src/image/edit.js +2 -4
  269. package/src/image/edit.native.js +1 -1
  270. package/src/image/image.js +1 -1
  271. package/src/index.js +7 -1
  272. package/src/index.native.js +12 -2
  273. package/src/latest-comments/edit.js +1 -1
  274. package/src/list/index.js +7 -3
  275. package/src/loginout/edit.js +1 -1
  276. package/src/media-text/edit.js +1 -2
  277. package/src/media-text/edit.native.js +1 -1
  278. package/src/navigation/block.json +1 -1
  279. package/src/navigation/edit/index.js +24 -0
  280. package/src/navigation/edit/navigation-menu-selector.js +15 -9
  281. package/src/navigation/edit/unsaved-inner-blocks.js +5 -4
  282. package/src/navigation/index.php +5 -0
  283. package/src/navigation/view-modal.js +36 -0
  284. package/src/navigation/view.js +0 -35
  285. package/src/paragraph/edit.native.js +13 -1
  286. package/src/post-author/edit.js +1 -1
  287. package/src/post-comments/block.json +4 -3
  288. package/src/post-comments-form/index.php +12 -4
  289. package/src/post-comments-form/style.scss +11 -0
  290. package/src/post-excerpt/edit.js +1 -1
  291. package/src/post-featured-image/edit.js +24 -12
  292. package/src/query/edit/index.js +125 -26
  293. package/src/query/edit/query-placeholder.js +3 -13
  294. package/src/query/edit/query-toolbar.js +6 -0
  295. package/src/query/editor.scss +38 -0
  296. package/src/quote/index.js +8 -4
  297. package/src/quote/v2/edit.js +3 -0
  298. package/src/rss/edit.js +1 -1
  299. package/src/search/edit.js +13 -7
  300. package/src/search/index.php +84 -33
  301. package/src/spacer/constants.js +1 -0
  302. package/src/spacer/controls.js +2 -2
  303. package/src/spacer/controls.native.js +1 -1
  304. package/src/spacer/edit.js +1 -2
  305. package/src/table/edit.js +11 -2
  306. package/src/table/editor.scss +13 -0
  307. package/src/table/style.scss +52 -0
  308. package/src/tag-cloud/edit.js +1 -1
  309. package/src/video/edit.js +1 -1
  310. package/src/video/edit.native.js +1 -1
@@ -0,0 +1,197 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import classnames from 'classnames';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import {
10
+ AlignmentControl,
11
+ BlockControls,
12
+ useBlockProps,
13
+ PlainText,
14
+ InspectorControls,
15
+ } from '@wordpress/block-editor';
16
+ import { __ } from '@wordpress/i18n';
17
+ import { useEntityProp } from '@wordpress/core-data';
18
+ import {
19
+ PanelBody,
20
+ ToggleControl,
21
+ __experimentalToggleGroupControl as ToggleGroupControl,
22
+ __experimentalToggleGroupControlOption as ToggleGroupControlOption,
23
+ } from '@wordpress/components';
24
+ import { useState, useEffect } from '@wordpress/element';
25
+ import apiFetch from '@wordpress/api-fetch';
26
+ import { addQueryArgs } from '@wordpress/url';
27
+
28
+ /**
29
+ * Internal dependencies
30
+ */
31
+ import HeadingLevelDropdown from '../heading/heading-level-dropdown';
32
+
33
+ export default function Edit( {
34
+ attributes: {
35
+ textAlign,
36
+ singleCommentLabel,
37
+ multipleCommentsLabel,
38
+ showPostTitle,
39
+ showCommentsCount,
40
+ level,
41
+ },
42
+ setAttributes,
43
+ context: { postType, postId },
44
+ } ) {
45
+ const TagName = 'h' + level;
46
+ const [ commentsCount, setCommentsCount ] = useState();
47
+ const [ editingMode, setEditingMode ] = useState( 'plural' );
48
+ const [ rawTitle ] = useEntityProp( 'postType', postType, 'title', postId );
49
+ const isSiteEditor = typeof postId === 'undefined';
50
+ const blockProps = useBlockProps( {
51
+ className: classnames( {
52
+ [ `has-text-align-${ textAlign }` ]: textAlign,
53
+ } ),
54
+ } );
55
+
56
+ useEffect( () => {
57
+ if ( isSiteEditor ) {
58
+ setCommentsCount( 3 );
59
+ return;
60
+ }
61
+ const currentPostId = postId;
62
+ apiFetch( {
63
+ path: addQueryArgs( '/wp/v2/comments', {
64
+ post: postId,
65
+ _fields: 'id',
66
+ } ),
67
+ method: 'HEAD',
68
+ parse: false,
69
+ } )
70
+ .then( ( res ) => {
71
+ // Stale requests will have the `currentPostId` of an older closure.
72
+ if ( currentPostId === postId ) {
73
+ setCommentsCount(
74
+ parseInt( res.headers.get( 'X-WP-Total' ) )
75
+ );
76
+ }
77
+ } )
78
+ .catch( () => {
79
+ setCommentsCount( 0 );
80
+ } );
81
+ }, [ postId ] );
82
+
83
+ const blockControls = (
84
+ <BlockControls group="block">
85
+ <AlignmentControl
86
+ value={ textAlign }
87
+ onChange={ ( newAlign ) =>
88
+ setAttributes( { textAlign: newAlign } )
89
+ }
90
+ />
91
+ <HeadingLevelDropdown
92
+ selectedLevel={ level }
93
+ onChange={ ( newLevel ) =>
94
+ setAttributes( { level: newLevel } )
95
+ }
96
+ />
97
+ </BlockControls>
98
+ );
99
+
100
+ const inspectorControls = (
101
+ <InspectorControls>
102
+ <PanelBody title={ __( 'Settings' ) }>
103
+ { isSiteEditor && (
104
+ <ToggleGroupControl
105
+ label={ __( 'Editing mode' ) }
106
+ onChange={ setEditingMode }
107
+ value={ editingMode }
108
+ >
109
+ <ToggleGroupControlOption
110
+ label={ __( 'Singular' ) }
111
+ value="singular"
112
+ />
113
+ <ToggleGroupControlOption
114
+ label={ __( 'Plural' ) }
115
+ value="plural"
116
+ />
117
+ </ToggleGroupControl>
118
+ ) }
119
+ <ToggleControl
120
+ label={ __( 'Show post title' ) }
121
+ checked={ showPostTitle }
122
+ onChange={ ( value ) =>
123
+ setAttributes( { showPostTitle: value } )
124
+ }
125
+ />
126
+ <ToggleControl
127
+ label={ __( 'Show comments count' ) }
128
+ checked={ showCommentsCount }
129
+ onChange={ ( value ) =>
130
+ setAttributes( { showCommentsCount: value } )
131
+ }
132
+ />
133
+ </PanelBody>
134
+ </InspectorControls>
135
+ );
136
+
137
+ const postTitle = isSiteEditor ? __( '"Post Title"' ) : `"${ rawTitle }"`;
138
+
139
+ const singlePlaceholder = showPostTitle
140
+ ? __( 'One response to ' )
141
+ : __( 'One response' );
142
+
143
+ const multiplePlaceholder = showPostTitle
144
+ ? __( 'Responses to ' )
145
+ : __( 'Responses' );
146
+
147
+ return (
148
+ <>
149
+ { blockControls }
150
+ { inspectorControls }
151
+ <TagName { ...blockProps }>
152
+ { editingMode === 'singular' || commentsCount === 1 ? (
153
+ <>
154
+ <PlainText
155
+ __experimentalVersion={ 2 }
156
+ tagName="span"
157
+ aria-label={ singlePlaceholder }
158
+ placeholder={ singlePlaceholder }
159
+ value={ singleCommentLabel }
160
+ onChange={ ( newLabel ) =>
161
+ setAttributes( {
162
+ singleCommentLabel: newLabel,
163
+ } )
164
+ }
165
+ />
166
+ { showPostTitle ? postTitle : null }
167
+ </>
168
+ ) : (
169
+ <>
170
+ { showCommentsCount ? commentsCount : null }
171
+ <PlainText
172
+ __experimentalVersion={ 2 }
173
+ tagName="span"
174
+ aria-label={
175
+ showCommentsCount
176
+ ? ` ${ multiplePlaceholder }`
177
+ : multiplePlaceholder
178
+ }
179
+ placeholder={
180
+ showCommentsCount
181
+ ? ` ${ multiplePlaceholder }`
182
+ : multiplePlaceholder
183
+ }
184
+ value={ multipleCommentsLabel }
185
+ onChange={ ( newLabel ) =>
186
+ setAttributes( {
187
+ multipleCommentsLabel: newLabel,
188
+ } )
189
+ }
190
+ />
191
+ { showPostTitle ? postTitle : null }
192
+ </>
193
+ ) }
194
+ </TagName>
195
+ </>
196
+ );
197
+ }
@@ -0,0 +1,4 @@
1
+
2
+ .wp-block-comments-title.has-background {
3
+ padding: inherit;
4
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { commentTitle as icon } from '@wordpress/icons';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import metadata from './block.json';
10
+ import edit from './edit';
11
+
12
+ const { name } = metadata;
13
+ export { metadata, name };
14
+
15
+ export const settings = {
16
+ icon,
17
+ edit,
18
+ };
@@ -0,0 +1,68 @@
1
+ <?php
2
+ /**
3
+ * Server-side rendering of the `core/comments-title` block.
4
+ *
5
+ * @package WordPress
6
+ */
7
+
8
+ /**
9
+ * Renders the `core/comments-title` block on the server.
10
+ *
11
+ * @param array $attributes Block attributes.
12
+ *
13
+ * @return string Return the post comments title.
14
+ */
15
+ function render_block_core_comments_title( $attributes ) {
16
+
17
+ $align_class_name = empty( $attributes['textAlign'] ) ? '' : "has-text-align-{$attributes['textAlign']}";
18
+ $show_post_title = ! empty( $attributes['showPostTitle'] ) && $attributes['showPostTitle'];
19
+ $show_comments_count = ! empty( $attributes['showCommentsCount'] ) && $attributes['showCommentsCount'];
20
+ $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $align_class_name ) );
21
+ $post_title = $show_post_title ? sprintf( '"%1$s"', get_the_title() ) : null;
22
+ $comments_count = number_format_i18n( get_comments_number() );
23
+ $tag_name = 'h2';
24
+ if ( isset( $attributes['level'] ) ) {
25
+ $tag_name = 'h' . $attributes['level'];
26
+ }
27
+
28
+ if ( '0' === $comments_count ) {
29
+ return;
30
+ }
31
+
32
+ $single_default_comment_label = $show_post_title ? __( 'One response to' ) : __( 'One response' );
33
+ $single_comment_label = ! empty( $attributes['singleCommentLabel'] ) ? $attributes['singleCommentLabel'] : $single_default_comment_label;
34
+
35
+ $multiple_default_comment_label = $show_post_title ? __( 'Responses to' ) : __( 'Responses' );
36
+ $multiple_comment_label = ! empty( $attributes['multipleCommentsLabel'] ) ? $attributes['multipleCommentsLabel'] : $multiple_default_comment_label;
37
+
38
+ $comments_title = '%1$s %2$s %3$s';
39
+
40
+ $comments_title = sprintf(
41
+ $comments_title,
42
+ // If there is only one comment, only display the label.
43
+ '1' !== $comments_count && $show_comments_count ? $comments_count : null,
44
+ '1' === $comments_count ? $single_comment_label : $multiple_comment_label,
45
+ $post_title
46
+ );
47
+
48
+ return sprintf(
49
+ '<%1$s id="comments" %2$s>%3$s</%1$s>',
50
+ $tag_name,
51
+ $wrapper_attributes,
52
+ $comments_title
53
+ );
54
+ }
55
+
56
+ /**
57
+ * Registers the `core/comments-title` block on the server.
58
+ */
59
+ function register_block_core_comments_title() {
60
+ register_block_type_from_metadata(
61
+ __DIR__ . '/comments-title',
62
+ array(
63
+ 'render_callback' => 'render_block_core_comments_title',
64
+ )
65
+ );
66
+ }
67
+
68
+ add_action( 'init', 'register_block_core_comments_title' );
package/src/common.scss CHANGED
@@ -116,11 +116,34 @@
116
116
  html :where(.has-border-color) {
117
117
  border-style: solid;
118
118
  }
119
+ html :where([style*="border-top-color"]) {
120
+ border-top-style: solid;
121
+ }
122
+ html :where([style*="border-right-color"]) {
123
+ border-right-style: solid;
124
+ }
125
+ html :where([style*="border-bottom-color"]) {
126
+ border-bottom-style: solid;
127
+ }
128
+ html :where([style*="border-left-color"]) {
129
+ border-left-style: solid;
130
+ }
119
131
 
120
132
  html :where([style*="border-width"]) {
121
133
  border-style: solid;
122
134
  }
123
-
135
+ html :where([style*="border-top-width"]) {
136
+ border-top-style: solid;
137
+ }
138
+ html :where([style*="border-right-width"]) {
139
+ border-right-style: solid;
140
+ }
141
+ html :where([style*="border-bottom-width"]) {
142
+ border-bottom-style: solid;
143
+ }
144
+ html :where([style*="border-left-width"]) {
145
+ border-left-style: solid;
146
+ }
124
147
 
125
148
  /**
126
149
  * Provide baseline responsiveness for images.
@@ -64,37 +64,60 @@ const transforms = {
64
64
  {
65
65
  type: 'block',
66
66
  blocks: [ 'core/group' ],
67
- isMatch: ( { backgroundColor, gradient, style } ) => {
68
- /*
69
- * Make this transformation available only if the Group has background
70
- * or gradient set, because otherwise `Cover` block displays a Placeholder.
71
- *
72
- * This helps avoid arbitrary decisions about the Cover block's background
73
- * and user confusion about the existence of previous content.
74
- */
75
- return (
67
+ transform: ( attributes, innerBlocks ) => {
68
+ const {
69
+ align,
70
+ anchor,
71
+ backgroundColor,
72
+ gradient,
73
+ style,
74
+ } = attributes;
75
+
76
+ // If no background or gradient color is provided, default to 50% opacity.
77
+ // This matches the styling of a Cover block with a background image,
78
+ // in the state where a background image has been removed.
79
+ const dimRatio =
76
80
  backgroundColor ||
81
+ gradient ||
77
82
  style?.color?.background ||
78
- style?.color?.gradient ||
79
- gradient
80
- );
81
- },
82
- transform: (
83
- { align, anchor, backgroundColor, gradient, style },
84
- innerBlocks
85
- ) => {
86
- return createBlock(
87
- 'core/cover',
88
- {
89
- align,
90
- anchor,
91
- overlayColor: backgroundColor,
92
- customOverlayColor: style?.color?.background,
93
- gradient,
94
- customGradient: style?.color?.gradient,
83
+ style?.color?.gradient
84
+ ? undefined
85
+ : 50;
86
+
87
+ // Move the background or gradient color to the parent Cover block.
88
+ const parentAttributes = {
89
+ align,
90
+ anchor,
91
+ dimRatio,
92
+ overlayColor: backgroundColor,
93
+ customOverlayColor: style?.color?.background,
94
+ gradient,
95
+ customGradient: style?.color?.gradient,
96
+ };
97
+
98
+ const attributesWithoutBackgroundColors = {
99
+ ...attributes,
100
+ backgroundColor: undefined,
101
+ gradient: undefined,
102
+ style: {
103
+ ...attributes?.style,
104
+ color: {
105
+ ...attributes?.style?.color,
106
+ background: undefined,
107
+ gradient: undefined,
108
+ },
95
109
  },
96
- innerBlocks
97
- );
110
+ };
111
+
112
+ // Preserve the block by nesting it within the Cover block,
113
+ // instead of converting the Group block directly to the Cover block.
114
+ return createBlock( 'core/cover', parentAttributes, [
115
+ createBlock(
116
+ 'core/group',
117
+ attributesWithoutBackgroundColors,
118
+ innerBlocks
119
+ ),
120
+ ] );
98
121
  },
99
122
  },
100
123
  ],
package/src/editor.scss CHANGED
@@ -10,6 +10,7 @@
10
10
  @import "./comments-query-loop/editor.scss";
11
11
  @import "./comments-pagination/editor.scss";
12
12
  @import "./comments-pagination-numbers/editor.scss";
13
+ @import "./comments-title/editor.scss";
13
14
  @import "./cover/editor.scss";
14
15
  @import "./embed/editor.scss";
15
16
  @import "./file/editor.scss";
package/src/embed/edit.js CHANGED
@@ -5,8 +5,8 @@ import {
5
5
  createUpgradedEmbedBlock,
6
6
  getClassNames,
7
7
  fallback,
8
- getAttributesFromPreview,
9
8
  getEmbedInfoByProvider,
9
+ getMergedAttributesWithPreview,
10
10
  } from './util';
11
11
  import EmbedControls from './embed-controls';
12
12
  import { embedContentIcon } from './icons';
@@ -99,21 +99,19 @@ const EmbedEdit = ( props ) => {
99
99
  );
100
100
 
101
101
  /**
102
- * @return {Object} Attributes derived from the preview, merged with the current attributes.
102
+ * Returns the attributes derived from the preview, merged with the current attributes.
103
+ *
104
+ * @param {boolean} ignorePreviousClassName Determines if the previous className attribute should be ignored when merging.
105
+ * @return {Object} Merged attributes.
103
106
  */
104
- const getMergedAttributes = () => {
105
- const { allowResponsive, className } = attributes;
106
- return {
107
- ...attributes,
108
- ...getAttributesFromPreview(
109
- preview,
110
- title,
111
- className,
112
- responsive,
113
- allowResponsive
114
- ),
115
- };
116
- };
107
+ const getMergedAttributes = ( ignorePreviousClassName = false ) =>
108
+ getMergedAttributesWithPreview(
109
+ attributes,
110
+ preview,
111
+ title,
112
+ responsive,
113
+ ignorePreviousClassName
114
+ );
117
115
 
118
116
  const toggleResponsive = () => {
119
117
  const { allowResponsive, className } = attributes;
@@ -145,15 +143,12 @@ const EmbedEdit = ( props ) => {
145
143
  // Handle incoming preview.
146
144
  useEffect( () => {
147
145
  if ( preview && ! isEditingURL ) {
148
- // Even though we set attributes that get derived from the preview,
149
- // we don't access them directly because for the initial render,
150
- // the `setAttributes` call will not have taken effect. If we're
151
- // rendering responsive content, setting the responsive classes
152
- // after the preview has been rendered can result in unwanted
153
- // clipping or scrollbars. The `getAttributesFromPreview` function
154
- // that `getMergedAttributes` uses is memoized so that we're not
155
- // calculating them on every render.
156
- setAttributes( getMergedAttributes() );
146
+ // When obtaining an incoming preview, we set the attributes derived from
147
+ // the preview data. In this case when getting the merged attributes,
148
+ // we ignore the previous classname because it might not match the expected
149
+ // classes by the new preview.
150
+ setAttributes( getMergedAttributes( true ) );
151
+
157
152
  if ( onReplace ) {
158
153
  const upgradedBlock = createUpgradedEmbedBlock(
159
154
  props,
@@ -5,8 +5,8 @@ import {
5
5
  createUpgradedEmbedBlock,
6
6
  getClassNames,
7
7
  fallback,
8
- getAttributesFromPreview,
9
8
  getEmbedInfoByProvider,
9
+ getMergedAttributesWithPreview,
10
10
  } from './util';
11
11
  import EmbedControls from './embed-controls';
12
12
  import { embedContentIcon } from './icons';
@@ -130,19 +130,14 @@ const EmbedEdit = ( props ) => {
130
130
  * @param {boolean} ignorePreviousClassName Determines if the previous className attribute should be ignored when merging.
131
131
  * @return {Object} Merged attributes.
132
132
  */
133
- const getMergedAttributes = ( ignorePreviousClassName = false ) => {
134
- const { allowResponsive, className } = attributes;
135
- return {
136
- ...attributes,
137
- ...getAttributesFromPreview(
138
- preview,
139
- title,
140
- ignorePreviousClassName ? undefined : className,
141
- responsive,
142
- allowResponsive
143
- ),
144
- };
145
- };
133
+ const getMergedAttributes = ( ignorePreviousClassName = false ) =>
134
+ getMergedAttributesWithPreview(
135
+ attributes,
136
+ preview,
137
+ title,
138
+ responsive,
139
+ ignorePreviousClassName
140
+ );
146
141
 
147
142
  const toggleResponsive = () => {
148
143
  const { allowResponsive, className } = attributes;
package/src/embed/util.js CHANGED
@@ -66,9 +66,11 @@ export const isFromWordPress = ( html ) =>
66
66
  html && html.includes( 'class="wp-embedded-content"' );
67
67
 
68
68
  export const getPhotoHtml = ( photo ) => {
69
+ // If full image url not found use thumbnail.
70
+ const imageUrl = photo.url || photo.thumbnail_url;
71
+
69
72
  // 100% width for the preview so it fits nicely into the document, some "thumbnails" are
70
- // actually the full size photo. If thumbnails not found, use full image.
71
- const imageUrl = photo.thumbnail_url || photo.url;
73
+ // actually the full size photo.
72
74
  const photoPreview = (
73
75
  <p>
74
76
  <img src={ imageUrl } alt={ photo.title } width="100%" />
@@ -290,3 +292,33 @@ export const getAttributesFromPreview = memoize(
290
292
  return attributes;
291
293
  }
292
294
  );
295
+
296
+ /**
297
+ * Returns the attributes derived from the preview, merged with the current attributes.
298
+ *
299
+ * @param {Object} currentAttributes The current attributes of the block.
300
+ * @param {Object} preview The preview data.
301
+ * @param {string} title The block's title, e.g. Twitter.
302
+ * @param {boolean} isResponsive Boolean indicating if the block supports responsive content.
303
+ * @param {boolean} ignorePreviousClassName Determines if the previous className attribute should be ignored when merging.
304
+ * @return {Object} Merged attributes.
305
+ */
306
+ export const getMergedAttributesWithPreview = (
307
+ currentAttributes,
308
+ preview,
309
+ title,
310
+ isResponsive,
311
+ ignorePreviousClassName = false
312
+ ) => {
313
+ const { allowResponsive, className } = currentAttributes;
314
+ return {
315
+ ...currentAttributes,
316
+ ...getAttributesFromPreview(
317
+ preview,
318
+ title,
319
+ ignorePreviousClassName ? undefined : className,
320
+ isResponsive,
321
+ allowResponsive
322
+ ),
323
+ };
324
+ };
@@ -68,7 +68,7 @@ export default function FileBlockInspector( {
68
68
  ) }
69
69
  </PanelBody>
70
70
  ) }
71
- <PanelBody title={ __( 'Text link settings' ) }>
71
+ <PanelBody title={ __( 'Settings' ) }>
72
72
  <SelectControl
73
73
  label={ __( 'Link to' ) }
74
74
  value={ textLinkHref }
@@ -80,8 +80,6 @@ export default function FileBlockInspector( {
80
80
  checked={ openInNewWindow }
81
81
  onChange={ changeOpenInNewWindow }
82
82
  />
83
- </PanelBody>
84
- <PanelBody title={ __( 'Download button settings' ) }>
85
83
  <ToggleControl
86
84
  label={ __( 'Show download button' ) }
87
85
  checked={ showDownloadButton }
@@ -478,7 +478,7 @@ function GalleryEdit( props ) {
478
478
  return (
479
479
  <>
480
480
  <InspectorControls>
481
- <PanelBody title={ __( 'Gallery settings' ) }>
481
+ <PanelBody title={ __( 'Settings' ) }>
482
482
  { images.length > 1 && (
483
483
  <RangeControl
484
484
  label={ __( 'Columns' ) }
@@ -420,7 +420,7 @@ function GalleryEdit( props ) {
420
420
  return (
421
421
  <>
422
422
  <InspectorControls>
423
- <PanelBody title={ __( 'Gallery settings' ) }>
423
+ <PanelBody title={ __( 'Settings' ) }>
424
424
  { images.length > 1 && (
425
425
  <RangeControl
426
426
  label={ __( 'Columns' ) }
package/src/html/edit.js CHANGED
@@ -59,14 +59,14 @@ export default function HTMLEdit( { attributes, setAttributes, isSelected } ) {
59
59
  isPressed={ ! isPreview }
60
60
  onClick={ switchToHTML }
61
61
  >
62
- <span>HTML</span>
62
+ HTML
63
63
  </ToolbarButton>
64
64
  <ToolbarButton
65
65
  className="components-tab-button"
66
66
  isPressed={ isPreview }
67
67
  onClick={ switchToPreview }
68
68
  >
69
- <span>{ __( 'Preview' ) }</span>
69
+ { __( 'Preview' ) }
70
70
  </ToolbarButton>
71
71
  </ToolbarGroup>
72
72
  </BlockControls>
package/src/image/edit.js CHANGED
@@ -22,8 +22,6 @@ import { useEffect, useRef, useState } from '@wordpress/element';
22
22
  import { __ } from '@wordpress/i18n';
23
23
  import { image as icon } from '@wordpress/icons';
24
24
 
25
- /* global wp */
26
-
27
25
  /**
28
26
  * Internal dependencies
29
27
  */
@@ -97,7 +95,7 @@ function hasDefaultSize( image, defaultSize ) {
97
95
  * @return {boolean} Whether the image has been destroyed.
98
96
  */
99
97
  export function isMediaDestroyed( id ) {
100
- const attachment = wp?.media?.attachment( id ) || {};
98
+ const attachment = window?.wp?.media?.attachment( id ) || {};
101
99
  return attachment.destroyed;
102
100
  }
103
101
 
@@ -232,7 +230,7 @@ export function ImageEdit( {
232
230
  // The constants used in Gutenberg do not match WP options so a little more complicated than ideal.
233
231
  // TODO: fix this in a follow up PR, requires updating media-text and ui component.
234
232
  switch (
235
- wp?.media?.view?.settings?.defaultProps?.link ||
233
+ window?.wp?.media?.view?.settings?.defaultProps?.link ||
236
234
  LINK_DESTINATION_NONE
237
235
  ) {
238
236
  case 'file':
@@ -670,7 +670,7 @@ export class ImageEdit extends Component {
670
670
 
671
671
  const getInspectorControls = () => (
672
672
  <InspectorControls>
673
- <PanelBody title={ __( 'Image settings' ) } />
673
+ <PanelBody title={ __( 'Settings' ) } />
674
674
  <PanelBody style={ styles.panelBody }>
675
675
  <BlockStyles clientId={ clientId } url={ url } />
676
676
  </PanelBody>
@@ -370,7 +370,7 @@ export default function Image( {
370
370
  </BlockControls>
371
371
  ) }
372
372
  <InspectorControls>
373
- <PanelBody title={ __( 'Image settings' ) }>
373
+ <PanelBody title={ __( 'Settings' ) }>
374
374
  { ! multiImageSelection && (
375
375
  <TextareaControl
376
376
  label={ __( 'Alt text (alternative text)' ) }