@wordpress/block-editor 15.10.1-next.v.0 → 15.11.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 (81) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/block-edit/context.cjs +5 -0
  3. package/build/components/block-edit/context.cjs.map +2 -2
  4. package/build/components/block-edit/index.cjs +3 -0
  5. package/build/components/block-edit/index.cjs.map +2 -2
  6. package/build/components/block-inspector/index.cjs +2 -9
  7. package/build/components/block-inspector/index.cjs.map +2 -2
  8. package/build/components/block-list/block.cjs +3 -0
  9. package/build/components/block-list/block.cjs.map +2 -2
  10. package/build/components/button-block-appender/index.cjs +23 -19
  11. package/build/components/button-block-appender/index.cjs.map +2 -2
  12. package/build/components/font-sizes/font-size-picker.cjs +2 -1
  13. package/build/components/font-sizes/font-size-picker.cjs.map +2 -2
  14. package/build/components/inspector-controls/fill.cjs +4 -25
  15. package/build/components/inspector-controls/fill.cjs.map +2 -2
  16. package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.cjs +6 -6
  17. package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.cjs.map +2 -2
  18. package/build/hooks/block-fields/index.cjs +52 -86
  19. package/build/hooks/block-fields/index.cjs.map +3 -3
  20. package/build/hooks/block-fields/link/index.cjs +2 -11
  21. package/build/hooks/block-fields/link/index.cjs.map +2 -2
  22. package/build/hooks/block-fields/media/index.cjs +9 -14
  23. package/build/hooks/block-fields/media/index.cjs.map +2 -2
  24. package/build/hooks/index.cjs +2 -1
  25. package/build/hooks/index.cjs.map +3 -3
  26. package/build/hooks/list-view.cjs +27 -10
  27. package/build/hooks/list-view.cjs.map +2 -2
  28. package/build/hooks/utils.cjs +3 -2
  29. package/build/hooks/utils.cjs.map +2 -2
  30. package/build/store/selectors.cjs +7 -1
  31. package/build/store/selectors.cjs.map +2 -2
  32. package/build-module/components/block-edit/context.mjs +4 -0
  33. package/build-module/components/block-edit/context.mjs.map +2 -2
  34. package/build-module/components/block-edit/index.mjs +4 -0
  35. package/build-module/components/block-edit/index.mjs.map +2 -2
  36. package/build-module/components/block-inspector/index.mjs +2 -9
  37. package/build-module/components/block-inspector/index.mjs.map +2 -2
  38. package/build-module/components/block-list/block.mjs +3 -0
  39. package/build-module/components/block-list/block.mjs.map +2 -2
  40. package/build-module/components/button-block-appender/index.mjs +23 -19
  41. package/build-module/components/button-block-appender/index.mjs.map +2 -2
  42. package/build-module/components/font-sizes/font-size-picker.mjs +2 -1
  43. package/build-module/components/font-sizes/font-size-picker.mjs.map +2 -2
  44. package/build-module/components/inspector-controls/fill.mjs +6 -22
  45. package/build-module/components/inspector-controls/fill.mjs.map +2 -2
  46. package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.mjs +6 -6
  47. package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.mjs.map +2 -2
  48. package/build-module/hooks/block-fields/index.mjs +45 -87
  49. package/build-module/hooks/block-fields/index.mjs.map +2 -2
  50. package/build-module/hooks/block-fields/link/index.mjs +2 -11
  51. package/build-module/hooks/block-fields/link/index.mjs.map +2 -2
  52. package/build-module/hooks/block-fields/media/index.mjs +9 -14
  53. package/build-module/hooks/block-fields/media/index.mjs.map +2 -2
  54. package/build-module/hooks/index.mjs +2 -1
  55. package/build-module/hooks/index.mjs.map +2 -2
  56. package/build-module/hooks/list-view.mjs +27 -10
  57. package/build-module/hooks/list-view.mjs.map +2 -2
  58. package/build-module/hooks/utils.mjs +5 -3
  59. package/build-module/hooks/utils.mjs.map +2 -2
  60. package/build-module/store/selectors.mjs +7 -1
  61. package/build-module/store/selectors.mjs.map +2 -2
  62. package/package.json +39 -39
  63. package/src/components/block-edit/context.js +3 -0
  64. package/src/components/block-edit/index.js +6 -0
  65. package/src/components/block-inspector/index.js +2 -6
  66. package/src/components/block-list/block.js +3 -0
  67. package/src/components/block-list/block.native.js +5 -0
  68. package/src/components/block-patterns-list/stories/index.story.jsx +1 -1
  69. package/src/components/button-block-appender/index.js +2 -2
  70. package/src/components/font-sizes/font-size-picker.js +1 -0
  71. package/src/components/inspector-controls/fill.js +10 -20
  72. package/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js +11 -8
  73. package/src/hooks/block-fields/index.js +66 -111
  74. package/src/hooks/block-fields/link/index.js +2 -14
  75. package/src/hooks/block-fields/media/index.js +9 -21
  76. package/src/hooks/index.js +2 -1
  77. package/src/hooks/list-view.js +40 -10
  78. package/src/hooks/utils.js +4 -0
  79. package/src/store/selectors.js +14 -6
  80. /package/src/components/block-icon/stories/{index.story.js → index.story.ts} +0 -0
  81. /package/src/components/contrast-checker/stories/{index.story.js → index.story.ts} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/block-editor",
3
- "version": "15.10.1-next.v.0+500f87dd8",
3
+ "version": "15.11.0",
4
4
  "description": "Generic block editor.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -61,43 +61,43 @@
61
61
  ],
62
62
  "dependencies": {
63
63
  "@react-spring/web": "^9.4.5",
64
- "@wordpress/a11y": "^4.37.1-next.v.0+500f87dd8",
65
- "@wordpress/api-fetch": "^7.37.1-next.v.0+500f87dd8",
66
- "@wordpress/base-styles": "^6.13.2-next.v.0+500f87dd8",
67
- "@wordpress/blob": "^4.37.1-next.v.0+500f87dd8",
68
- "@wordpress/block-serialization-default-parser": "^5.37.1-next.v.0+500f87dd8",
69
- "@wordpress/blocks": "^15.10.1-next.v.0+500f87dd8",
70
- "@wordpress/commands": "^1.37.1-next.v.0+500f87dd8",
71
- "@wordpress/components": "^32.0.1-next.v.0+500f87dd8",
72
- "@wordpress/compose": "^7.37.1-next.v.0+500f87dd8",
73
- "@wordpress/data": "^10.37.1-next.v.0+500f87dd8",
74
- "@wordpress/dataviews": "^11.2.1-next.v.0+500f87dd8",
75
- "@wordpress/date": "^5.37.2-next.v.0+500f87dd8",
76
- "@wordpress/deprecated": "^4.37.1-next.v.0+500f87dd8",
77
- "@wordpress/dom": "^4.37.1-next.v.0+500f87dd8",
78
- "@wordpress/element": "^6.37.1-next.v.0+500f87dd8",
79
- "@wordpress/escape-html": "^3.37.1-next.v.0+500f87dd8",
80
- "@wordpress/global-styles-engine": "^1.4.1-next.v.0+500f87dd8",
81
- "@wordpress/hooks": "^4.37.1-next.v.0+500f87dd8",
82
- "@wordpress/html-entities": "^4.37.1-next.v.0+500f87dd8",
83
- "@wordpress/i18n": "^6.10.1-next.v.0+500f87dd8",
84
- "@wordpress/icons": "^11.4.1-next.v.0+500f87dd8",
85
- "@wordpress/image-cropper": "^1.1.1-next.v.0+500f87dd8",
86
- "@wordpress/interactivity": "^6.37.2-next.v.0+500f87dd8",
87
- "@wordpress/is-shallow-equal": "^5.37.1-next.v.0+500f87dd8",
88
- "@wordpress/keyboard-shortcuts": "^5.37.1-next.v.0+500f87dd8",
89
- "@wordpress/keycodes": "^4.38.1-next.v.0+500f87dd8",
90
- "@wordpress/notices": "^5.38.1-next.v.0+500f87dd8",
91
- "@wordpress/preferences": "^4.37.1-next.v.0+500f87dd8",
92
- "@wordpress/priority-queue": "^3.37.1-next.v.0+500f87dd8",
93
- "@wordpress/private-apis": "^1.37.1-next.v.0+500f87dd8",
94
- "@wordpress/rich-text": "^7.37.1-next.v.0+500f87dd8",
95
- "@wordpress/style-engine": "^2.37.1-next.v.0+500f87dd8",
96
- "@wordpress/token-list": "^3.37.1-next.v.0+500f87dd8",
97
- "@wordpress/upload-media": "^0.22.1-next.v.0+500f87dd8",
98
- "@wordpress/url": "^4.37.1-next.v.0+500f87dd8",
99
- "@wordpress/warning": "^3.37.1-next.v.0+500f87dd8",
100
- "@wordpress/wordcount": "^4.37.1-next.v.0+500f87dd8",
64
+ "@wordpress/a11y": "^4.38.0",
65
+ "@wordpress/api-fetch": "^7.38.0",
66
+ "@wordpress/base-styles": "^6.14.0",
67
+ "@wordpress/blob": "^4.38.0",
68
+ "@wordpress/block-serialization-default-parser": "^5.38.0",
69
+ "@wordpress/blocks": "^15.11.0",
70
+ "@wordpress/commands": "^1.38.0",
71
+ "@wordpress/components": "^32.0.0",
72
+ "@wordpress/compose": "^7.38.0",
73
+ "@wordpress/data": "^10.38.0",
74
+ "@wordpress/dataviews": "^11.2.0",
75
+ "@wordpress/date": "^5.38.0",
76
+ "@wordpress/deprecated": "^4.38.0",
77
+ "@wordpress/dom": "^4.38.0",
78
+ "@wordpress/element": "^6.38.0",
79
+ "@wordpress/escape-html": "^3.38.0",
80
+ "@wordpress/global-styles-engine": "^1.5.0",
81
+ "@wordpress/hooks": "^4.38.0",
82
+ "@wordpress/html-entities": "^4.38.0",
83
+ "@wordpress/i18n": "^6.11.0",
84
+ "@wordpress/icons": "^11.5.0",
85
+ "@wordpress/image-cropper": "^1.2.0",
86
+ "@wordpress/interactivity": "^6.38.0",
87
+ "@wordpress/is-shallow-equal": "^5.38.0",
88
+ "@wordpress/keyboard-shortcuts": "^5.38.0",
89
+ "@wordpress/keycodes": "^4.38.0",
90
+ "@wordpress/notices": "^5.38.0",
91
+ "@wordpress/preferences": "^4.38.0",
92
+ "@wordpress/priority-queue": "^3.38.0",
93
+ "@wordpress/private-apis": "^1.38.0",
94
+ "@wordpress/rich-text": "^7.38.0",
95
+ "@wordpress/style-engine": "^2.38.0",
96
+ "@wordpress/token-list": "^3.38.0",
97
+ "@wordpress/upload-media": "^0.23.0",
98
+ "@wordpress/url": "^4.38.0",
99
+ "@wordpress/warning": "^3.38.0",
100
+ "@wordpress/wordcount": "^4.38.0",
101
101
  "change-case": "^4.1.2",
102
102
  "clsx": "^2.1.1",
103
103
  "colord": "^2.7.0",
@@ -124,5 +124,5 @@
124
124
  "publishConfig": {
125
125
  "access": "public"
126
126
  },
127
- "gitHead": "ca0db0ee8ac2116cd307650136027d26d0cdd9bd"
127
+ "gitHead": "50c4c0f51e4797c217946ce42adfaa5eb026f33f"
128
128
  }
@@ -5,6 +5,9 @@ import { createContext, useContext } from '@wordpress/element';
5
5
 
6
6
  export const mayDisplayControlsKey = Symbol( 'mayDisplayControls' );
7
7
  export const mayDisplayParentControlsKey = Symbol( 'mayDisplayParentControls' );
8
+ export const mayDisplayPatternEditingControlsKey = Symbol(
9
+ 'mayDisplayPatternEditingControls'
10
+ );
8
11
  export const blockEditingModeKey = Symbol( 'blockEditingMode' );
9
12
  export const blockBindingsKey = Symbol( 'blockBindings' );
10
13
  export const isPreviewModeKey = Symbol( 'isPreviewMode' );
@@ -13,6 +13,7 @@ import {
13
13
  useBlockEditContext,
14
14
  mayDisplayControlsKey,
15
15
  mayDisplayParentControlsKey,
16
+ mayDisplayPatternEditingControlsKey,
16
17
  blockEditingModeKey,
17
18
  blockBindingsKey,
18
19
  isPreviewModeKey,
@@ -33,6 +34,7 @@ export { useBlockEditContext };
33
34
  export default function BlockEdit( {
34
35
  mayDisplayControls,
35
36
  mayDisplayParentControls,
37
+ mayDisplayPatternEditingControls,
36
38
  blockEditingMode,
37
39
  isPreviewMode,
38
40
  // The remaining props are passed through the BlockEdit filters and are thus
@@ -69,6 +71,9 @@ export default function BlockEdit( {
69
71
  // usage outside of the package (this context is exposed).
70
72
  [ mayDisplayControlsKey ]: mayDisplayControls,
71
73
  [ mayDisplayParentControlsKey ]: mayDisplayParentControls,
74
+ [ mayDisplayPatternEditingControlsKey ]:
75
+ mayDisplayPatternEditingControls &&
76
+ blockEditingMode !== 'disabled',
72
77
  [ blockEditingModeKey ]: blockEditingMode,
73
78
  [ blockBindingsKey ]: bindings,
74
79
  [ isPreviewModeKey ]: isPreviewMode,
@@ -82,6 +87,7 @@ export default function BlockEdit( {
82
87
  __unstableLayoutClassNames,
83
88
  mayDisplayControls,
84
89
  mayDisplayParentControls,
90
+ mayDisplayPatternEditingControls,
85
91
  blockEditingMode,
86
92
  bindings,
87
93
  isPreviewMode,
@@ -36,14 +36,12 @@ function StyleInspectorSlots( {
36
36
  blockName,
37
37
  showAdvancedControls = true,
38
38
  showPositionControls = true,
39
- showListControls = false,
40
39
  showBindingsControls = true,
41
40
  } ) {
42
41
  const borderPanelLabel = useBorderPanelLabel( { blockName } );
43
42
  return (
44
43
  <>
45
44
  <InspectorControls.Slot />
46
- { showListControls && <InspectorControls.Slot group="list" /> }
47
45
  <InspectorControls.Slot
48
46
  group="color"
49
47
  label={ __( 'Color' ) }
@@ -377,11 +375,9 @@ const BlockInspectorSingleBlock = ( {
377
375
  ) }
378
376
  <ContentTab contentClientIds={ contentClientIds } />
379
377
  <InspectorControls.Slot group="content" />
378
+ <InspectorControls.Slot group="list" />
380
379
  { ! isSectionBlock && (
381
- <StyleInspectorSlots
382
- blockName={ blockName }
383
- showListControls
384
- />
380
+ <StyleInspectorSlots blockName={ blockName } />
385
381
  ) }
386
382
  { isSectionBlock &&
387
383
  isBlockSynced &&
@@ -106,6 +106,7 @@ function BlockListBlock( {
106
106
  const {
107
107
  mayDisplayControls,
108
108
  mayDisplayParentControls,
109
+ isSelectionWithinCurrentSection,
109
110
  themeSupportsLayout,
110
111
  ...context
111
112
  } = useContext( PrivateBlockContext );
@@ -135,6 +136,7 @@ function BlockListBlock( {
135
136
  }
136
137
  mayDisplayControls={ mayDisplayControls }
137
138
  mayDisplayParentControls={ mayDisplayParentControls }
139
+ mayDisplayPatternEditingControls={ isSelectionWithinCurrentSection }
138
140
  blockEditingMode={ context.blockEditingMode }
139
141
  isPreviewMode={ context.isPreviewMode }
140
142
  />
@@ -231,6 +233,7 @@ function BlockListBlock( {
231
233
  value={ {
232
234
  wrapperProps: updatedWrapperProps,
233
235
  isAligned,
236
+ isSelectionWithinCurrentSection,
234
237
  ...context,
235
238
  } }
236
239
  >
@@ -195,6 +195,7 @@ function BlockListBlock( {
195
195
  isParentSelected,
196
196
  order,
197
197
  mayDisplayControls,
198
+ mayDisplayPatternEditingControls,
198
199
  blockEditingMode,
199
200
  } = useSelect(
200
201
  ( select ) => {
@@ -263,6 +264,7 @@ function BlockListBlock( {
263
264
  getMultiSelectedBlockClientIds().every(
264
265
  ( id ) => getBlockName( id ) === name
265
266
  ) ),
267
+ mayDisplayPatternEditingControls: false, // Section/pattern editing not yet supported on native
266
268
  blockEditingMode: getBlockEditingMode( clientId ),
267
269
  };
268
270
  },
@@ -403,6 +405,9 @@ function BlockListBlock( {
403
405
  }
404
406
  wrapperProps={ wrapperProps }
405
407
  mayDisplayControls={ mayDisplayControls }
408
+ mayDisplayPatternEditingControls={
409
+ mayDisplayPatternEditingControls
410
+ }
406
411
  blockEditingMode={ blockEditingMode }
407
412
  />
408
413
  <View onLayout={ onLayout } />
@@ -9,7 +9,7 @@ import { fn } from 'storybook/test';
9
9
  import BlockPatternsList from '../';
10
10
  import { ExperimentalBlockEditorProvider } from '../../provider';
11
11
  import patterns from './fixtures';
12
- import blockLibraryStyles from '!!raw-loader!../../../../../block-library/build-style/style.css';
12
+ import blockLibraryStyles from '../../../../../block-library/build-style/style.css?raw';
13
13
 
14
14
  const blockEditorSettings = {
15
15
  styles: [ { css: blockLibraryStyles } ],
@@ -54,6 +54,8 @@ function ButtonBlockAppender(
54
54
  );
55
55
 
56
56
  return (
57
+ // Disable reason: There shouldn't be a case where this button is disabled but not visually hidden.
58
+ // eslint-disable-next-line @wordpress/components-no-unsafe-button-disabled
57
59
  <Button
58
60
  __next40pxDefaultSize
59
61
  ref={ ref }
@@ -66,8 +68,6 @@ function ButtonBlockAppender(
66
68
  onClick={ onToggle }
67
69
  aria-haspopup={ isToggleButton ? 'true' : undefined }
68
70
  aria-expanded={ isToggleButton ? isOpen : undefined }
69
- // Disable reason: There shouldn't be a case where this button is disabled but not visually hidden.
70
- // eslint-disable-next-line no-restricted-syntax
71
71
  disabled={ disabled }
72
72
  label={ label }
73
73
  showTooltip
@@ -19,6 +19,7 @@ function FontSizePicker( props ) {
19
19
  { ...props }
20
20
  fontSizes={ fontSizes }
21
21
  disableCustomFontSizes={ ! customFontSize }
22
+ __next40pxDefaultSize
22
23
  />
23
24
  );
24
25
  }
@@ -15,15 +15,15 @@ import { useEffect, useContext } from '@wordpress/element';
15
15
  import {
16
16
  useBlockEditContext,
17
17
  mayDisplayControlsKey,
18
+ mayDisplayPatternEditingControlsKey,
18
19
  } from '../block-edit/context';
19
20
  import groups from './groups';
20
21
 
21
- export function PrivateInspectorControlsFill( {
22
+ export default function InspectorControlsFill( {
22
23
  children,
23
24
  group = 'default',
24
25
  __experimentalGroup,
25
26
  resetAllFilter,
26
- forceDisplayControls,
27
27
  } ) {
28
28
  if ( __experimentalGroup ) {
29
29
  deprecated(
@@ -43,7 +43,14 @@ export function PrivateInspectorControlsFill( {
43
43
  warning( `Unknown InspectorControls group "${ group }" provided.` );
44
44
  return null;
45
45
  }
46
- if ( ! forceDisplayControls && ! context[ mayDisplayControlsKey ] ) {
46
+ const shouldDisplayForPatternEditing =
47
+ context[ mayDisplayPatternEditingControlsKey ] &&
48
+ ( group === 'list' || group === 'content' );
49
+
50
+ if (
51
+ ! context[ mayDisplayControlsKey ] &&
52
+ ! shouldDisplayForPatternEditing
53
+ ) {
47
54
  return null;
48
55
  }
49
56
 
@@ -64,23 +71,6 @@ export function PrivateInspectorControlsFill( {
64
71
  );
65
72
  }
66
73
 
67
- export default function InspectorControlsFill( {
68
- children,
69
- group = 'default',
70
- __experimentalGroup,
71
- resetAllFilter,
72
- } ) {
73
- return (
74
- <PrivateInspectorControlsFill
75
- group={ group }
76
- __experimentalGroup={ __experimentalGroup }
77
- resetAllFilter={ resetAllFilter }
78
- >
79
- { children }
80
- </PrivateInspectorControlsFill>
81
- );
82
- }
83
-
84
74
  function RegisterResetAll( { resetAllFilter, children } ) {
85
75
  const { registerResetAllFilter, deregisterResetAllFilter } =
86
76
  useContext( ToolsPanelContext );
@@ -84,26 +84,29 @@ export default function useInspectorControlsTabs(
84
84
  ...( hasListFills && hasStyleFills > 1 ? advancedFills : [] ),
85
85
  ];
86
86
 
87
+ // When the block fields experiment is active, only rely on `hasContentFills`
88
+ // to determine whether the content tab to be shown. The tab purely uses slot
89
+ // fills in this situation.
90
+ const shouldShowBlockFields =
91
+ window?.__experimentalContentOnlyInspectorFields;
87
92
  const hasContentTab =
88
93
  hasContentFills ||
89
- !! ( contentClientIds && contentClientIds.length > 0 );
94
+ ( ! shouldShowBlockFields && contentClientIds?.length );
90
95
 
91
- const hasListTab = hasListFills && ! isSectionBlock;
96
+ if ( hasContentTab ) {
97
+ tabs.push( TAB_CONTENT );
98
+ }
92
99
 
93
100
  // Add the tabs in the order that they will default to if available.
94
101
  // List View > Content > Settings > Styles.
95
- if ( hasListTab ) {
102
+ if ( hasListFills ) {
96
103
  tabs.push( TAB_LIST_VIEW );
97
104
  }
98
105
 
99
- if ( hasContentTab ) {
100
- tabs.push( TAB_CONTENT );
101
- }
102
-
103
106
  if (
104
107
  ( settingsFills.length ||
105
108
  // Advanded fills who up in settings tab if available or they blend into the default tab, if there's only one tab.
106
- ( advancedFills.length && ( hasContentTab || hasListTab ) ) ) &&
109
+ ( advancedFills.length && ( hasContentTab || hasListFills ) ) ) &&
107
110
  ! isSectionBlock
108
111
  ) {
109
112
  tabs.push( TAB_SETTINGS );
@@ -1,13 +1,15 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { addFilter } from '@wordpress/hooks';
5
- import { privateApis as blocksPrivateApis } from '@wordpress/blocks';
4
+ import {
5
+ privateApis as blocksPrivateApis,
6
+ getBlockType,
7
+ } from '@wordpress/blocks';
6
8
  import {
7
9
  __experimentalHStack as HStack,
8
10
  __experimentalTruncate as Truncate,
9
11
  } from '@wordpress/components';
10
- import { createHigherOrderComponent } from '@wordpress/compose';
12
+ import { useSelect } from '@wordpress/data';
11
13
  import { DataForm } from '@wordpress/dataviews';
12
14
  import { useContext, useState, useMemo } from '@wordpress/element';
13
15
  import { __ } from '@wordpress/i18n';
@@ -15,6 +17,7 @@ import { __ } from '@wordpress/i18n';
15
17
  /**
16
18
  * Internal dependencies
17
19
  */
20
+ import { store as blockEditorStore } from '../../store';
18
21
  import { unlock } from '../../lock-unlock';
19
22
  import BlockIcon from '../../components/block-icon';
20
23
  import useBlockDisplayTitle from '../../components/block-title/use-block-display-title';
@@ -22,34 +25,23 @@ import useBlockDisplayInformation from '../../components/use-block-display-infor
22
25
  const { fieldsKey, formKey } = unlock( blocksPrivateApis );
23
26
  import FieldsDropdownMenu from './fields-dropdown-menu';
24
27
  import { PrivateBlockContext } from '../../components/block-list/private-block-context';
25
- import { PrivateInspectorControlsFill } from '../../components/inspector-controls/fill';
28
+ import InspectorControls from '../../components/inspector-controls/fill';
26
29
 
27
30
  // controls
28
31
  import RichText from './rich-text';
29
32
  import Media from './media';
30
33
  import Link from './link';
31
34
 
32
- const CONTROLS = {
33
- richtext: RichText,
34
- media: Media,
35
- link: Link,
36
- };
37
-
38
35
  /**
39
36
  * Creates a configured control component that wraps a custom control
40
37
  * and passes configuration as props.
41
38
  *
42
39
  * @param {Component} ControlComponent The React component for the control.
43
- * @param {string} type The type of control.
44
40
  * @param {Object} config The control configuration passed as a prop.
45
41
  *
46
42
  * @return {Function} A wrapped control component
47
43
  */
48
- function createConfiguredControl( ControlComponent, type, config ) {
49
- if ( ! ControlComponent ) {
50
- throw new Error( `Control type "${ type }" not found` );
51
- }
52
-
44
+ function createConfiguredControl( ControlComponent, config = {} ) {
53
45
  return function ConfiguredControl( props ) {
54
46
  return <ControlComponent { ...props } config={ config } />;
55
47
  };
@@ -60,7 +52,6 @@ function createConfiguredControl( ControlComponent, type, config ) {
60
52
  * @param {Object} props
61
53
  * @param {string} props.clientId The clientId of the block.
62
54
  * @param {Object} props.blockType The blockType definition.
63
- * @param {Object} props.attributes The block's attribute values.
64
55
  * @param {Function} props.setAttributes Action to set the block's attributes.
65
56
  * @param {boolean} props.isCollapsed Whether the DataForm is rendered as 'collapsed' with only the first field
66
57
  * displayed by default. When collapsed a dropdown is displayed to allow
@@ -70,7 +61,6 @@ function createConfiguredControl( ControlComponent, type, config ) {
70
61
  function BlockFields( {
71
62
  clientId,
72
63
  blockType,
73
- attributes,
74
64
  setAttributes,
75
65
  isCollapsed = false,
76
66
  } ) {
@@ -82,6 +72,11 @@ function BlockFields( {
82
72
 
83
73
  const blockTypeFields = blockType?.[ fieldsKey ];
84
74
 
75
+ const attributes = useSelect(
76
+ ( select ) => select( blockEditorStore ).getBlockAttributes( clientId ),
77
+ [ clientId ]
78
+ );
79
+
85
80
  const computedForm = useMemo( () => {
86
81
  if ( ! isCollapsed ) {
87
82
  return blockType?.[ formKey ];
@@ -104,51 +99,33 @@ function BlockFields( {
104
99
 
105
100
  return blockTypeFields.map( ( fieldDef ) => {
106
101
  const field = {
107
- id: fieldDef.id,
108
- label: fieldDef.label,
109
- type: fieldDef.type, // Use the field's type; DataForm will use built-in or custom Edit
102
+ ...fieldDef,
110
103
  };
111
104
 
112
- // If the field defines a `mapping`, then custom `getValue` and `setValue`
113
- // implementations are provided.
114
- // These functions map from the inconsistent attribute keys found on blocks
115
- // to consistent keys that the field can use internally (and back again).
116
- // When `mapping` isn't provided, we can use the field API's default
117
- // implementation of these functions.
118
- if ( fieldDef.mapping ) {
119
- field.getValue = ( { item } ) => {
120
- // Extract mapped properties from the block attributes
121
- const mappedValue = {};
122
- Object.entries( fieldDef.mapping ).forEach(
123
- ( [ key, attrKey ] ) => {
124
- mappedValue[ key ] = item[ attrKey ];
125
- }
126
- );
127
- return mappedValue;
128
- };
129
- field.setValue = ( { value } ) => {
130
- const attributeUpdates = {};
131
- Object.entries( fieldDef.mapping ).forEach(
132
- ( [ key, attrKey ] ) => {
133
- attributeUpdates[ attrKey ] = value[ key ];
134
- }
135
- );
136
- return attributeUpdates;
137
- };
138
- }
139
-
140
- // Only add custom Edit component if one exists for this type
141
- const ControlComponent = CONTROLS[ fieldDef.type ];
142
- if ( ControlComponent ) {
143
- // Use EditConfig pattern: Edit is an object with control type and config props
144
- field.Edit = createConfiguredControl(
145
- ControlComponent,
146
- fieldDef.type,
147
- {
148
- clientId,
149
- fieldDef,
150
- }
151
- );
105
+ // These should be custom Edit components, not replaced here.
106
+ //
107
+ // - rich-text control: it needs clientId
108
+ // - link control: does not need anything extra
109
+ // - media control: needs the Edit config
110
+ if (
111
+ 'string' === typeof fieldDef.Edit &&
112
+ fieldDef.Edit === 'rich-text'
113
+ ) {
114
+ field.Edit = createConfiguredControl( RichText, {
115
+ clientId,
116
+ } );
117
+ } else if (
118
+ 'string' === typeof fieldDef.Edit &&
119
+ fieldDef.Edit === 'link'
120
+ ) {
121
+ field.Edit = createConfiguredControl( Link );
122
+ } else if (
123
+ 'object' === typeof fieldDef.Edit &&
124
+ fieldDef.Edit.control === 'media'
125
+ ) {
126
+ field.Edit = createConfiguredControl( Media, {
127
+ ...fieldDef.Edit,
128
+ } );
152
129
  }
153
130
 
154
131
  return field;
@@ -216,56 +193,34 @@ function BlockFields( {
216
193
  );
217
194
  }
218
195
 
219
- const withBlockFields = createHigherOrderComponent(
220
- ( BlockEdit ) => ( props ) => {
221
- const {
222
- blockType,
223
- isSelectionWithinCurrentSection,
224
- isSectionBlock,
225
- blockEditingMode,
226
- isSelected,
227
- } = useContext( PrivateBlockContext );
228
-
229
- const shouldShowBlockFields =
230
- window?.__experimentalContentOnlyInspectorFields;
231
- const blockTypeFields = blockType?.[ fieldsKey ];
196
+ function hasBlockFieldsSupport( blockName ) {
197
+ return !! (
198
+ window?.__experimentalContentOnlyInspectorFields &&
199
+ getBlockType( blockName )?.[ fieldsKey ]
200
+ );
201
+ }
232
202
 
233
- if ( ! shouldShowBlockFields || ! blockTypeFields?.length ) {
234
- return <BlockEdit key="edit" { ...props } />;
235
- }
203
+ export function BlockFieldsPanel( props ) {
204
+ const { blockType, isSelectionWithinCurrentSection } =
205
+ useContext( PrivateBlockContext );
236
206
 
237
- return (
238
- <>
239
- <BlockEdit key="edit" { ...props } />
240
- {
241
- // Display the controls of all inner blocks for section/pattern editing.
242
- isSelectionWithinCurrentSection &&
243
- ( isSectionBlock ||
244
- blockEditingMode === 'contentOnly' ) && (
245
- <PrivateInspectorControlsFill
246
- group="content"
247
- forceDisplayControls
248
- >
249
- <BlockFields
250
- { ...props }
251
- blockType={ blockType }
252
- isCollapsed
253
- />
254
- </PrivateInspectorControlsFill>
255
- )
256
- }
257
- { ! isSelectionWithinCurrentSection && isSelected && (
258
- <PrivateInspectorControlsFill group="content">
259
- <BlockFields { ...props } blockType={ blockType } />
260
- </PrivateInspectorControlsFill>
261
- ) }
262
- </>
263
- );
264
- }
265
- );
207
+ return (
208
+ <InspectorControls group="content">
209
+ <BlockFields
210
+ { ...props }
211
+ blockType={ blockType }
212
+ isCollapsed={ isSelectionWithinCurrentSection }
213
+ />
214
+ </InspectorControls>
215
+ );
216
+ }
266
217
 
267
- addFilter(
268
- 'editor.BlockEdit',
269
- 'core/content-only-controls/block-fields',
270
- withBlockFields
271
- );
218
+ /**
219
+ * Export block support definition.
220
+ */
221
+ export default {
222
+ edit: BlockFieldsPanel,
223
+ hasSupport: hasBlockFieldsSupport,
224
+ attributeKeys: [],
225
+ supportsPatternEditing: true,
226
+ };
@@ -67,12 +67,11 @@ export function getUpdatedLinkAttributes( {
67
67
  };
68
68
  }
69
69
 
70
- export default function Link( { data, field, onChange, config = {} } ) {
70
+ export default function Link( { data, field, onChange } ) {
71
71
  const [ isLinkControlOpen, setIsLinkControlOpen ] = useState( false );
72
72
  const { popoverProps } = useInspectorPopoverPlacement( {
73
73
  isControl: true,
74
74
  } );
75
- const { fieldDef } = config;
76
75
  const value = field.getValue( { item: data } );
77
76
  const url = value?.url;
78
77
  const rel = value?.rel || '';
@@ -148,21 +147,10 @@ export default function Link( { data, field, onChange, config = {} } ) {
148
147
  );
149
148
  } }
150
149
  onRemove={ () => {
151
- // Remove all link-related properties based on what's in the mapping
152
- const removeValue = {};
153
-
154
- if ( fieldDef?.mapping ) {
155
- Object.keys( fieldDef.mapping ).forEach(
156
- ( key ) => {
157
- removeValue[ key ] = undefined;
158
- }
159
- );
160
- }
161
-
162
150
  onChange(
163
151
  field.setValue( {
164
152
  item: data,
165
- value: removeValue,
153
+ value: {},
166
154
  } )
167
155
  );
168
156
  } }