@wordpress/block-editor 15.10.1-next.79a2f3cdd.0 → 15.10.1-next.ba3aee3a2.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 (97) hide show
  1. package/build/components/block-edit/context.cjs +5 -5
  2. package/build/components/block-edit/context.cjs.map +1 -1
  3. package/build/components/block-list/block.cjs +24 -12
  4. package/build/components/block-list/block.cjs.map +3 -3
  5. package/build/components/block-list/use-block-props/index.cjs +8 -2
  6. package/build/components/block-list/use-block-props/index.cjs.map +2 -2
  7. package/build/components/block-visibility/constants.cjs +49 -0
  8. package/build/components/block-visibility/constants.cjs.map +7 -0
  9. package/build/components/block-visibility/index.cjs +5 -2
  10. package/build/components/block-visibility/index.cjs.map +2 -2
  11. package/build/components/block-visibility/use-block-visibility.cjs +69 -0
  12. package/build/components/block-visibility/use-block-visibility.cjs.map +7 -0
  13. package/build/components/collab/block-comment-icon-slot.cjs +1 -1
  14. package/build/components/collab/block-comment-icon-slot.cjs.map +1 -1
  15. package/build/components/collab/block-comment-icon-toolbar-slot.cjs +1 -1
  16. package/build/components/collab/block-comment-icon-toolbar-slot.cjs.map +1 -1
  17. package/build/components/inspector-controls/groups.cjs +1 -1
  18. package/build/components/inspector-controls/groups.cjs.map +1 -1
  19. package/build/components/inspector-controls-tabs/content-tab.cjs +1 -1
  20. package/build/components/inspector-controls-tabs/content-tab.cjs.map +2 -2
  21. package/build/components/list-view/index.cjs +11 -6
  22. package/build/components/list-view/index.cjs.map +2 -2
  23. package/build/components/list-view/utils.cjs +24 -17
  24. package/build/components/list-view/utils.cjs.map +2 -2
  25. package/build/components/rich-text/event-listeners/input-rules.cjs +13 -1
  26. package/build/components/rich-text/event-listeners/input-rules.cjs.map +2 -2
  27. package/build/components/rich-text/format-edit.cjs +1 -1
  28. package/build/components/rich-text/format-edit.cjs.map +1 -1
  29. package/build/components/rich-text/index.cjs +1 -1
  30. package/build/components/rich-text/index.cjs.map +1 -1
  31. package/build/components/writing-flow/utils.cjs +1 -1
  32. package/build/components/writing-flow/utils.cjs.map +1 -1
  33. package/build/hooks/block-fields/index.cjs +1 -1
  34. package/build/hooks/block-fields/index.cjs.map +2 -2
  35. package/build/hooks/fit-text.cjs +1 -1
  36. package/build/hooks/fit-text.cjs.map +1 -1
  37. package/build/store/private-keys.cjs +10 -10
  38. package/build/store/private-keys.cjs.map +1 -1
  39. package/build/store/utils.cjs +1 -1
  40. package/build/store/utils.cjs.map +1 -1
  41. package/build-module/components/block-edit/context.mjs +5 -5
  42. package/build-module/components/block-edit/context.mjs.map +1 -1
  43. package/build-module/components/block-list/block.mjs +24 -12
  44. package/build-module/components/block-list/block.mjs.map +3 -3
  45. package/build-module/components/block-list/use-block-props/index.mjs +8 -2
  46. package/build-module/components/block-list/use-block-props/index.mjs.map +2 -2
  47. package/build-module/components/block-visibility/constants.mjs +24 -0
  48. package/build-module/components/block-visibility/constants.mjs.map +7 -0
  49. package/build-module/components/block-visibility/index.mjs +3 -1
  50. package/build-module/components/block-visibility/index.mjs.map +2 -2
  51. package/build-module/components/block-visibility/use-block-visibility.mjs +44 -0
  52. package/build-module/components/block-visibility/use-block-visibility.mjs.map +7 -0
  53. package/build-module/components/collab/block-comment-icon-slot.mjs +1 -1
  54. package/build-module/components/collab/block-comment-icon-slot.mjs.map +1 -1
  55. package/build-module/components/collab/block-comment-icon-toolbar-slot.mjs +1 -1
  56. package/build-module/components/collab/block-comment-icon-toolbar-slot.mjs.map +1 -1
  57. package/build-module/components/inspector-controls/groups.mjs +1 -1
  58. package/build-module/components/inspector-controls/groups.mjs.map +1 -1
  59. package/build-module/components/inspector-controls-tabs/content-tab.mjs +1 -1
  60. package/build-module/components/inspector-controls-tabs/content-tab.mjs.map +2 -2
  61. package/build-module/components/list-view/index.mjs +11 -7
  62. package/build-module/components/list-view/index.mjs.map +2 -2
  63. package/build-module/components/list-view/utils.mjs +24 -17
  64. package/build-module/components/list-view/utils.mjs.map +2 -2
  65. package/build-module/components/rich-text/event-listeners/input-rules.mjs +13 -1
  66. package/build-module/components/rich-text/event-listeners/input-rules.mjs.map +2 -2
  67. package/build-module/components/rich-text/format-edit.mjs +1 -1
  68. package/build-module/components/rich-text/format-edit.mjs.map +1 -1
  69. package/build-module/components/rich-text/index.mjs +1 -1
  70. package/build-module/components/rich-text/index.mjs.map +1 -1
  71. package/build-module/components/writing-flow/utils.mjs +1 -1
  72. package/build-module/components/writing-flow/utils.mjs.map +1 -1
  73. package/build-module/hooks/block-fields/index.mjs +1 -1
  74. package/build-module/hooks/block-fields/index.mjs.map +2 -2
  75. package/build-module/hooks/fit-text.mjs +1 -1
  76. package/build-module/hooks/fit-text.mjs.map +1 -1
  77. package/build-module/store/private-keys.mjs +10 -10
  78. package/build-module/store/private-keys.mjs.map +1 -1
  79. package/build-module/store/utils.mjs +1 -1
  80. package/build-module/store/utils.mjs.map +1 -1
  81. package/build-style/style-rtl.css +6 -1
  82. package/build-style/style.css +6 -1
  83. package/package.json +39 -39
  84. package/src/components/block-list/block.js +23 -9
  85. package/src/components/block-list/use-block-props/index.js +10 -2
  86. package/src/components/block-toolbar/style.scss +0 -1
  87. package/src/components/block-tools/style.scss +10 -0
  88. package/src/components/block-visibility/constants.js +29 -0
  89. package/src/components/block-visibility/index.js +1 -0
  90. package/src/components/block-visibility/test/use-block-visibility.js +360 -0
  91. package/src/components/block-visibility/use-block-visibility.js +73 -0
  92. package/src/components/inspector-controls-tabs/content-tab.js +0 -1
  93. package/src/components/list-view/index.js +15 -11
  94. package/src/components/list-view/utils.js +31 -23
  95. package/src/components/rich-text/event-listeners/input-rules.js +17 -0
  96. package/src/hooks/block-fields/index.js +0 -1
  97. package/src/hooks/fit-text.js +1 -1
@@ -0,0 +1,73 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useViewportMatch } from '@wordpress/compose';
5
+ import { useMemo } from '@wordpress/element';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { BLOCK_VISIBILITY_VIEWPORTS } from './constants';
11
+
12
+ /**
13
+ * Determines if a block should be hidden based on visibility settings.
14
+ *
15
+ * Priority:
16
+ * 1. Device type override (Mobile/Tablet) - uses device type to determine viewport
17
+ * 2. Actual window size (Desktop mode) - uses viewport detection
18
+ *
19
+ * @param {Object} options Parameters to avoid extra store subscriptions.
20
+ * @param {Object|boolean} options.blockVisibility Block visibility metadata.
21
+ * @param {string} options.deviceType Current device type ('desktop', 'tablet', 'mobile').
22
+ * @return {Object} Object with `isBlockCurrentlyHidden` boolean property.
23
+ */
24
+ export function useBlockVisibility( options = {} ) {
25
+ const {
26
+ blockVisibility = undefined,
27
+ deviceType = BLOCK_VISIBILITY_VIEWPORTS.desktop.value,
28
+ } = options;
29
+
30
+ const isLargerThanMobile = useViewportMatch( 'mobile', '>=' ); // >= 480px
31
+ const isLargerThanTablet = useViewportMatch( 'medium', '>=' ); // >= 782px
32
+
33
+ /*
34
+ * When Desktop is selected, use actual viewport detection.
35
+ * When Mobile/Tablet is selected, override with device type.
36
+ */
37
+ const currentViewport = useMemo( () => {
38
+ if ( deviceType === BLOCK_VISIBILITY_VIEWPORTS.mobile.value ) {
39
+ return BLOCK_VISIBILITY_VIEWPORTS.mobile.value;
40
+ }
41
+ if ( deviceType === BLOCK_VISIBILITY_VIEWPORTS.tablet.value ) {
42
+ return BLOCK_VISIBILITY_VIEWPORTS.tablet.value;
43
+ }
44
+ if ( ! isLargerThanMobile ) {
45
+ return BLOCK_VISIBILITY_VIEWPORTS.mobile.value;
46
+ }
47
+ if ( isLargerThanMobile && ! isLargerThanTablet ) {
48
+ return BLOCK_VISIBILITY_VIEWPORTS.tablet.value;
49
+ }
50
+ return BLOCK_VISIBILITY_VIEWPORTS.desktop.value;
51
+ }, [ deviceType, isLargerThanMobile, isLargerThanTablet ] );
52
+
53
+ // Determine if block is currently hidden.
54
+ const isBlockCurrentlyHidden = useMemo( () => {
55
+ if ( blockVisibility === false ) {
56
+ return true;
57
+ }
58
+
59
+ if (
60
+ window.__experimentalHideBlocksBasedOnScreenSize &&
61
+ blockVisibility?.[ currentViewport ] === false
62
+ ) {
63
+ return true;
64
+ }
65
+
66
+ return false;
67
+ }, [ blockVisibility, currentViewport ] );
68
+
69
+ return useMemo(
70
+ () => ( { isBlockCurrentlyHidden, currentViewport } ),
71
+ [ isBlockCurrentlyHidden, currentViewport ]
72
+ );
73
+ }
@@ -15,7 +15,6 @@ const ContentTab = ( { contentClientIds } ) => {
15
15
  }
16
16
 
17
17
  const shouldShowBlockFields =
18
- window?.__experimentalContentOnlyPatternInsertion &&
19
18
  window?.__experimentalContentOnlyInspectorFields;
20
19
 
21
20
  return (
@@ -19,7 +19,6 @@ import { AsyncModeProvider, useSelect } from '@wordpress/data';
19
19
  import deprecated from '@wordpress/deprecated';
20
20
  import {
21
21
  useCallback,
22
- useEffect,
23
22
  useMemo,
24
23
  useRef,
25
24
  useReducer,
@@ -118,7 +117,8 @@ function ListViewComponent(
118
117
  useListViewClientIds( { blocks, rootClientId } );
119
118
  const blockIndexes = useListViewBlockIndexes( clientIdsTree );
120
119
 
121
- const { getBlock } = useSelect( blockEditorStore );
120
+ const { getBlock, getSelectedBlockClientIds } =
121
+ useSelect( blockEditorStore );
122
122
  const { visibleBlockCount } = useSelect(
123
123
  ( select ) => {
124
124
  const { getGlobalBlockCount, getClientIdsOfDescendants } =
@@ -172,22 +172,26 @@ function ListViewComponent(
172
172
  selectBlock: selectEditorBlock,
173
173
  } );
174
174
 
175
+ const focusSelectedBlock = useCallback(
176
+ ( node ) => {
177
+ const [ firstSelectedClientId ] = getSelectedBlockClientIds();
178
+ // If a blocks are already selected when the list view is initially
179
+ // mounted, shift focus to the first selected block.
180
+ if ( firstSelectedClientId && node ) {
181
+ focusListItem( firstSelectedClientId, node );
182
+ }
183
+ },
184
+ [ getSelectedBlockClientIds ]
185
+ );
186
+
175
187
  const treeGridRef = useMergeRefs( [
176
188
  clipBoardRef,
189
+ focusSelectedBlock,
177
190
  elementRef,
178
191
  dropZoneRef,
179
192
  ref,
180
193
  ] );
181
194
 
182
- useEffect( () => {
183
- // If a blocks are already selected when the list view is initially
184
- // mounted, shift focus to the first selected block.
185
- if ( selectedClientIds?.length ) {
186
- focusListItem( selectedClientIds[ 0 ], elementRef?.current );
187
- }
188
- // Only focus on the selected item when the list view is mounted.
189
- }, [] );
190
-
191
195
  const expand = useCallback(
192
196
  ( clientId ) => {
193
197
  if ( ! clientId ) {
@@ -81,33 +81,41 @@ export function getCommonDepthClientIds(
81
81
  * @param {?HTMLElement} treeGridElement The container element to search within.
82
82
  */
83
83
  export function focusListItem( focusClientId, treeGridElement ) {
84
- const getFocusElement = () => {
85
- const row = treeGridElement?.querySelector(
86
- `[role=row][data-block="${ focusClientId }"]`
87
- );
88
- if ( ! row ) {
89
- return null;
84
+ if ( ! treeGridElement ) {
85
+ return;
86
+ }
87
+
88
+ const selector = `[role=row][data-block="${ focusClientId }"]`;
89
+
90
+ return new Promise( ( resolve ) => {
91
+ if ( treeGridElement.querySelector( selector ) ) {
92
+ return resolve( treeGridElement.querySelector( selector ) );
90
93
  }
91
- // Focus the first focusable in the row, which is the ListViewBlockSelectButton.
92
- return focus.focusable.find( row )[ 0 ];
93
- };
94
94
 
95
- let focusElement = getFocusElement();
96
- if ( focusElement ) {
97
- focusElement.focus();
98
- } else {
99
- // The element hasn't been painted yet. Defer focusing on the next frame.
100
- // This could happen when all blocks have been deleted and the default block
101
- // hasn't been added to the editor yet.
102
- window.requestAnimationFrame( () => {
103
- focusElement = getFocusElement();
104
-
105
- // Ignore if the element still doesn't exist.
106
- if ( focusElement ) {
107
- focusElement.focus();
95
+ let timer = null;
96
+ // Wait for the element to be added to the DOM.
97
+ const observer = new window.MutationObserver( () => {
98
+ if ( treeGridElement.querySelector( selector ) ) {
99
+ clearTimeout( timer );
100
+ observer.disconnect();
101
+ resolve( treeGridElement.querySelector( selector ) );
108
102
  }
109
103
  } );
110
- }
104
+
105
+ observer.observe( treeGridElement, {
106
+ childList: true,
107
+ subtree: true,
108
+ } );
109
+
110
+ // Stop trying after 3 seconds.
111
+ timer = setTimeout( () => {
112
+ observer.disconnect();
113
+ resolve( null );
114
+ }, 3000 );
115
+ } ).then( ( element ) => {
116
+ // Focus the first focusable in the row, which is the ListViewBlockSelectButton.
117
+ focus.focusable.find( element )?.[ 0 ]?.focus();
118
+ } );
111
119
  }
112
120
 
113
121
  /**
@@ -99,6 +99,7 @@ export default ( props ) => ( element ) => {
99
99
  __unstableAllowPrefixTransformations,
100
100
  formatTypes,
101
101
  registry,
102
+ onReplace,
102
103
  } = props.current;
103
104
 
104
105
  // Only run input rules when inserting text.
@@ -111,6 +112,22 @@ export default ( props ) => ( element ) => {
111
112
  }
112
113
 
113
114
  const value = getValue();
115
+
116
+ const transforms = getBlockTransforms( 'from' ).filter(
117
+ ( transform ) => transform.type === 'input'
118
+ );
119
+ const transformation = findTransform( transforms, ( item ) => {
120
+ return item.regExp.test( value.text );
121
+ } );
122
+
123
+ if ( transformation ) {
124
+ onReplace( transformation.transform() );
125
+ registry
126
+ .dispatch( blockEditorStore )
127
+ .__unstableMarkAutomaticChange();
128
+ return;
129
+ }
130
+
114
131
  const transformed = formatTypes.reduce(
115
132
  ( accumulator, { __unstableInputRule } ) => {
116
133
  if ( __unstableInputRule ) {
@@ -348,7 +348,6 @@ const withBlockFields = createHigherOrderComponent(
348
348
  } = useContext( PrivateBlockContext );
349
349
 
350
350
  const shouldShowBlockFields =
351
- window?.__experimentalContentOnlyPatternInsertion &&
352
351
  window?.__experimentalContentOnlyInspectorFields;
353
352
  const blockTypeFields = blockType?.[ fieldsKey ];
354
353
 
@@ -13,7 +13,7 @@ import {
13
13
  import { createHigherOrderComponent } from '@wordpress/compose';
14
14
 
15
15
  const EMPTY_OBJECT = {};
16
- const MIN_FONT_SIZE_FOR_WARNING = 6;
16
+ const MIN_FONT_SIZE_FOR_WARNING = 12;
17
17
 
18
18
  /**
19
19
  * Internal dependencies