@wordpress/block-editor 15.8.1-next.dc3f6d3c1.0 → 15.9.1-next.8b30e05b0.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 (216) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +4 -0
  3. package/build/components/block-list/index.js +2 -1
  4. package/build/components/block-list/index.js.map +2 -2
  5. package/build/components/block-list/use-block-props/use-selected-block-event-handlers.js +27 -5
  6. package/build/components/block-list/use-block-props/use-selected-block-event-handlers.js.map +2 -2
  7. package/build/components/block-lock/modal.js +5 -5
  8. package/build/components/block-lock/modal.js.map +2 -2
  9. package/build/components/block-lock/use-block-lock.js +10 -13
  10. package/build/components/block-lock/use-block-lock.js.map +2 -2
  11. package/build/components/block-settings-menu-controls/index.js +1 -1
  12. package/build/components/block-settings-menu-controls/index.js.map +2 -2
  13. package/build/components/block-tools/index.js +56 -45
  14. package/build/components/block-tools/index.js.map +3 -3
  15. package/build/components/block-visibility/toolbar.js +1 -1
  16. package/build/components/block-visibility/toolbar.js.map +1 -1
  17. package/build/components/content-only-controls/fields-dropdown-menu.js +66 -0
  18. package/build/components/content-only-controls/fields-dropdown-menu.js.map +7 -0
  19. package/build/components/content-only-controls/index.js +225 -44
  20. package/build/components/content-only-controls/index.js.map +3 -3
  21. package/build/components/content-only-controls/link/index.js +92 -103
  22. package/build/components/content-only-controls/link/index.js.map +3 -3
  23. package/build/components/content-only-controls/media/index.js +134 -134
  24. package/build/components/content-only-controls/media/index.js.map +3 -3
  25. package/build/components/content-only-controls/rich-text/index.js +65 -74
  26. package/build/components/content-only-controls/rich-text/index.js.map +3 -3
  27. package/build/components/font-family/index.js +1 -15
  28. package/build/components/font-family/index.js.map +2 -2
  29. package/build/components/global-styles/dimensions-panel.js +35 -2
  30. package/build/components/global-styles/dimensions-panel.js.map +2 -2
  31. package/build/components/global-styles/hooks.js +1 -1
  32. package/build/components/global-styles/hooks.js.map +2 -2
  33. package/build/components/global-styles/typography-panel.js +1 -2
  34. package/build/components/global-styles/typography-panel.js.map +2 -2
  35. package/build/components/index.js +3 -0
  36. package/build/components/index.js.map +2 -2
  37. package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.js +1 -1
  38. package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.js.map +2 -2
  39. package/build/components/link-control/index.js +15 -7
  40. package/build/components/link-control/index.js.map +2 -2
  41. package/build/components/list-view/block-select-button.js +3 -11
  42. package/build/components/list-view/block-select-button.js.map +2 -2
  43. package/build/components/list-view/block.js +9 -7
  44. package/build/components/list-view/block.js.map +2 -2
  45. package/build/components/media-placeholder/index.js +17 -4
  46. package/build/components/media-placeholder/index.js.map +2 -2
  47. package/build/components/media-placeholder/utils.js +60 -0
  48. package/build/components/media-placeholder/utils.js.map +7 -0
  49. package/build/components/media-replace-flow/index.js +20 -3
  50. package/build/components/media-replace-flow/index.js.map +2 -2
  51. package/build/components/tool-selector/index.js +46 -0
  52. package/build/components/tool-selector/index.js.map +7 -0
  53. package/build/components/use-block-commands/index.js +1 -1
  54. package/build/components/use-block-commands/index.js.map +2 -2
  55. package/build/components/use-block-drop-zone/index.js +1 -5
  56. package/build/components/use-block-drop-zone/index.js.map +2 -2
  57. package/build/hooks/dimensions.js +3 -3
  58. package/build/hooks/dimensions.js.map +2 -2
  59. package/build/hooks/metadata.js +1 -1
  60. package/build/hooks/metadata.js.map +2 -2
  61. package/build/hooks/utils.js +5 -1
  62. package/build/hooks/utils.js.map +2 -2
  63. package/build/store/private-selectors.js +43 -3
  64. package/build/store/private-selectors.js.map +2 -2
  65. package/build/store/reducer.js +2 -1
  66. package/build/store/reducer.js.map +2 -2
  67. package/build/store/selectors.js +6 -4
  68. package/build/store/selectors.js.map +2 -2
  69. package/build-module/components/block-list/index.js +2 -1
  70. package/build-module/components/block-list/index.js.map +2 -2
  71. package/build-module/components/block-list/use-block-props/use-selected-block-event-handlers.js +27 -5
  72. package/build-module/components/block-list/use-block-props/use-selected-block-event-handlers.js.map +2 -2
  73. package/build-module/components/block-lock/modal.js +5 -5
  74. package/build-module/components/block-lock/modal.js.map +2 -2
  75. package/build-module/components/block-lock/use-block-lock.js +10 -13
  76. package/build-module/components/block-lock/use-block-lock.js.map +2 -2
  77. package/build-module/components/block-settings-menu-controls/index.js +1 -1
  78. package/build-module/components/block-settings-menu-controls/index.js.map +2 -2
  79. package/build-module/components/block-tools/index.js +56 -45
  80. package/build-module/components/block-tools/index.js.map +2 -2
  81. package/build-module/components/block-visibility/toolbar.js +1 -1
  82. package/build-module/components/block-visibility/toolbar.js.map +1 -1
  83. package/build-module/components/content-only-controls/fields-dropdown-menu.js +45 -0
  84. package/build-module/components/content-only-controls/fields-dropdown-menu.js.map +7 -0
  85. package/build-module/components/content-only-controls/index.js +229 -46
  86. package/build-module/components/content-only-controls/index.js.map +2 -2
  87. package/build-module/components/content-only-controls/link/index.js +92 -104
  88. package/build-module/components/content-only-controls/link/index.js.map +2 -2
  89. package/build-module/components/content-only-controls/media/index.js +134 -135
  90. package/build-module/components/content-only-controls/media/index.js.map +2 -2
  91. package/build-module/components/content-only-controls/rich-text/index.js +67 -81
  92. package/build-module/components/content-only-controls/rich-text/index.js.map +2 -2
  93. package/build-module/components/font-family/index.js +1 -15
  94. package/build-module/components/font-family/index.js.map +2 -2
  95. package/build-module/components/global-styles/dimensions-panel.js +35 -2
  96. package/build-module/components/global-styles/dimensions-panel.js.map +2 -2
  97. package/build-module/components/global-styles/hooks.js +1 -1
  98. package/build-module/components/global-styles/hooks.js.map +2 -2
  99. package/build-module/components/global-styles/typography-panel.js +1 -2
  100. package/build-module/components/global-styles/typography-panel.js.map +2 -2
  101. package/build-module/components/index.js +2 -0
  102. package/build-module/components/index.js.map +2 -2
  103. package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.js +1 -1
  104. package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.js.map +2 -2
  105. package/build-module/components/link-control/index.js +16 -8
  106. package/build-module/components/link-control/index.js.map +2 -2
  107. package/build-module/components/list-view/block-select-button.js +3 -11
  108. package/build-module/components/list-view/block-select-button.js.map +2 -2
  109. package/build-module/components/list-view/block.js +9 -7
  110. package/build-module/components/list-view/block.js.map +2 -2
  111. package/build-module/components/media-placeholder/index.js +18 -5
  112. package/build-module/components/media-placeholder/index.js.map +2 -2
  113. package/build-module/components/media-placeholder/utils.js +35 -0
  114. package/build-module/components/media-placeholder/utils.js.map +7 -0
  115. package/build-module/components/media-replace-flow/index.js +20 -3
  116. package/build-module/components/media-replace-flow/index.js.map +2 -2
  117. package/build-module/components/tool-selector/index.js +15 -0
  118. package/build-module/components/tool-selector/index.js.map +7 -0
  119. package/build-module/components/use-block-commands/index.js +1 -1
  120. package/build-module/components/use-block-commands/index.js.map +2 -2
  121. package/build-module/components/use-block-drop-zone/index.js +1 -5
  122. package/build-module/components/use-block-drop-zone/index.js.map +2 -2
  123. package/build-module/hooks/dimensions.js +3 -3
  124. package/build-module/hooks/dimensions.js.map +2 -2
  125. package/build-module/hooks/metadata.js +1 -1
  126. package/build-module/hooks/metadata.js.map +2 -2
  127. package/build-module/hooks/utils.js +5 -1
  128. package/build-module/hooks/utils.js.map +2 -2
  129. package/build-module/store/private-selectors.js +39 -3
  130. package/build-module/store/private-selectors.js.map +2 -2
  131. package/build-module/store/reducer.js +2 -1
  132. package/build-module/store/reducer.js.map +2 -2
  133. package/build-module/store/selectors.js +6 -4
  134. package/build-module/store/selectors.js.map +2 -2
  135. package/build-style/content-rtl.css +3 -0
  136. package/build-style/content.css +3 -0
  137. package/build-style/style-rtl.css +14 -5
  138. package/build-style/style.css +14 -5
  139. package/package.json +38 -37
  140. package/src/components/block-list/content.scss +5 -0
  141. package/src/components/block-list/index.js +3 -1
  142. package/src/components/block-list/use-block-props/use-selected-block-event-handlers.js +34 -3
  143. package/src/components/block-lock/modal.js +6 -5
  144. package/src/components/block-lock/use-block-lock.js +10 -14
  145. package/src/components/block-patterns-list/stories/{index.story.js → index.story.jsx} +3 -1
  146. package/src/components/block-settings-menu-controls/index.js +1 -1
  147. package/src/components/block-tools/index.js +15 -2
  148. package/src/components/block-tools/style.scss +4 -0
  149. package/src/components/block-visibility/toolbar.js +1 -1
  150. package/src/components/content-only-controls/fields-dropdown-menu.js +53 -0
  151. package/src/components/content-only-controls/index.js +314 -50
  152. package/src/components/content-only-controls/link/index.js +62 -57
  153. package/src/components/content-only-controls/media/index.js +177 -156
  154. package/src/components/content-only-controls/rich-text/index.js +30 -44
  155. package/src/components/content-only-controls/styles.scss +10 -1
  156. package/src/components/font-family/README.md +0 -9
  157. package/src/components/font-family/index.js +1 -16
  158. package/src/components/font-family/stories/{index.story.js → index.story.jsx} +0 -1
  159. package/src/components/global-styles/dimensions-panel.js +36 -0
  160. package/src/components/global-styles/hooks.js +1 -1
  161. package/src/components/global-styles/typography-panel.js +0 -1
  162. package/src/components/index.js +4 -0
  163. package/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js +1 -5
  164. package/src/components/link-control/index.js +36 -12
  165. package/src/components/list-view/block-select-button.js +22 -30
  166. package/src/components/list-view/block.js +9 -7
  167. package/src/components/media-placeholder/index.js +20 -5
  168. package/src/components/media-placeholder/test/get-computed-accept-attribute.js +164 -0
  169. package/src/components/media-placeholder/utils.js +65 -0
  170. package/src/components/media-replace-flow/index.js +22 -3
  171. package/src/components/tool-selector/index.js +19 -0
  172. package/src/components/use-block-commands/index.js +1 -1
  173. package/src/components/use-block-drop-zone/index.js +1 -5
  174. package/src/hooks/dimensions.js +8 -3
  175. package/src/hooks/metadata.js +1 -1
  176. package/src/hooks/test/metadata.js +1 -1
  177. package/src/hooks/utils.js +4 -0
  178. package/src/store/private-selectors.js +123 -6
  179. package/src/store/reducer.js +3 -0
  180. package/src/store/selectors.js +6 -4
  181. package/src/store/test/private-selectors.js +242 -0
  182. package/src/store/test/reducer.js +17 -7
  183. package/src/style.scss +0 -1
  184. package/tsconfig.json +1 -0
  185. package/build/components/content-only-controls/plain-text/index.js +0 -68
  186. package/build/components/content-only-controls/plain-text/index.js.map +0 -7
  187. package/build-module/components/content-only-controls/plain-text/index.js +0 -50
  188. package/build-module/components/content-only-controls/plain-text/index.js.map +0 -7
  189. package/src/components/content-only-controls/plain-text/index.js +0 -49
  190. package/src/components/font-family/style.scss +0 -7
  191. /package/src/components/alignment-control/stories/{aliginment-toolbar.story.js → aliginment-toolbar.story.jsx} +0 -0
  192. /package/src/components/alignment-control/stories/{index.story.js → index.story.jsx} +0 -0
  193. /package/src/components/block-alignment-matrix-control/stories/{index.story.js → index.story.jsx} +0 -0
  194. /package/src/components/block-draggable/stories/{index.story.js → index.story.jsx} +0 -0
  195. /package/src/components/block-heading-level-dropdown/stories/{index.story.js → index.story.jsx} +0 -0
  196. /package/src/components/block-mover/stories/{index.story.js → index.story.jsx} +0 -0
  197. /package/src/components/block-title/stories/{index.story.js → index.story.jsx} +0 -0
  198. /package/src/components/border-radius-control/stories/{index.story.js → index.story.jsx} +0 -0
  199. /package/src/components/date-format-picker/stories/{index.story.js → index.story.jsx} +0 -0
  200. /package/src/components/dimensions-tool/stories/{aspect-ratio-tool.story.js → aspect-ratio-tool.story.jsx} +0 -0
  201. /package/src/components/dimensions-tool/stories/{index.story.js → index.story.jsx} +0 -0
  202. /package/src/components/dimensions-tool/stories/{scale-tool.story.js → scale-tool.story.jsx} +0 -0
  203. /package/src/components/dimensions-tool/stories/{width-height-tool.story.js → width-height-tool.story.jsx} +0 -0
  204. /package/src/components/height-control/stories/{index.story.js → index.story.jsx} +0 -0
  205. /package/src/components/inserter/stories/{index.story.js → index.story.jsx} +0 -0
  206. /package/src/components/line-height-control/stories/{index.story.js → index.story.jsx} +0 -0
  207. /package/src/components/plain-text/stories/{index.story.js → index.story.jsx} +0 -0
  208. /package/src/components/resolution-tool/stories/{index.story.js → index.story.jsx} +0 -0
  209. /package/src/components/tabbed-sidebar/stories/{index.story.js → index.story.jsx} +0 -0
  210. /package/src/components/text-alignment-control/stories/{index.story.js → index.story.jsx} +0 -0
  211. /package/src/components/text-decoration-control/stories/{index.story.js → index.story.jsx} +0 -0
  212. /package/src/components/text-transform-control/stories/{index.story.js → index.story.jsx} +0 -0
  213. /package/src/components/unit-control/stories/{index.story.js → index.story.jsx} +0 -0
  214. /package/src/components/url-popover/stories/{index.story.js → index.story.jsx} +0 -0
  215. /package/src/components/warning/stories/{index.story.js → index.story.jsx} +0 -0
  216. /package/src/components/writing-mode-control/stories/{index.story.js → index.story.jsx} +0 -0
@@ -4,11 +4,9 @@
4
4
  import {
5
5
  Button,
6
6
  Icon,
7
- __experimentalToolsPanelItem as ToolsPanelItem,
8
7
  __experimentalGrid as Grid,
9
8
  } from '@wordpress/components';
10
9
  import { useSelect } from '@wordpress/data';
11
- import { useMemo } from '@wordpress/element';
12
10
  import { __ } from '@wordpress/i18n';
13
11
  import {
14
12
  audio as audioIcon,
@@ -26,9 +24,10 @@ import { useInspectorPopoverPlacement } from '../use-inspector-popover-placement
26
24
  import { getMediaSelectKey } from '../../../store/private-keys';
27
25
  import { store as blockEditorStore } from '../../../store';
28
26
 
29
- function MediaThumbnail( { control, attributeValues, attachment } ) {
30
- const { allowedTypes, multiple } = control.args;
31
- const mapping = control.mapping;
27
+ function MediaThumbnail( { data, field, attachment } ) {
28
+ const config = field.config || {};
29
+ const { allowedTypes = [], multiple = false } = config;
30
+
32
31
  if ( multiple ) {
33
32
  return 'todo multiple';
34
33
  }
@@ -50,29 +49,17 @@ function MediaThumbnail( { control, attributeValues, attachment } ) {
50
49
  }
51
50
 
52
51
  if ( allowedTypes.length === 1 ) {
53
- let src;
54
- if (
55
- allowedTypes[ 0 ] === 'image' &&
56
- mapping.src &&
57
- attributeValues[ mapping.src ]
58
- ) {
59
- src = attributeValues[ mapping.src ];
60
- } else if (
61
- allowedTypes[ 0 ] === 'video' &&
62
- mapping.poster &&
63
- attributeValues[ mapping.poster ]
64
- ) {
65
- src = attributeValues[ mapping.poster ];
66
- }
52
+ const value = field.getValue( { item: data } );
53
+ const url = value?.url;
67
54
 
68
- if ( src ) {
55
+ if ( url ) {
69
56
  return (
70
57
  <img
71
58
  className="block-editor-content-only-controls__media-thumbnail"
72
59
  alt=""
73
60
  width={ 24 }
74
61
  height={ 24 }
75
- src={ src }
62
+ src={ url }
76
63
  />
77
64
  );
78
65
  }
@@ -96,29 +83,27 @@ function MediaThumbnail( { control, attributeValues, attachment } ) {
96
83
  return <Icon icon={ mediaIcon } size={ 24 } />;
97
84
  }
98
85
 
99
- export default function Media( {
100
- clientId,
101
- control,
102
- blockType,
103
- attributeValues,
104
- updateAttributes,
105
- } ) {
86
+ export default function Media( { data, field, config = {} } ) {
106
87
  const { popoverProps } = useInspectorPopoverPlacement( {
107
88
  isControl: true,
108
89
  } );
109
- const typeKey = control.mapping.type;
110
- const idKey = control.mapping.id;
111
- const srcKey = control.mapping.src;
112
- const captionKey = control.mapping.caption;
113
- const altKey = control.mapping.alt;
114
- const posterKey = control.mapping.poster;
115
- const featuredImageKey = control.mapping.featuredImage;
90
+ const value = field.getValue( { item: data } );
91
+ const { allowedTypes = [], multiple = false } = field.config || {};
92
+ const { clientId, updateBlockAttributes, fieldDef } = config;
93
+ const updateAttributes = ( newFieldValue ) => {
94
+ const mappedChanges = field.setValue( {
95
+ item: data,
96
+ value: newFieldValue,
97
+ } );
98
+ updateBlockAttributes( clientId, mappedChanges );
99
+ };
116
100
 
117
- const id = attributeValues[ idKey ];
118
- const src = attributeValues[ srcKey ];
119
- const caption = attributeValues[ captionKey ];
120
- const alt = attributeValues[ altKey ];
121
- const useFeaturedImage = attributeValues[ featuredImageKey ];
101
+ // Check if featured image is supported by checking if it's in the mapping
102
+ const hasFeaturedImageSupport =
103
+ fieldDef?.mapping && 'featuredImage' in fieldDef.mapping;
104
+
105
+ const id = value?.id;
106
+ const url = value?.url;
122
107
 
123
108
  const attachment = useSelect(
124
109
  ( select ) => {
@@ -140,8 +125,8 @@ export default function Media( {
140
125
 
141
126
  // TODO - pluralize when multiple.
142
127
  let chooseItemLabel;
143
- if ( control.args.allowedTypes.length === 1 ) {
144
- const allowedType = control.args.allowedTypes[ 0 ];
128
+ if ( allowedTypes.length === 1 ) {
129
+ const allowedType = allowedTypes[ 0 ];
145
130
  if ( allowedType === 'image' ) {
146
131
  chooseItemLabel = __( 'Choose an image…' );
147
132
  } else if ( allowedType === 'video' ) {
@@ -155,131 +140,167 @@ export default function Media( {
155
140
  chooseItemLabel = __( 'Choose a media item…' );
156
141
  }
157
142
 
158
- const defaultValues = useMemo( () => {
159
- return Object.fromEntries(
160
- Object.entries( control.mapping ).map( ( [ , attributeKey ] ) => {
161
- return [
162
- attributeKey,
163
- blockType.attributes[ attributeKey ]?.defaultValue ??
164
- undefined,
165
- ];
166
- } )
167
- );
168
- }, [ blockType.attributes, control.mapping ] );
169
-
170
143
  return (
171
144
  <MediaUploadCheck>
172
- <ToolsPanelItem
173
- panelId={ clientId }
174
- label={ control.label }
175
- hasValue={ () => !! src }
176
- onDeselect={ () => {
177
- updateAttributes( defaultValues );
178
- } }
179
- isShownByDefault={ control.shownByDefault }
180
- >
181
- <MediaReplaceFlow
182
- className="block-editor-content-only-controls__media-replace-flow"
183
- allowedTypes={ control.args.allowedTypes }
184
- mediaId={ id }
185
- mediaURL={ src }
186
- multiple={ control.args.multiple }
187
- popoverProps={ popoverProps }
188
- onReset={ () => {
189
- updateAttributes( defaultValues );
190
- } }
191
- useFeaturedImage={ !! useFeaturedImage }
192
- onToggleFeaturedImage={
193
- !! featuredImageKey &&
194
- ( () => {
195
- updateAttributes( {
196
- ...defaultValues,
197
- [ featuredImageKey ]: ! useFeaturedImage,
198
- } );
199
- } )
200
- }
201
- onSelect={ ( selectedMedia ) => {
202
- if ( selectedMedia.id && selectedMedia.url ) {
203
- const optionalAttributes = {};
145
+ <MediaReplaceFlow
146
+ className="block-editor-content-only-controls__media-replace-flow"
147
+ allowedTypes={ allowedTypes }
148
+ mediaId={ id }
149
+ mediaURL={ url }
150
+ multiple={ multiple }
151
+ popoverProps={ popoverProps }
152
+ onReset={ () => {
153
+ // Build reset value dynamically based on mapping
154
+ const resetValue = {};
204
155
 
205
- if ( typeKey && selectedMedia.type ) {
206
- optionalAttributes[ typeKey ] =
207
- selectedMedia.type;
156
+ if ( fieldDef?.mapping ) {
157
+ Object.keys( fieldDef.mapping ).forEach( ( key ) => {
158
+ if (
159
+ key === 'id' ||
160
+ key === 'src' ||
161
+ key === 'url'
162
+ ) {
163
+ resetValue[ key ] = undefined;
164
+ } else if ( key === 'caption' || key === 'alt' ) {
165
+ resetValue[ key ] = '';
208
166
  }
167
+ } );
168
+ }
169
+
170
+ // Turn off featured image when resetting (only if it's in the mapping)
171
+ if ( hasFeaturedImageSupport ) {
172
+ resetValue.featuredImage = false;
173
+ }
209
174
 
175
+ // Merge with existing value to preserve other field properties
176
+ updateAttributes( { ...value, ...resetValue } );
177
+ } }
178
+ { ...( hasFeaturedImageSupport && {
179
+ useFeaturedImage: !! value?.featuredImage,
180
+ onToggleFeaturedImage: () => {
181
+ updateAttributes( {
182
+ ...value,
183
+ featuredImage: ! value?.featuredImage,
184
+ } );
185
+ },
186
+ } ) }
187
+ onSelect={ ( selectedMedia ) => {
188
+ if ( selectedMedia.id && selectedMedia.url ) {
189
+ // Determine mediaType from MIME type, not from object type
190
+ let mediaType = 'image'; // default
191
+ if ( selectedMedia.mime_type ) {
210
192
  if (
211
- captionKey &&
212
- ! caption &&
213
- selectedMedia.caption
193
+ selectedMedia.mime_type.startsWith( 'video/' )
214
194
  ) {
215
- optionalAttributes[ captionKey ] =
216
- selectedMedia.caption;
217
- }
218
- if ( altKey && ! alt && selectedMedia.alt ) {
219
- optionalAttributes[ altKey ] =
220
- selectedMedia.alt;
221
- }
222
- if ( posterKey && selectedMedia.poster ) {
223
- optionalAttributes[ posterKey ] =
224
- selectedMedia.poster;
195
+ mediaType = 'video';
196
+ } else if (
197
+ selectedMedia.mime_type.startsWith( 'audio/' )
198
+ ) {
199
+ mediaType = 'audio';
225
200
  }
201
+ }
202
+
203
+ // Build new value dynamically based on what's in the mapping
204
+ const newValue = {};
226
205
 
227
- updateAttributes( {
228
- [ idKey ]: selectedMedia.id,
229
- [ srcKey ]: selectedMedia.url,
230
- ...optionalAttributes,
231
- } );
206
+ // Iterate over mapping keys and set values for supported properties
207
+ if ( fieldDef?.mapping ) {
208
+ Object.keys( fieldDef.mapping ).forEach(
209
+ ( key ) => {
210
+ if ( key === 'id' ) {
211
+ newValue[ key ] = selectedMedia.id;
212
+ } else if (
213
+ key === 'src' ||
214
+ key === 'url'
215
+ ) {
216
+ newValue[ key ] = selectedMedia.url;
217
+ } else if ( key === 'type' ) {
218
+ newValue[ key ] = mediaType;
219
+ } else if (
220
+ key === 'link' &&
221
+ selectedMedia.link
222
+ ) {
223
+ newValue[ key ] = selectedMedia.link;
224
+ } else if (
225
+ key === 'caption' &&
226
+ ! value?.caption &&
227
+ selectedMedia.caption
228
+ ) {
229
+ newValue[ key ] = selectedMedia.caption;
230
+ } else if (
231
+ key === 'alt' &&
232
+ ! value?.alt &&
233
+ selectedMedia.alt
234
+ ) {
235
+ newValue[ key ] = selectedMedia.alt;
236
+ } else if (
237
+ key === 'poster' &&
238
+ selectedMedia.poster
239
+ ) {
240
+ newValue[ key ] = selectedMedia.poster;
241
+ }
242
+ }
243
+ );
232
244
  }
233
- } }
234
- renderToggle={ ( buttonProps ) => (
235
- <Button
236
- __next40pxDefaultSize
237
- className="block-editor-content-only-controls__media"
238
- { ...buttonProps }
245
+
246
+ // Turn off featured image when manually selecting media
247
+ if ( hasFeaturedImageSupport ) {
248
+ newValue.featuredImage = false;
249
+ }
250
+
251
+ // Merge with existing value to preserve other field properties
252
+ const finalValue = { ...value, ...newValue };
253
+ updateAttributes( finalValue );
254
+ }
255
+ } }
256
+ renderToggle={ ( buttonProps ) => (
257
+ <Button
258
+ __next40pxDefaultSize
259
+ className="block-editor-content-only-controls__media"
260
+ { ...buttonProps }
261
+ >
262
+ <Grid
263
+ rowGap={ 0 }
264
+ columnGap={ 8 }
265
+ templateColumns="24px 1fr"
266
+ className="block-editor-content-only-controls__media-row"
239
267
  >
240
- <Grid
241
- rowGap={ 0 }
242
- columnGap={ 8 }
243
- templateColumns="24px 1fr"
244
- className="block-editor-content-only-controls__media-row"
245
- >
246
- { src && (
247
- <>
248
- <MediaThumbnail
249
- attachment={ attachment }
250
- control={ control }
251
- attributeValues={ attributeValues }
252
- />
253
- <span className="block-editor-content-only-controls__media-title">
254
- {
255
- // TODO - truncate long titles or url smartly (e.g. show filename).
256
- attachment?.title?.raw &&
257
- attachment?.title?.raw !== ''
258
- ? attachment?.title?.raw
259
- : src
260
- }
261
- </span>
262
- </>
263
- ) }
264
- { ! src && (
265
- <>
266
- <span
267
- className="block-editor-content-only-controls__media-placeholder"
268
- style={ {
269
- width: '24px',
270
- height: '24px',
271
- } }
272
- />
273
- <span className="block-editor-content-only-controls__media-title">
274
- { chooseItemLabel }
275
- </span>
276
- </>
277
- ) }
278
- </Grid>
279
- </Button>
280
- ) }
281
- />
282
- </ToolsPanelItem>
268
+ { url && (
269
+ <>
270
+ <MediaThumbnail
271
+ attachment={ attachment }
272
+ field={ field }
273
+ data={ data }
274
+ />
275
+ <span className="block-editor-content-only-controls__media-title">
276
+ {
277
+ // TODO - truncate long titles or url smartly (e.g. show filename).
278
+ attachment?.title?.raw &&
279
+ attachment?.title?.raw !== ''
280
+ ? attachment?.title?.raw
281
+ : url
282
+ }
283
+ </span>
284
+ </>
285
+ ) }
286
+ { ! url && (
287
+ <>
288
+ <span
289
+ className="block-editor-content-only-controls__media-placeholder"
290
+ style={ {
291
+ width: '24px',
292
+ height: '24px',
293
+ } }
294
+ />
295
+ <span className="block-editor-content-only-controls__media-title">
296
+ { chooseItemLabel }
297
+ </span>
298
+ </>
299
+ ) }
300
+ </Grid>
301
+ </Button>
302
+ ) }
303
+ />
283
304
  </MediaUploadCheck>
284
305
  );
285
306
  }
@@ -1,17 +1,12 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import {
5
- BaseControl,
6
- useBaseControlProps,
7
- __experimentalToolsPanelItem as ToolsPanelItem,
8
- } from '@wordpress/components';
4
+ import { BaseControl, useBaseControlProps } from '@wordpress/components';
9
5
  import { useMergeRefs } from '@wordpress/compose';
10
6
  import { useRegistry } from '@wordpress/data';
11
7
  import { useRef, useState } from '@wordpress/element';
12
8
  import {
13
9
  __unstableUseRichText as useRichText,
14
- isEmpty,
15
10
  removeFormat,
16
11
  } from '@wordpress/rich-text';
17
12
 
@@ -25,17 +20,19 @@ import FormatEdit from '../../rich-text/format-edit';
25
20
  import { keyboardShortcutContext, inputEventContext } from '../../rich-text';
26
21
 
27
22
  export default function RichTextControl( {
28
- clientId,
29
- control,
30
- blockType,
31
- attributeValues,
32
- updateAttributes,
23
+ data,
24
+ field,
25
+ hideLabelFromVision,
26
+ config = {},
33
27
  } ) {
34
28
  const registry = useRegistry();
35
- const valueKey = control.mapping.value;
36
- const attrValue = attributeValues[ valueKey ];
37
- const defaultValue =
38
- blockType.attributes[ valueKey ]?.defaultValue ?? undefined;
29
+ const attrValue = field.getValue( { item: data } );
30
+ const fieldConfig = field.config || {};
31
+ const { clientId, updateBlockAttributes } = config;
32
+ const updateAttributes = ( html ) => {
33
+ const mappedChanges = field.setValue( { item: data, value: html } );
34
+ updateBlockAttributes( clientId, mappedChanges );
35
+ };
39
36
  const [ selection, setSelection ] = useState( {
40
37
  start: undefined,
41
38
  end: undefined,
@@ -46,8 +43,8 @@ export default function RichTextControl( {
46
43
  const keyboardShortcuts = useRef( new Set() );
47
44
 
48
45
  const adjustedAllowedFormats = getAllowedFormats( {
49
- allowedFormats: control.args?.allowedFormats,
50
- disableFormats: control.args?.disableFormats,
46
+ allowedFormats: fieldConfig?.allowedFormats,
47
+ disableFormats: fieldConfig?.disableFormats,
51
48
  } );
52
49
 
53
50
  const {
@@ -58,10 +55,9 @@ export default function RichTextControl( {
58
55
  dependencies,
59
56
  } = useFormatTypes( {
60
57
  clientId,
61
- identifier: valueKey,
58
+ identifier: field.id,
62
59
  allowedFormats: adjustedAllowedFormats,
63
- withoutInteractiveFormatting:
64
- control.args?.withoutInteractiveFormatting,
60
+ withoutInteractiveFormatting: fieldConfig?.withoutInteractiveFormatting,
65
61
  disableNoneEssentialFormatting: true,
66
62
  } );
67
63
 
@@ -102,12 +98,12 @@ export default function RichTextControl( {
102
98
  const {
103
99
  value,
104
100
  getValue,
105
- onChange,
101
+ onChange: onRichTextChange,
106
102
  ref: richTextRef,
107
103
  } = useRichText( {
108
104
  value: attrValue,
109
105
  onChange( html, { __unstableFormats, __unstableText } ) {
110
- updateAttributes( { [ valueKey ]: html } );
106
+ updateAttributes( html );
111
107
  Object.values( changeHandlers ).forEach( ( changeHandler ) => {
112
108
  changeHandler( __unstableFormats, __unstableText );
113
109
  } );
@@ -116,9 +112,9 @@ export default function RichTextControl( {
116
112
  selectionEnd: selection.end,
117
113
  onSelectionChange: ( start, end ) => setSelection( { start, end } ),
118
114
  __unstableIsSelected: isSelected,
119
- preserveWhiteSpace: !! control.args?.preserveWhiteSpace,
120
- placeholder: control.args?.placeholder,
121
- __unstableDisableFormats: control.args?.disableFormats,
115
+ preserveWhiteSpace: !! fieldConfig?.preserveWhiteSpace,
116
+ placeholder: fieldConfig?.placeholder,
117
+ __unstableDisableFormats: fieldConfig?.disableFormats,
122
118
  __unstableDependencies: dependencies,
123
119
  __unstableAfterParse: addEditorOnlyFormats,
124
120
  __unstableBeforeSerialize: removeEditorOnlyFormats,
@@ -126,29 +122,19 @@ export default function RichTextControl( {
126
122
  } );
127
123
 
128
124
  const { baseControlProps, controlProps } = useBaseControlProps( {
129
- hideLabelFromVision: control.shownByDefault,
130
- label: control.label,
125
+ hideLabelFromVision: hideLabelFromVision ?? field.hideLabelFromVision,
126
+ label: field.label,
131
127
  } );
132
128
 
133
129
  return (
134
- <ToolsPanelItem
135
- panelId={ clientId }
136
- label={ control.label }
137
- hasValue={ () => {
138
- return value?.text && ! isEmpty( value );
139
- } }
140
- onDeselect={ () =>
141
- updateAttributes( { [ valueKey ]: defaultValue } )
142
- }
143
- isShownByDefault={ control.shownByDefault }
144
- >
130
+ <>
145
131
  { isSelected && (
146
132
  <keyboardShortcutContext.Provider value={ keyboardShortcuts }>
147
133
  <inputEventContext.Provider value={ inputEvents }>
148
134
  <div>
149
135
  <FormatEdit
150
136
  value={ value }
151
- onChange={ onChange }
137
+ onChange={ onRichTextChange }
152
138
  onFocus={ onFocus }
153
139
  formatTypes={ formatTypes }
154
140
  forwardedRef={ anchorRef }
@@ -162,21 +148,21 @@ export default function RichTextControl( {
162
148
  <div
163
149
  className="block-editor-content-only-controls__rich-text"
164
150
  role="textbox"
165
- aria-multiline={ ! control.args?.disableLineBreaks }
151
+ aria-multiline={ ! fieldConfig?.disableLineBreaks }
166
152
  ref={ useMergeRefs( [
167
153
  richTextRef,
168
154
  useEventListeners( {
169
155
  registry,
170
156
  getValue,
171
- onChange,
157
+ onChange: onRichTextChange,
172
158
  formatTypes,
173
159
  selectionChange: setSelection,
174
160
  isSelected,
175
- disableFormats: control.args?.disableFormats,
161
+ disableFormats: fieldConfig?.disableFormats,
176
162
  value,
177
163
  tagName: 'div',
178
164
  removeEditorOnlyFormats,
179
- disableLineBreaks: control.args?.disableLineBreaks,
165
+ disableLineBreaks: fieldConfig?.disableLineBreaks,
180
166
  keyboardShortcuts,
181
167
  inputEvents,
182
168
  } ),
@@ -188,6 +174,6 @@ export default function RichTextControl( {
188
174
  { ...controlProps }
189
175
  />
190
176
  </BaseControl>
191
- </ToolsPanelItem>
177
+ </>
192
178
  );
193
179
  }
@@ -6,7 +6,7 @@
6
6
 
7
7
  .block-editor-content-only-controls__screen {
8
8
  &.components-navigator-screen {
9
- padding: $grid-unit-10 0 0 0;
9
+ padding: $grid-unit-10 0 $grid-unit-20 0;
10
10
  }
11
11
 
12
12
  // Add border for the entire content controls and remove the similar border
@@ -33,3 +33,12 @@
33
33
  .block-editor-content-only-controls__drill-down-button {
34
34
  width: 100%;
35
35
  }
36
+
37
+ .block-editor-content-only-controls__fields-container {
38
+ padding: 0 $grid-unit-20;
39
+ }
40
+
41
+ .block-editor-content-only-controls__fields-header {
42
+ padding: $grid-unit-10 0;
43
+ margin-bottom: $grid-unit-05;
44
+ }
@@ -28,7 +28,6 @@ const MyFontFamilyControl = () => {
28
28
  onChange={ ( newFontFamily ) => {
29
29
  setFontFamily( newFontFamily );
30
30
  } }
31
- __nextHasNoMarginBottom
32
31
  __next40pxDefaultSize
33
32
  />
34
33
  );
@@ -83,11 +82,3 @@ The rest of the props are passed down to the underlying `<SelectControl />` inst
83
82
  - Default: `false`
84
83
 
85
84
  Start opting into the larger default height that will become the default size in a future version.
86
-
87
- #### `__nextHasNoMarginBottom`
88
-
89
- - Type: `boolean`
90
- - Required: No
91
- - Default: `false`
92
-
93
- Start opting into the new margin-free styles that will become the default in a future version.
@@ -18,8 +18,6 @@ import { useSettings } from '../use-settings';
18
18
  export default function FontFamilyControl( {
19
19
  /** Start opting into the larger default height that will become the default size in a future version. */
20
20
  __next40pxDefaultSize = false,
21
- /** Start opting into the new margin-free styles that will become the default in a future version. */
22
- __nextHasNoMarginBottom = false,
23
21
  value = '',
24
22
  onChange,
25
23
  fontFamilies,
@@ -47,17 +45,6 @@ export default function FontFamilyControl( {
47
45
  } ) ),
48
46
  ];
49
47
 
50
- if ( ! __nextHasNoMarginBottom ) {
51
- deprecated(
52
- 'Bottom margin styles for wp.blockEditor.FontFamilyControl',
53
- {
54
- since: '6.7',
55
- version: '7.0',
56
- hint: 'Set the `__nextHasNoMarginBottom` prop to true to start opting into the new styles, which will become the default in a future version',
57
- }
58
- );
59
- }
60
-
61
48
  if (
62
49
  ! __next40pxDefaultSize &&
63
50
  ( props.size === undefined || props.size === 'default' )
@@ -82,9 +69,7 @@ export default function FontFamilyControl( {
82
69
  value={ selectedValue }
83
70
  onChange={ ( { selectedItem } ) => onChange( selectedItem.key ) }
84
71
  options={ options }
85
- className={ clsx( 'block-editor-font-family-control', className, {
86
- 'is-next-has-no-margin-bottom': __nextHasNoMarginBottom,
87
- } ) }
72
+ className={ clsx( 'block-editor-font-family-control', className ) }
88
73
  { ...props }
89
74
  />
90
75
  );
@@ -49,7 +49,6 @@ export const Default = {
49
49
  slug: 'system-font',
50
50
  },
51
51
  ],
52
- __nextHasNoMarginBottom: true,
53
52
  __next40pxDefaultSize: true,
54
53
  },
55
54
  };