@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
@@ -166,6 +166,11 @@
166
166
  content: "";
167
167
  }
168
168
 
169
+ // Hide the dot divider since the parent selector is visually separated.
170
+ &::after {
171
+ display: none;
172
+ }
173
+
169
174
  .block-editor-block-parent-selector__button {
170
175
  border: $border-width solid $gray-900;
171
176
  padding-right: 6px;
@@ -186,6 +191,11 @@
186
191
  position: relative;
187
192
  left: auto;
188
193
  margin-left: -$border-width;
194
+
195
+ // Show the dot divider since the parent selector is inline.
196
+ &::after {
197
+ display: inline-flex;
198
+ }
189
199
  }
190
200
 
191
201
  .block-editor-block-mover__move-button-container,
@@ -16,7 +16,6 @@ import { unseen } from '@wordpress/icons';
16
16
  */
17
17
  import { unlock } from '../../lock-unlock';
18
18
  import { store as blockEditorStore } from '../../store';
19
- import './styles.scss';
20
19
 
21
20
  const { Badge } = unlock( componentsPrivateApis );
22
21
 
@@ -0,0 +1,33 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+ import { desktop, tablet, mobile } from '@wordpress/icons';
6
+
7
+ /**
8
+ * The choices for the block visibility.
9
+ * Must match those in packages/editor/src/components/preview-dropdown/index.js.
10
+ *
11
+ * @todo create a single source of truth for the viewport types.
12
+ */
13
+ export const BLOCK_VISIBILITY_VIEWPORTS = {
14
+ desktop: {
15
+ label: __( 'Desktop' ),
16
+ icon: desktop,
17
+ key: 'desktop',
18
+ },
19
+ tablet: {
20
+ label: __( 'Tablet' ),
21
+ icon: tablet,
22
+ key: 'tablet',
23
+ },
24
+ mobile: {
25
+ label: __( 'Mobile' ),
26
+ icon: mobile,
27
+ key: 'mobile',
28
+ },
29
+ };
30
+
31
+ export const BLOCK_VISIBILITY_VIEWPORT_ENTRIES = Object.entries(
32
+ BLOCK_VISIBILITY_VIEWPORTS
33
+ );
@@ -1,2 +1,21 @@
1
- export { default as BlockVisibilityMenuItem } from './menu-item';
2
- export { default as BlockVisibilityToolbar } from './toolbar';
1
+ export { default as BlockVisibilityModal } from './modal';
2
+ export { default as useBlockVisibility } from './use-block-visibility';
3
+
4
+ import BlockVisibilityToolbarDefault from './toolbar';
5
+ import BlockVisibilityViewportToolbar from './viewport-toolbar';
6
+
7
+ import BlockVisibilityMenuItemDefault from './menu-item';
8
+ import BlockVisibilityViewportMenuItem from './viewport-menu-item';
9
+
10
+ const hasViewportVisibilityExperiment =
11
+ typeof window !== 'undefined' &&
12
+ window.__experimentalHideBlocksBasedOnScreenSize;
13
+
14
+ // Conditionally export the viewport versions when the experimental flag is enabled.
15
+ export const BlockVisibilityMenuItem = hasViewportVisibilityExperiment
16
+ ? BlockVisibilityViewportMenuItem
17
+ : BlockVisibilityMenuItemDefault;
18
+
19
+ export const BlockVisibilityToolbar = hasViewportVisibilityExperiment
20
+ ? BlockVisibilityViewportToolbar
21
+ : BlockVisibilityToolbarDefault;
@@ -0,0 +1,358 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import clsx from 'clsx';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { __, sprintf } from '@wordpress/i18n';
10
+ import {
11
+ useState,
12
+ useMemo,
13
+ useCallback,
14
+ createInterpolateElement,
15
+ } from '@wordpress/element';
16
+ import {
17
+ Button,
18
+ CheckboxControl,
19
+ Flex,
20
+ FlexItem,
21
+ Icon,
22
+ Modal,
23
+ } from '@wordpress/components';
24
+ import { useDispatch, useSelect } from '@wordpress/data';
25
+ import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts';
26
+ import { store as noticesStore } from '@wordpress/notices';
27
+
28
+ /**
29
+ * Internal dependencies
30
+ */
31
+ import {
32
+ BLOCK_VISIBILITY_VIEWPORT_ENTRIES,
33
+ BLOCK_VISIBILITY_VIEWPORTS,
34
+ } from './constants';
35
+ import { store as blockEditorStore } from '../../store';
36
+ import { cleanEmptyObject } from '../../hooks/utils';
37
+ import {
38
+ getViewportCheckboxState,
39
+ getHideEverywhereCheckboxState,
40
+ } from './utils';
41
+ import './style.scss';
42
+
43
+ const DEFAULT_VIEWPORT_CHECKBOX_VALUES = {
44
+ [ BLOCK_VISIBILITY_VIEWPORTS.mobile.key ]: false,
45
+ [ BLOCK_VISIBILITY_VIEWPORTS.tablet.key ]: false,
46
+ [ BLOCK_VISIBILITY_VIEWPORTS.desktop.key ]: false,
47
+ };
48
+
49
+ const EMPTY_BLOCKS = [];
50
+
51
+ /**
52
+ * Modal component for configuring block visibility across viewports.
53
+ *
54
+ * Allows users to hide blocks on specific viewport sizes (mobile, tablet, desktop)
55
+ * or hide them everywhere. When editing multiple blocks, checkboxes only show as
56
+ * checked if ALL selected blocks share the same setting to avoid ambiguity.
57
+ *
58
+ * @param {Object} props Component props.
59
+ * @param {Array} props.clientIds The client IDs of the blocks to hide.
60
+ * @param {Function} props.onClose Callback function invoked when the modal is closed.
61
+ * @return {JSX.Element} The modal component.
62
+ */
63
+ export default function BlockVisibilityModal( { clientIds, onClose } ) {
64
+ const { createSuccessNotice } = useDispatch( noticesStore );
65
+ const { updateBlockAttributes } = useDispatch( blockEditorStore );
66
+
67
+ const blocks = useSelect(
68
+ ( select ) =>
69
+ select( blockEditorStore ).getBlocksByClientId( clientIds ) ??
70
+ EMPTY_BLOCKS,
71
+ [ clientIds ]
72
+ );
73
+ const listViewShortcut = useSelect( ( select ) => {
74
+ return select( keyboardShortcutsStore ).getShortcutRepresentation(
75
+ 'core/editor/toggle-list-view'
76
+ );
77
+ }, [] );
78
+
79
+ const initialViewportValues = useMemo( () => {
80
+ if ( blocks?.length === 0 ) {
81
+ return {
82
+ hideEverywhere: false,
83
+ viewportChecked: {},
84
+ };
85
+ }
86
+
87
+ const viewportValues = {};
88
+
89
+ BLOCK_VISIBILITY_VIEWPORT_ENTRIES.forEach( ( [ , { key } ] ) => {
90
+ viewportValues[ key ] = getViewportCheckboxState( blocks, key );
91
+ } );
92
+
93
+ return {
94
+ hideEverywhere: getHideEverywhereCheckboxState( blocks ),
95
+ viewportChecked: viewportValues,
96
+ };
97
+ }, [ blocks ] );
98
+
99
+ const [ viewportChecked, setViewportChecked ] = useState(
100
+ initialViewportValues?.viewportChecked ?? {}
101
+ );
102
+ const [ hideEverywhere, setHideEverywhere ] = useState(
103
+ initialViewportValues?.hideEverywhere ?? false
104
+ );
105
+
106
+ const handleViewportCheckboxChange = useCallback(
107
+ ( viewport, isChecked ) => {
108
+ setViewportChecked( {
109
+ ...viewportChecked,
110
+ [ viewport ]: isChecked,
111
+ } );
112
+ },
113
+ [ viewportChecked ]
114
+ );
115
+
116
+ const noticeMessage = useMemo( () => {
117
+ if ( ! hideEverywhere ) {
118
+ return sprintf(
119
+ // translators: %s: The shortcut key to access the List View.
120
+ __(
121
+ 'Block visibility settings saved. You can access them via the List View (%s).'
122
+ ),
123
+ listViewShortcut
124
+ );
125
+ }
126
+
127
+ const message =
128
+ blocks?.length > 1
129
+ ? // translators: %s: The shortcut key to access the List View.
130
+ __(
131
+ 'Blocks hidden. You can access them via the List View (%s).'
132
+ )
133
+ : // translators: %s: The shortcut key to access the List View.
134
+ __(
135
+ 'Block hidden. You can access it via the List View (%s).'
136
+ );
137
+
138
+ return sprintf( message, listViewShortcut );
139
+ }, [ hideEverywhere, blocks?.length, listViewShortcut ] );
140
+
141
+ const isAnyViewportChecked = useMemo(
142
+ () =>
143
+ Object.values( viewportChecked ).some(
144
+ ( checked ) => checked === true || checked === null
145
+ ),
146
+ [ viewportChecked ]
147
+ );
148
+
149
+ const hasIndeterminateValues = useMemo( () => {
150
+ if ( hideEverywhere === null ) {
151
+ return true;
152
+ }
153
+ return Object.values( viewportChecked ).some(
154
+ ( checked ) => checked === null
155
+ );
156
+ }, [ hideEverywhere, viewportChecked ] );
157
+
158
+ const handleSubmit = useCallback(
159
+ ( event ) => {
160
+ event.preventDefault();
161
+ const newVisibility = hideEverywhere
162
+ ? false
163
+ : BLOCK_VISIBILITY_VIEWPORT_ENTRIES.reduce(
164
+ ( acc, [ , { key } ] ) => {
165
+ if ( viewportChecked[ key ] ) {
166
+ // Values are inverted to hide the block on the selected viewport.
167
+ // In the UI, the checkbox is checked (true) when the block is hidden on the selected viewport,
168
+ // so 'false' means hide the block on the selected viewport.
169
+ acc[ key ] = false;
170
+ }
171
+ return acc;
172
+ },
173
+ {}
174
+ );
175
+ const attributesByClientId = Object.fromEntries(
176
+ blocks.map( ( { clientId, attributes } ) => [
177
+ clientId,
178
+ {
179
+ metadata: cleanEmptyObject( {
180
+ ...attributes?.metadata,
181
+ blockVisibility: newVisibility,
182
+ } ),
183
+ },
184
+ ] )
185
+ );
186
+ updateBlockAttributes( clientIds, attributesByClientId, {
187
+ uniqueByBlock: true,
188
+ } );
189
+
190
+ createSuccessNotice( noticeMessage, {
191
+ id: hideEverywhere
192
+ ? 'block-visibility-hidden'
193
+ : 'block-visibility-viewports-saved',
194
+ type: 'snackbar',
195
+ } );
196
+ onClose();
197
+ },
198
+ [
199
+ blocks,
200
+ clientIds,
201
+ createSuccessNotice,
202
+ hideEverywhere,
203
+ noticeMessage,
204
+ onClose,
205
+ updateBlockAttributes,
206
+ viewportChecked,
207
+ ]
208
+ );
209
+
210
+ const hasMultipleBlocks = blocks?.length > 1;
211
+
212
+ return (
213
+ <Modal
214
+ title={
215
+ clientIds?.length > 1 ? __( 'Hide blocks' ) : __( 'Hide block' )
216
+ }
217
+ onRequestClose={ onClose }
218
+ overlayClassName="block-editor-block-visibility-modal"
219
+ size="small"
220
+ >
221
+ <form onSubmit={ handleSubmit }>
222
+ <fieldset>
223
+ <legend>
224
+ { hasMultipleBlocks
225
+ ? __(
226
+ 'Select the viewport sizes for which you want to hide the blocks. Changes will apply to all selected blocks.'
227
+ )
228
+ : __(
229
+ 'Select the viewport size for which you want to hide the block.'
230
+ ) }
231
+ </legend>
232
+ <ul className="block-editor-block-visibility-modal__options">
233
+ <li className="block-editor-block-visibility-modal__options-item block-editor-block-visibility-modal__options-item--everywhere">
234
+ <CheckboxControl
235
+ className="block-editor-block-visibility-modal__options-checkbox--everywhere"
236
+ label={ __( 'Omit from published content' ) }
237
+ checked={ hideEverywhere === true }
238
+ indeterminate={ hideEverywhere === null }
239
+ onChange={ ( checked ) => {
240
+ setHideEverywhere( checked );
241
+ // Reset viewport checkboxes when hide everywhere is checked.
242
+ setViewportChecked(
243
+ DEFAULT_VIEWPORT_CHECKBOX_VALUES
244
+ );
245
+ } }
246
+ />
247
+ { hideEverywhere !== true && (
248
+ <ul className="block-editor-block-visibility-modal__sub-options">
249
+ { BLOCK_VISIBILITY_VIEWPORT_ENTRIES.map(
250
+ ( [ , { label, icon, key } ] ) => (
251
+ <li
252
+ key={ key }
253
+ className="block-editor-block-visibility-modal__options-item"
254
+ >
255
+ <CheckboxControl
256
+ label={ sprintf(
257
+ // translators: %s: The viewport name.
258
+ __( 'Hide on %s' ),
259
+ label
260
+ ) }
261
+ checked={
262
+ viewportChecked[
263
+ key
264
+ ] ?? false
265
+ }
266
+ indeterminate={
267
+ viewportChecked[
268
+ key
269
+ ] === null
270
+ }
271
+ onChange={ ( checked ) =>
272
+ handleViewportCheckboxChange(
273
+ key,
274
+ checked
275
+ )
276
+ }
277
+ />
278
+ <Icon
279
+ icon={ icon }
280
+ className={ clsx( {
281
+ 'block-editor-block-visibility-modal__options-icon--checked':
282
+ viewportChecked[
283
+ key
284
+ ],
285
+ } ) }
286
+ />
287
+ </li>
288
+ )
289
+ ) }
290
+ </ul>
291
+ ) }
292
+ </li>
293
+ </ul>
294
+ { hasMultipleBlocks && hasIndeterminateValues && (
295
+ <p className="block-editor-block-visibility-modal__description">
296
+ { __(
297
+ 'Selected blocks have different visibility settings. The checkboxes show an indeterminate state when settings differ.'
298
+ ) }
299
+ </p>
300
+ ) }
301
+ { ! hasMultipleBlocks && hideEverywhere === true && (
302
+ <p className="block-editor-block-visibility-modal__description">
303
+ { sprintf(
304
+ // translators: %s: The shortcut key to access the List View.
305
+ __(
306
+ 'Block will be hidden in the editor, and omitted from the published markup on the frontend. You can configure it again by selecting it in the List View (%s).'
307
+ ),
308
+ listViewShortcut
309
+ ) }
310
+ </p>
311
+ ) }
312
+ { ! hasMultipleBlocks &&
313
+ ! hideEverywhere &&
314
+ isAnyViewportChecked && (
315
+ <p className="block-editor-block-visibility-modal__description">
316
+ { createInterpolateElement(
317
+ sprintf(
318
+ // translators: %s: The shortcut key to access the List View
319
+ __(
320
+ 'Block will be hidden according to the selected viewports. It will be <strong>included in the published markup on the frontend</strong>. You can configure it again by selecting it in the List View (%s).'
321
+ ),
322
+ listViewShortcut
323
+ ),
324
+ {
325
+ strong: <strong />,
326
+ }
327
+ ) }
328
+ </p>
329
+ ) }
330
+ </fieldset>
331
+ <Flex
332
+ className="block-editor-block-visibility-modal__actions"
333
+ justify="flex-end"
334
+ expanded={ false }
335
+ >
336
+ <FlexItem>
337
+ <Button
338
+ variant="tertiary"
339
+ onClick={ onClose }
340
+ __next40pxDefaultSize
341
+ >
342
+ { __( 'Cancel' ) }
343
+ </Button>
344
+ </FlexItem>
345
+ <FlexItem>
346
+ <Button
347
+ variant="primary"
348
+ type="submit"
349
+ __next40pxDefaultSize
350
+ >
351
+ { __( 'Apply' ) }
352
+ </Button>
353
+ </FlexItem>
354
+ </Flex>
355
+ </form>
356
+ </Modal>
357
+ );
358
+ }
@@ -0,0 +1,58 @@
1
+ @use "@wordpress/base-styles/variables" as *;
2
+ @use "@wordpress/base-styles/colors" as *;
3
+ @use "@wordpress/base-styles/z-index" as *;
4
+
5
+ .block-editor-block-visibility-modal {
6
+ z-index: z-index(".block-editor-block-visibility-modal");
7
+
8
+ &__options {
9
+ border: 0;
10
+ padding: 0;
11
+ list-style: none;
12
+ margin: $grid-unit-30 0;
13
+
14
+ &-item {
15
+ display: flex;
16
+ align-items: center;
17
+ justify-content: space-between;
18
+ margin: 0 0 $grid-unit-20 0;
19
+ gap: $grid-unit-30;
20
+ }
21
+
22
+ &-item:last-child {
23
+ margin: 0;
24
+ }
25
+
26
+ &-item--everywhere {
27
+ flex-direction: column;
28
+ align-items: start;
29
+ }
30
+
31
+ &-checkbox--everywhere {
32
+ font-weight: 600;
33
+ }
34
+
35
+ &-icon--checked {
36
+ fill: $gray-300;
37
+ }
38
+ }
39
+
40
+ &__sub-options {
41
+ width: 100%;
42
+ padding-inline-start: $grid-unit-15;
43
+ }
44
+
45
+ &__description {
46
+ font-size: $font-size-small;
47
+ color: $gray-700;
48
+ }
49
+ }
50
+
51
+ .block-editor-block-visibility-info {
52
+ padding-top: $grid-unit-05;
53
+ padding-bottom: $grid-unit-05;
54
+ margin: 0 $grid-unit-20 $grid-unit-20;
55
+ display: flex;
56
+ align-items: center;
57
+ justify-content: start;
58
+ }