@wordpress/block-editor 15.10.1-next.79a2f3cdd.0 → 15.10.1-next.v.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 (228) hide show
  1. package/build/components/block-bindings/attribute-control.cjs +1 -1
  2. package/build/components/block-bindings/attribute-control.cjs.map +1 -1
  3. package/build/components/block-bindings/source-fields-list.cjs +1 -1
  4. package/build/components/block-bindings/source-fields-list.cjs.map +1 -1
  5. package/build/components/block-edit/context.cjs +5 -5
  6. package/build/components/block-edit/context.cjs.map +1 -1
  7. package/build/components/block-list/block.cjs +24 -12
  8. package/build/components/block-list/block.cjs.map +3 -3
  9. package/build/components/block-list/use-block-props/index.cjs +8 -2
  10. package/build/components/block-list/use-block-props/index.cjs.map +2 -2
  11. package/build/components/block-tools/index.cjs +82 -70
  12. package/build/components/block-tools/index.cjs.map +2 -2
  13. package/build/components/block-visibility/block-visibility-info.cjs +0 -59
  14. package/build/components/block-visibility/block-visibility-info.cjs.map +3 -3
  15. package/build/components/block-visibility/constants.cjs +54 -0
  16. package/build/components/block-visibility/constants.cjs.map +7 -0
  17. package/build/components/block-visibility/index.cjs +15 -4
  18. package/build/components/block-visibility/index.cjs.map +3 -3
  19. package/build/components/block-visibility/modal.cjs +397 -0
  20. package/build/components/block-visibility/modal.cjs.map +7 -0
  21. package/build/components/block-visibility/toolbar.cjs +1 -1
  22. package/build/components/block-visibility/toolbar.cjs.map +2 -2
  23. package/build/components/block-visibility/use-block-visibility.cjs +65 -0
  24. package/build/components/block-visibility/use-block-visibility.cjs.map +7 -0
  25. package/build/components/block-visibility/utils.cjs +81 -0
  26. package/build/components/block-visibility/utils.cjs.map +7 -0
  27. package/build/components/block-visibility/viewport-menu-item.cjs +61 -0
  28. package/build/components/block-visibility/viewport-menu-item.cjs.map +7 -0
  29. package/build/components/block-visibility/viewport-toolbar.cjs +89 -0
  30. package/build/components/block-visibility/viewport-toolbar.cjs.map +7 -0
  31. package/build/components/collab/block-comment-icon-slot.cjs +1 -1
  32. package/build/components/collab/block-comment-icon-slot.cjs.map +1 -1
  33. package/build/components/collab/block-comment-icon-toolbar-slot.cjs +1 -1
  34. package/build/components/collab/block-comment-icon-toolbar-slot.cjs.map +1 -1
  35. package/build/components/inner-blocks/use-inner-block-template-sync.cjs +1 -1
  36. package/build/components/inner-blocks/use-inner-block-template-sync.cjs.map +1 -1
  37. package/build/components/inserter/menu.cjs +6 -2
  38. package/build/components/inserter/menu.cjs.map +2 -2
  39. package/build/components/inspector-controls/groups.cjs +1 -1
  40. package/build/components/inspector-controls/groups.cjs.map +1 -1
  41. package/build/components/inspector-controls-tabs/content-tab.cjs +1 -1
  42. package/build/components/inspector-controls-tabs/content-tab.cjs.map +2 -2
  43. package/build/components/list-view/block-select-button.cjs +2 -2
  44. package/build/components/list-view/block-select-button.cjs.map +2 -2
  45. package/build/components/list-view/block.cjs +39 -22
  46. package/build/components/list-view/block.cjs.map +2 -2
  47. package/build/components/list-view/index.cjs +11 -6
  48. package/build/components/list-view/index.cjs.map +2 -2
  49. package/build/components/list-view/utils.cjs +24 -17
  50. package/build/components/list-view/utils.cjs.map +2 -2
  51. package/build/components/rich-text/event-listeners/input-rules.cjs +13 -1
  52. package/build/components/rich-text/event-listeners/input-rules.cjs.map +2 -2
  53. package/build/components/rich-text/format-edit.cjs +1 -1
  54. package/build/components/rich-text/format-edit.cjs.map +1 -1
  55. package/build/components/rich-text/index.cjs +2 -2
  56. package/build/components/rich-text/index.cjs.map +2 -2
  57. package/build/components/url-input/index.cjs +2 -0
  58. package/build/components/url-input/index.cjs.map +2 -2
  59. package/build/components/use-block-commands/index.cjs +1 -1
  60. package/build/components/use-block-commands/index.cjs.map +2 -2
  61. package/build/components/writing-flow/utils.cjs +1 -1
  62. package/build/components/writing-flow/utils.cjs.map +1 -1
  63. package/build/hooks/block-fields/index.cjs +76 -167
  64. package/build/hooks/block-fields/index.cjs.map +2 -2
  65. package/build/hooks/block-fields/link/index.cjs +13 -23
  66. package/build/hooks/block-fields/link/index.cjs.map +2 -2
  67. package/build/hooks/block-fields/media/index.cjs +32 -58
  68. package/build/hooks/block-fields/media/index.cjs.map +2 -2
  69. package/build/hooks/block-fields/rich-text/index.cjs +1 -5
  70. package/build/hooks/block-fields/rich-text/index.cjs.map +2 -2
  71. package/build/hooks/cross-origin-isolation.cjs +102 -0
  72. package/build/hooks/cross-origin-isolation.cjs.map +7 -0
  73. package/build/hooks/fit-text.cjs +1 -1
  74. package/build/hooks/fit-text.cjs.map +1 -1
  75. package/build/hooks/index.cjs +1 -0
  76. package/build/hooks/index.cjs.map +2 -2
  77. package/build/layouts/flex.cjs +6 -2
  78. package/build/layouts/flex.cjs.map +2 -2
  79. package/build/store/private-keys.cjs +10 -10
  80. package/build/store/private-keys.cjs.map +1 -1
  81. package/build/store/private-selectors.cjs +33 -1
  82. package/build/store/private-selectors.cjs.map +3 -3
  83. package/build/store/reducer.cjs +1 -1
  84. package/build/store/reducer.cjs.map +1 -1
  85. package/build/store/selectors.cjs +7 -8
  86. package/build/store/selectors.cjs.map +2 -2
  87. package/build/store/utils.cjs +1 -1
  88. package/build/store/utils.cjs.map +1 -1
  89. package/build-module/components/block-bindings/attribute-control.mjs +1 -1
  90. package/build-module/components/block-bindings/attribute-control.mjs.map +1 -1
  91. package/build-module/components/block-bindings/source-fields-list.mjs +1 -1
  92. package/build-module/components/block-bindings/source-fields-list.mjs.map +1 -1
  93. package/build-module/components/block-edit/context.mjs +5 -5
  94. package/build-module/components/block-edit/context.mjs.map +1 -1
  95. package/build-module/components/block-list/block.mjs +24 -12
  96. package/build-module/components/block-list/block.mjs.map +3 -3
  97. package/build-module/components/block-list/use-block-props/index.mjs +8 -2
  98. package/build-module/components/block-list/use-block-props/index.mjs.map +2 -2
  99. package/build-module/components/block-tools/index.mjs +85 -73
  100. package/build-module/components/block-tools/index.mjs.map +2 -2
  101. package/build-module/components/block-visibility/block-visibility-info.mjs +0 -59
  102. package/build-module/components/block-visibility/block-visibility-info.mjs.map +3 -3
  103. package/build-module/components/block-visibility/constants.mjs +28 -0
  104. package/build-module/components/block-visibility/constants.mjs.map +7 -0
  105. package/build-module/components/block-visibility/index.mjs +13 -4
  106. package/build-module/components/block-visibility/index.mjs.map +2 -2
  107. package/build-module/components/block-visibility/modal.mjs +384 -0
  108. package/build-module/components/block-visibility/modal.mjs.map +7 -0
  109. package/build-module/components/block-visibility/toolbar.mjs +1 -1
  110. package/build-module/components/block-visibility/toolbar.mjs.map +2 -2
  111. package/build-module/components/block-visibility/use-block-visibility.mjs +44 -0
  112. package/build-module/components/block-visibility/use-block-visibility.mjs.map +7 -0
  113. package/build-module/components/block-visibility/utils.mjs +55 -0
  114. package/build-module/components/block-visibility/utils.mjs.map +7 -0
  115. package/build-module/components/block-visibility/viewport-menu-item.mjs +40 -0
  116. package/build-module/components/block-visibility/viewport-menu-item.mjs.map +7 -0
  117. package/build-module/components/block-visibility/viewport-toolbar.mjs +68 -0
  118. package/build-module/components/block-visibility/viewport-toolbar.mjs.map +7 -0
  119. package/build-module/components/collab/block-comment-icon-slot.mjs +1 -1
  120. package/build-module/components/collab/block-comment-icon-slot.mjs.map +1 -1
  121. package/build-module/components/collab/block-comment-icon-toolbar-slot.mjs +1 -1
  122. package/build-module/components/collab/block-comment-icon-toolbar-slot.mjs.map +1 -1
  123. package/build-module/components/inner-blocks/use-inner-block-template-sync.mjs +1 -1
  124. package/build-module/components/inner-blocks/use-inner-block-template-sync.mjs.map +1 -1
  125. package/build-module/components/inserter/menu.mjs +6 -2
  126. package/build-module/components/inserter/menu.mjs.map +2 -2
  127. package/build-module/components/inspector-controls/groups.mjs +1 -1
  128. package/build-module/components/inspector-controls/groups.mjs.map +1 -1
  129. package/build-module/components/inspector-controls-tabs/content-tab.mjs +1 -1
  130. package/build-module/components/inspector-controls-tabs/content-tab.mjs.map +2 -2
  131. package/build-module/components/list-view/block-select-button.mjs +2 -2
  132. package/build-module/components/list-view/block-select-button.mjs.map +2 -2
  133. package/build-module/components/list-view/block.mjs +39 -22
  134. package/build-module/components/list-view/block.mjs.map +2 -2
  135. package/build-module/components/list-view/index.mjs +11 -7
  136. package/build-module/components/list-view/index.mjs.map +2 -2
  137. package/build-module/components/list-view/utils.mjs +24 -17
  138. package/build-module/components/list-view/utils.mjs.map +2 -2
  139. package/build-module/components/rich-text/event-listeners/input-rules.mjs +13 -1
  140. package/build-module/components/rich-text/event-listeners/input-rules.mjs.map +2 -2
  141. package/build-module/components/rich-text/format-edit.mjs +1 -1
  142. package/build-module/components/rich-text/format-edit.mjs.map +1 -1
  143. package/build-module/components/rich-text/index.mjs +2 -2
  144. package/build-module/components/rich-text/index.mjs.map +2 -2
  145. package/build-module/components/url-input/index.mjs +2 -0
  146. package/build-module/components/url-input/index.mjs.map +2 -2
  147. package/build-module/components/use-block-commands/index.mjs +1 -1
  148. package/build-module/components/use-block-commands/index.mjs.map +2 -2
  149. package/build-module/components/writing-flow/utils.mjs +1 -1
  150. package/build-module/components/writing-flow/utils.mjs.map +1 -1
  151. package/build-module/hooks/block-fields/index.mjs +76 -167
  152. package/build-module/hooks/block-fields/index.mjs.map +2 -2
  153. package/build-module/hooks/block-fields/link/index.mjs +13 -23
  154. package/build-module/hooks/block-fields/link/index.mjs.map +2 -2
  155. package/build-module/hooks/block-fields/media/index.mjs +32 -58
  156. package/build-module/hooks/block-fields/media/index.mjs.map +2 -2
  157. package/build-module/hooks/block-fields/rich-text/index.mjs +1 -5
  158. package/build-module/hooks/block-fields/rich-text/index.mjs.map +2 -2
  159. package/build-module/hooks/cross-origin-isolation.mjs +100 -0
  160. package/build-module/hooks/cross-origin-isolation.mjs.map +7 -0
  161. package/build-module/hooks/fit-text.mjs +1 -1
  162. package/build-module/hooks/fit-text.mjs.map +1 -1
  163. package/build-module/hooks/index.mjs +1 -0
  164. package/build-module/hooks/index.mjs.map +2 -2
  165. package/build-module/layouts/flex.mjs +6 -2
  166. package/build-module/layouts/flex.mjs.map +2 -2
  167. package/build-module/store/private-keys.mjs +10 -10
  168. package/build-module/store/private-keys.mjs.map +1 -1
  169. package/build-module/store/private-selectors.mjs +34 -1
  170. package/build-module/store/private-selectors.mjs.map +2 -2
  171. package/build-module/store/reducer.mjs +1 -1
  172. package/build-module/store/reducer.mjs.map +1 -1
  173. package/build-module/store/selectors.mjs +7 -8
  174. package/build-module/store/selectors.mjs.map +2 -2
  175. package/build-module/store/utils.mjs +1 -1
  176. package/build-module/store/utils.mjs.map +1 -1
  177. package/build-style/content-rtl.css +4 -1
  178. package/build-style/content.css +4 -1
  179. package/build-style/style-rtl.css +54 -1
  180. package/build-style/style.css +54 -1
  181. package/package.json +39 -39
  182. package/src/components/block-bindings/attribute-control.js +1 -1
  183. package/src/components/block-bindings/source-fields-list.js +1 -1
  184. package/src/components/block-list/block.js +23 -9
  185. package/src/components/block-list/content.scss +4 -1
  186. package/src/components/block-list/use-block-props/index.js +10 -2
  187. package/src/components/block-toolbar/style.scss +0 -1
  188. package/src/components/block-tools/index.js +45 -33
  189. package/src/components/block-tools/style.scss +10 -0
  190. package/src/components/block-visibility/block-visibility-info.js +0 -1
  191. package/src/components/block-visibility/constants.js +33 -0
  192. package/src/components/block-visibility/index.js +21 -2
  193. package/src/components/block-visibility/modal.js +358 -0
  194. package/src/components/block-visibility/style.scss +58 -0
  195. package/src/components/block-visibility/test/use-block-visibility.js +316 -0
  196. package/src/components/block-visibility/test/utils.js +266 -0
  197. package/src/components/block-visibility/toolbar.js +1 -1
  198. package/src/components/block-visibility/use-block-visibility.js +70 -0
  199. package/src/components/block-visibility/utils.js +95 -0
  200. package/src/components/block-visibility/viewport-menu-item.js +42 -0
  201. package/src/components/block-visibility/viewport-toolbar.js +88 -0
  202. package/src/components/inner-blocks/use-inner-block-template-sync.js +1 -1
  203. package/src/components/inserter/menu.js +6 -2
  204. package/src/components/inspector-controls-tabs/content-tab.js +0 -1
  205. package/src/components/list-view/block-select-button.js +2 -2
  206. package/src/components/list-view/block.js +47 -25
  207. package/src/components/list-view/index.js +15 -11
  208. package/src/components/list-view/utils.js +31 -23
  209. package/src/components/rich-text/event-listeners/input-rules.js +17 -0
  210. package/src/components/rich-text/index.js +1 -1
  211. package/src/components/url-input/index.js +2 -0
  212. package/src/components/use-block-commands/index.js +4 -3
  213. package/src/hooks/block-fields/index.js +104 -225
  214. package/src/hooks/block-fields/link/index.js +13 -39
  215. package/src/hooks/block-fields/media/index.js +31 -90
  216. package/src/hooks/block-fields/rich-text/index.js +1 -5
  217. package/src/hooks/block-fields/styles.scss +2 -0
  218. package/src/hooks/cross-origin-isolation.js +143 -0
  219. package/src/hooks/fit-text.js +1 -1
  220. package/src/hooks/index.js +1 -0
  221. package/src/layouts/flex.js +8 -3
  222. package/src/layouts/test/flex.js +53 -0
  223. package/src/store/private-selectors.js +64 -1
  224. package/src/store/reducer.js +1 -1
  225. package/src/store/selectors.js +7 -9
  226. package/src/store/test/private-selectors.js +80 -0
  227. package/src/style.scss +1 -0
  228. package/src/components/block-visibility/styles.scss +0 -10
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { BLOCK_VISIBILITY_VIEWPORT_ENTRIES } from './constants';
5
+
6
+ /**
7
+ * Checks if a block is hidden for a specific viewport.
8
+ *
9
+ * @param {Object} block The block to check.
10
+ * @param {string} viewport The viewport to check (e.g., 'mobile', 'tablet', 'desktop').
11
+ * @return {boolean} Whether the block is hidden for the viewport.
12
+ */
13
+ function isBlockHiddenForViewport( block, viewport ) {
14
+ if ( ! block ) {
15
+ return false;
16
+ }
17
+
18
+ const blockVisibility = block.attributes?.metadata?.blockVisibility;
19
+
20
+ // If explicitly visible everywhere (true), return false for all viewports.
21
+ if ( blockVisibility === true ) {
22
+ return false;
23
+ }
24
+
25
+ // If null or not an object, block is not hidden for any specific viewport.
26
+ if ( 'object' !== typeof blockVisibility ) {
27
+ return false;
28
+ }
29
+
30
+ // Check if the viewport is valid.
31
+ if (
32
+ ! BLOCK_VISIBILITY_VIEWPORT_ENTRIES.some(
33
+ ( [ , { key } ] ) => key === viewport
34
+ )
35
+ ) {
36
+ return false;
37
+ }
38
+
39
+ // Check if the specific viewport is hidden.
40
+ return blockVisibility[ viewport ] === false;
41
+ }
42
+
43
+ /**
44
+ * Gets the checkbox state for a viewport across multiple blocks.
45
+ * Returns `true` if all blocks are hidden, `null` if some are hidden, `false` if none are hidden.
46
+ *
47
+ * @param {Array} blocks Array of blocks to check.
48
+ * @param {string} viewport The viewport to check (e.g., 'mobile', 'tablet', 'desktop').
49
+ * @return {boolean|null} `true` if all hidden, `null` if some hidden, `false` if none hidden.
50
+ */
51
+ export function getViewportCheckboxState( blocks, viewport ) {
52
+ if ( ! blocks?.length ) {
53
+ return false;
54
+ }
55
+
56
+ const hiddenCount = blocks.filter( ( block ) =>
57
+ isBlockHiddenForViewport( block, viewport )
58
+ ).length;
59
+
60
+ if ( hiddenCount === 0 ) {
61
+ return false;
62
+ }
63
+ if ( hiddenCount === blocks.length ) {
64
+ return true;
65
+ }
66
+
67
+ return null; // Indeterminate: some hidden, some visible (normal mixed state)
68
+ }
69
+
70
+ /**
71
+ * Gets the checkbox state for "hide everywhere" across multiple blocks.
72
+ * Returns `true` if all blocks are hidden everywhere, `null` if some are hidden everywhere, `false` if none are.
73
+ *
74
+ * @param {Array} blocks Array of blocks to check.
75
+ * @return {boolean|null} `true` if all hidden everywhere, `null` if some hidden everywhere, `false` if none.
76
+ */
77
+ export function getHideEverywhereCheckboxState( blocks ) {
78
+ if ( ! blocks?.length ) {
79
+ return false;
80
+ }
81
+
82
+ const hiddenEverywhereCount = blocks.filter(
83
+ ( block ) =>
84
+ block && block.attributes?.metadata?.blockVisibility === false
85
+ ).length;
86
+
87
+ if ( hiddenEverywhereCount === 0 ) {
88
+ return false;
89
+ }
90
+ if ( hiddenEverywhereCount === blocks.length ) {
91
+ return true;
92
+ }
93
+
94
+ return null; // Indeterminate: some but not all
95
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+ import { MenuItem } from '@wordpress/components';
6
+ import { seen, unseen } from '@wordpress/icons';
7
+ import { useState } from '@wordpress/element';
8
+ import { useSelect } from '@wordpress/data';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import { BlockVisibilityModal } from './';
14
+ import { store as blockEditorStore } from '../../store';
15
+ import { unlock } from '../../lock-unlock';
16
+
17
+ export default function BlockVisibilityViewportMenuItem( { clientIds } ) {
18
+ const [ isModalOpen, setIsModalOpen ] = useState( false );
19
+ const areBlocksHiddenAnywhere = useSelect(
20
+ ( select ) =>
21
+ unlock( select( blockEditorStore ) ).areBlocksHiddenAnywhere(
22
+ clientIds
23
+ ),
24
+ [ clientIds ]
25
+ );
26
+ return (
27
+ <>
28
+ <MenuItem
29
+ icon={ areBlocksHiddenAnywhere ? unseen : seen }
30
+ onClick={ () => setIsModalOpen( true ) }
31
+ >
32
+ { areBlocksHiddenAnywhere ? __( 'Show' ) : __( 'Hide' ) }
33
+ </MenuItem>
34
+ { isModalOpen && (
35
+ <BlockVisibilityModal
36
+ clientIds={ clientIds }
37
+ onClose={ () => setIsModalOpen( false ) }
38
+ />
39
+ ) }
40
+ </>
41
+ );
42
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+ import { ToolbarButton, ToolbarGroup } from '@wordpress/components';
6
+ import { useRef, useEffect, useState } from '@wordpress/element';
7
+ import { seen, unseen } from '@wordpress/icons';
8
+ import { hasBlockSupport } from '@wordpress/blocks';
9
+ import { useSelect } from '@wordpress/data';
10
+
11
+ /**
12
+ * Internal dependencies
13
+ */
14
+ import { store as blockEditorStore } from '../../store';
15
+ import { BlockVisibilityModal } from './';
16
+ import { unlock } from '../../lock-unlock';
17
+
18
+ export default function BlockVisibilityViewportToolbar( { clientIds } ) {
19
+ const hasBlockVisibilityButtonShownRef = useRef( false );
20
+ const [ isModalOpen, setIsModalOpen ] = useState( false );
21
+ const { canToggleBlockVisibility, areBlocksHiddenAnywhere } = useSelect(
22
+ ( select ) => {
23
+ const {
24
+ getBlocksByClientId,
25
+ getBlockName,
26
+ areBlocksHiddenAnywhere: _areBlocksHiddenAnywhere,
27
+ } = unlock( select( blockEditorStore ) );
28
+ const _blocks = getBlocksByClientId( clientIds );
29
+ return {
30
+ canToggleBlockVisibility: _blocks.every( ( { clientId } ) =>
31
+ hasBlockSupport(
32
+ getBlockName( clientId ),
33
+ 'visibility',
34
+ true
35
+ )
36
+ ),
37
+ areBlocksHiddenAnywhere: _areBlocksHiddenAnywhere( clientIds ),
38
+ };
39
+ },
40
+
41
+ [ clientIds ]
42
+ );
43
+
44
+ /*
45
+ * If the block visibility button has been shown, we don't want to
46
+ * remove it from the toolbar until the toolbar is rendered again
47
+ * without it. Removing it beforehand can cause focus loss issues.
48
+ * It needs to return focus from whence it came, and to do that,
49
+ * we need to leave the button in the toolbar.
50
+ */
51
+ useEffect( () => {
52
+ if ( areBlocksHiddenAnywhere ) {
53
+ hasBlockVisibilityButtonShownRef.current = true;
54
+ }
55
+ }, [ areBlocksHiddenAnywhere ] );
56
+
57
+ if (
58
+ ! areBlocksHiddenAnywhere &&
59
+ ! hasBlockVisibilityButtonShownRef.current
60
+ ) {
61
+ return null;
62
+ }
63
+
64
+ return (
65
+ <>
66
+ <ToolbarGroup className="block-editor-block-visibility-toolbar">
67
+ <ToolbarButton
68
+ disabled={ ! canToggleBlockVisibility }
69
+ icon={ areBlocksHiddenAnywhere ? unseen : seen }
70
+ label={
71
+ areBlocksHiddenAnywhere
72
+ ? __( 'Hidden' )
73
+ : __( 'Visible' )
74
+ }
75
+ onClick={ () => setIsModalOpen( true ) }
76
+ aria-expanded={ isModalOpen }
77
+ aria-haspopup={ ! isModalOpen ? 'dialog' : undefined }
78
+ />
79
+ </ToolbarGroup>
80
+ { isModalOpen && (
81
+ <BlockVisibilityModal
82
+ clientIds={ clientIds }
83
+ onClose={ () => setIsModalOpen( false ) }
84
+ />
85
+ ) }
86
+ </>
87
+ );
88
+ }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import fastDeepEqual from 'fast-deep-equal/es6';
4
+ import fastDeepEqual from 'fast-deep-equal/es6/index.js';
5
5
 
6
6
  /**
7
7
  * WordPress dependencies
@@ -75,6 +75,8 @@ function InserterMenu(
75
75
  const [ selectedMediaCategory, setSelectedMediaCategory ] =
76
76
  useState( null );
77
77
  const isLargeViewport = useViewportMatch( 'large' );
78
+ const isMobileViewport = useViewportMatch( 'medium', '<' );
79
+ const maybeCloseInserter = isMobileViewport ? onClose : NOOP;
78
80
 
79
81
  function getInitialTab() {
80
82
  if ( __experimentalInitialTab ) {
@@ -114,6 +116,7 @@ function InserterMenu(
114
116
  _rootClientId
115
117
  );
116
118
  onSelect( blocks );
119
+ maybeCloseInserter();
117
120
 
118
121
  // Check for focus loss due to filtering blocks by selected block type
119
122
  window.requestAnimationFrame( () => {
@@ -128,7 +131,7 @@ function InserterMenu(
128
131
  }
129
132
  } );
130
133
  },
131
- [ onInsertBlocks, onSelect, shouldFocusBlock ]
134
+ [ onInsertBlocks, maybeCloseInserter, onSelect, ref, shouldFocusBlock ]
132
135
  );
133
136
 
134
137
  const onInsertPattern = useCallback(
@@ -136,8 +139,9 @@ function InserterMenu(
136
139
  onToggleInsertionPoint( false );
137
140
  onInsertBlocks( blocks, { patternName }, ...args );
138
141
  onSelect();
142
+ maybeCloseInserter();
139
143
  },
140
- [ onInsertBlocks, onSelect ]
144
+ [ onInsertBlocks, maybeCloseInserter, onSelect, onToggleInsertionPoint ]
141
145
  );
142
146
 
143
147
  const onHover = useCallback(
@@ -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 (
@@ -66,7 +66,7 @@ function ListViewBlockSelectButton(
66
66
  ( select ) => {
67
67
  const { getBlockName, getBlockAttributes } =
68
68
  select( blockEditorStore );
69
- const { isBlockHidden: _isBlockHidden } = unlock(
69
+ const { areBlocksHiddenAnywhere } = unlock(
70
70
  select( blockEditorStore )
71
71
  );
72
72
  const blockAttributes = getBlockAttributes( clientId );
@@ -76,7 +76,7 @@ function ListViewBlockSelectButton(
76
76
  'visibility',
77
77
  true
78
78
  ),
79
- isBlockHidden: _isBlockHidden( clientId ),
79
+ isBlockHidden: areBlocksHiddenAnywhere( [ clientId ] ),
80
80
  hasPatternName: !! blockAttributes?.metadata?.patternName,
81
81
  };
82
82
  },
@@ -54,6 +54,7 @@ import AriaReferencedText from './aria-referenced-text';
54
54
  import { unlock } from '../../lock-unlock';
55
55
  import usePasteStyles from '../use-paste-styles';
56
56
  import { cleanEmptyObject } from '../../hooks/utils';
57
+ import { BlockVisibilityModal } from '../block-visibility';
57
58
 
58
59
  function ListViewBlock( {
59
60
  block: { clientId },
@@ -79,7 +80,8 @@ function ListViewBlock( {
79
80
  const settingsRef = useRef( null );
80
81
  const [ isHovered, setIsHovered ] = useState( false );
81
82
  const [ settingsAnchorRect, setSettingsAnchorRect ] = useState();
82
-
83
+ const [ visibilityModalClientIds, setVisibilityModalClientIds ] =
84
+ useState( null );
83
85
  const { isLocked } = useBlockLock( clientId );
84
86
 
85
87
  const isFirstSelectedBlock =
@@ -98,6 +100,7 @@ function ListViewBlock( {
98
100
  insertBeforeBlock,
99
101
  updateBlockAttributes,
100
102
  } = unlock( useDispatch( blockEditorStore ) );
103
+
101
104
  const debouncedToggleBlockHighlight = useDebounce(
102
105
  toggleBlockHighlight,
103
106
  50
@@ -125,15 +128,18 @@ function ListViewBlock( {
125
128
  const { block, blockName, allowRightClickOverrides, isBlockHidden } =
126
129
  useSelect(
127
130
  ( select ) => {
128
- const { getBlock, getBlockName, getSettings } =
129
- select( blockEditorStore );
131
+ const {
132
+ getBlock,
133
+ getBlockName: _getBlockName,
134
+ getSettings,
135
+ } = select( blockEditorStore );
130
136
  const { isBlockHidden: _isBlockHidden } = unlock(
131
137
  select( blockEditorStore )
132
138
  );
133
139
 
134
140
  return {
135
141
  block: getBlock( clientId ),
136
- blockName: getBlockName( clientId ),
142
+ blockName: _getBlockName( clientId ),
137
143
  allowRightClickOverrides:
138
144
  getSettings().allowRightClickOverrides,
139
145
  isBlockHidden: _isBlockHidden( clientId ),
@@ -373,30 +379,40 @@ function ListViewBlock( {
373
379
  event.preventDefault();
374
380
  const { blocksToUpdate } = getBlocksToUpdate();
375
381
  const blocks = getBlocksByClientId( blocksToUpdate );
376
- const canToggleVisibility = blocks.every( ( blockToUpdate ) =>
377
- hasBlockSupport( blockToUpdate.name, 'visibility', true )
382
+ const supportsBlockVisibility = blocks.every( ( _block ) =>
383
+ hasBlockSupport( _block.name, 'visibility', true )
378
384
  );
379
- if ( ! canToggleVisibility ) {
385
+
386
+ if ( ! supportsBlockVisibility ) {
380
387
  return;
381
388
  }
382
- const hasHiddenBlock = blocks.some(
383
- ( blockToUpdate ) =>
384
- blockToUpdate.attributes.metadata?.blockVisibility === false
385
- );
386
- const attributesByClientId = Object.fromEntries(
387
- blocks.map( ( { clientId: mapClientId, attributes } ) => [
388
- mapClientId,
389
- {
390
- metadata: cleanEmptyObject( {
391
- ...attributes?.metadata,
392
- blockVisibility: hasHiddenBlock ? undefined : false,
393
- } ),
394
- },
395
- ] )
396
- );
397
- updateBlockAttributes( blocksToUpdate, attributesByClientId, {
398
- uniqueByBlock: true,
399
- } );
389
+
390
+ if ( window.__experimentalHideBlocksBasedOnScreenSize ) {
391
+ // Open the visibility breakpoints modal.
392
+ setVisibilityModalClientIds( blocksToUpdate );
393
+ } else {
394
+ const hasHiddenBlock = blocks.some(
395
+ ( blockToUpdate ) =>
396
+ blockToUpdate.attributes.metadata?.blockVisibility ===
397
+ false
398
+ );
399
+ const attributesByClientId = Object.fromEntries(
400
+ blocks.map( ( { clientId: mapClientId, attributes } ) => [
401
+ mapClientId,
402
+ {
403
+ metadata: cleanEmptyObject( {
404
+ ...attributes?.metadata,
405
+ blockVisibility: hasHiddenBlock
406
+ ? undefined
407
+ : false,
408
+ } ),
409
+ },
410
+ ] )
411
+ );
412
+ updateBlockAttributes( blocksToUpdate, attributesByClientId, {
413
+ uniqueByBlock: true,
414
+ } );
415
+ }
400
416
  }
401
417
  }
402
418
 
@@ -699,6 +715,12 @@ function ListViewBlock( {
699
715
  ) }
700
716
  </TreeGridCell>
701
717
  ) }
718
+ { visibilityModalClientIds && (
719
+ <BlockVisibilityModal
720
+ clientIds={ visibilityModalClientIds }
721
+ onClose={ () => setVisibilityModalClientIds( null ) }
722
+ />
723
+ ) }
702
724
  </ListViewLeaf>
703
725
  );
704
726
  }
@@ -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 ) {
@@ -2,7 +2,7 @@
2
2
  * External dependencies
3
3
  */
4
4
  import clsx from 'clsx';
5
- import fastDeepEqual from 'fast-deep-equal/es6';
5
+ import fastDeepEqual from 'fast-deep-equal/es6/index.js';
6
6
 
7
7
  /**
8
8
  * WordPress dependencies
@@ -452,6 +452,8 @@ class URLInput extends Component {
452
452
  value,
453
453
  required: true,
454
454
  type: 'text',
455
+ name: inputId,
456
+ autoComplete: 'off',
455
457
  onChange: disabled ? () => {} : this.onChange, // Disable onChange when disabled
456
458
  onFocus: disabled ? () => {} : this.onFocus, // Disable onFocus when disabled
457
459
  placeholder,
@@ -223,9 +223,10 @@ const getQuickActionsCommands = () =>
223
223
  } );
224
224
  const canRemove = canRemoveBlocks( clientIds );
225
225
 
226
- const canToggleBlockVisibility = blocks.every( ( { clientId } ) =>
227
- hasBlockSupport( getBlockName( clientId ), 'visibility', true )
228
- );
226
+ const canToggleBlockVisibility =
227
+ blocks.every( ( { clientId } ) =>
228
+ hasBlockSupport( getBlockName( clientId ), 'visibility', true )
229
+ ) && ! window.__experimentalHideBlocksBasedOnScreenSize;
229
230
 
230
231
  const commands = [];
231
232