@wordpress/block-editor 11.8.0 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +15 -3
  3. package/build/components/block-info-slot-fill/index.js +47 -0
  4. package/build/components/block-info-slot-fill/index.js.map +1 -0
  5. package/build/components/block-inspector/index.js +4 -2
  6. package/build/components/block-inspector/index.js.map +1 -1
  7. package/build/components/block-list/block.native.js +3 -4
  8. package/build/components/block-list/block.native.js.map +1 -1
  9. package/build/components/block-toolbar/index.js +2 -1
  10. package/build/components/block-toolbar/index.js.map +1 -1
  11. package/build/components/block-tools/block-contextual-toolbar.js +83 -9
  12. package/build/components/block-tools/block-contextual-toolbar.js.map +1 -1
  13. package/build/components/block-tools/selected-block-popover.js +11 -28
  14. package/build/components/block-tools/selected-block-popover.js.map +1 -1
  15. package/build/components/editor-styles/index.js +4 -3
  16. package/build/components/editor-styles/index.js.map +1 -1
  17. package/build/components/font-sizes/fluid-utils.js +21 -14
  18. package/build/components/font-sizes/fluid-utils.js.map +1 -1
  19. package/build/components/global-styles/border-panel.js +2 -32
  20. package/build/components/global-styles/border-panel.js.map +1 -1
  21. package/build/components/global-styles/color-panel.js +12 -12
  22. package/build/components/global-styles/color-panel.js.map +1 -1
  23. package/build/components/global-styles/color-panel.native.js +174 -0
  24. package/build/components/global-styles/color-panel.native.js.map +1 -0
  25. package/build/components/global-styles/dimensions-panel.js +6 -6
  26. package/build/components/global-styles/dimensions-panel.js.map +1 -1
  27. package/build/components/global-styles/effects-panel.js +1 -1
  28. package/build/components/global-styles/effects-panel.js.map +1 -1
  29. package/build/components/global-styles/filters-panel.js +78 -14
  30. package/build/components/global-styles/filters-panel.js.map +1 -1
  31. package/build/components/global-styles/typography-panel.js +9 -9
  32. package/build/components/global-styles/typography-panel.js.map +1 -1
  33. package/build/components/global-styles/use-global-styles-output.js +87 -77
  34. package/build/components/global-styles/use-global-styles-output.js.map +1 -1
  35. package/build/components/index.js +7 -0
  36. package/build/components/index.js.map +1 -1
  37. package/build/components/inserter/block-types-tab.js +12 -7
  38. package/build/components/inserter/block-types-tab.js.map +1 -1
  39. package/build/components/inserter/index.js +2 -1
  40. package/build/components/inserter/index.js.map +1 -1
  41. package/build/components/inspector-controls/groups.js +2 -0
  42. package/build/components/inspector-controls/groups.js.map +1 -1
  43. package/build/components/inspector-controls-tabs/styles-tab.js +2 -0
  44. package/build/components/inspector-controls-tabs/styles-tab.js.map +1 -1
  45. package/build/components/list-view/block-select-button.js +7 -2
  46. package/build/components/list-view/block-select-button.js.map +1 -1
  47. package/build/components/list-view/block.js +12 -21
  48. package/build/components/list-view/block.js.map +1 -1
  49. package/build/components/list-view/drop-indicator.js +37 -10
  50. package/build/components/list-view/drop-indicator.js.map +1 -1
  51. package/build/components/list-view/index.js +10 -4
  52. package/build/components/list-view/index.js.map +1 -1
  53. package/build/components/list-view/leaf.js +2 -1
  54. package/build/components/list-view/leaf.js.map +1 -1
  55. package/build/components/list-view/use-block-selection.js +1 -1
  56. package/build/components/list-view/use-block-selection.js.map +1 -1
  57. package/build/components/media-replace-flow/index.js +5 -5
  58. package/build/components/media-replace-flow/index.js.map +1 -1
  59. package/build/components/navigable-toolbar/index.js +12 -4
  60. package/build/components/navigable-toolbar/index.js.map +1 -1
  61. package/build/components/off-canvas-editor/appender.js +2 -7
  62. package/build/components/off-canvas-editor/appender.js.map +1 -1
  63. package/build/hooks/duotone.js +29 -4
  64. package/build/hooks/duotone.js.map +1 -1
  65. package/build/hooks/utils.js +15 -3
  66. package/build/hooks/utils.js.map +1 -1
  67. package/build/private-apis.js +10 -1
  68. package/build/private-apis.js.map +1 -1
  69. package/build/store/actions.js +7 -0
  70. package/build/store/actions.js.map +1 -1
  71. package/build/utils/object.js +5 -5
  72. package/build/utils/object.js.map +1 -1
  73. package/build/utils/transform-styles/index.js +2 -2
  74. package/build/utils/transform-styles/index.js.map +1 -1
  75. package/build/utils/use-should-contextual-toolbar-show.js +68 -0
  76. package/build/utils/use-should-contextual-toolbar-show.js.map +1 -0
  77. package/build-module/components/block-info-slot-fill/index.js +34 -0
  78. package/build-module/components/block-info-slot-fill/index.js.map +1 -0
  79. package/build-module/components/block-inspector/index.js +3 -2
  80. package/build-module/components/block-inspector/index.js.map +1 -1
  81. package/build-module/components/block-list/block.native.js +3 -4
  82. package/build-module/components/block-list/block.native.js.map +1 -1
  83. package/build-module/components/block-toolbar/index.js +2 -1
  84. package/build-module/components/block-toolbar/index.js.map +1 -1
  85. package/build-module/components/block-tools/block-contextual-toolbar.js +79 -9
  86. package/build-module/components/block-tools/block-contextual-toolbar.js.map +1 -1
  87. package/build-module/components/block-tools/selected-block-popover.js +10 -27
  88. package/build-module/components/block-tools/selected-block-popover.js.map +1 -1
  89. package/build-module/components/editor-styles/index.js +4 -3
  90. package/build-module/components/editor-styles/index.js.map +1 -1
  91. package/build-module/components/font-sizes/fluid-utils.js +21 -14
  92. package/build-module/components/font-sizes/fluid-utils.js.map +1 -1
  93. package/build-module/components/global-styles/border-panel.js +2 -32
  94. package/build-module/components/global-styles/border-panel.js.map +1 -1
  95. package/build-module/components/global-styles/color-panel.js +13 -13
  96. package/build-module/components/global-styles/color-panel.js.map +1 -1
  97. package/build-module/components/global-styles/color-panel.native.js +150 -0
  98. package/build-module/components/global-styles/color-panel.native.js.map +1 -0
  99. package/build-module/components/global-styles/dimensions-panel.js +7 -7
  100. package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
  101. package/build-module/components/global-styles/effects-panel.js +2 -2
  102. package/build-module/components/global-styles/effects-panel.js.map +1 -1
  103. package/build-module/components/global-styles/filters-panel.js +78 -16
  104. package/build-module/components/global-styles/filters-panel.js.map +1 -1
  105. package/build-module/components/global-styles/typography-panel.js +10 -10
  106. package/build-module/components/global-styles/typography-panel.js.map +1 -1
  107. package/build-module/components/global-styles/use-global-styles-output.js +87 -77
  108. package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
  109. package/build-module/components/index.js +1 -1
  110. package/build-module/components/index.js.map +1 -1
  111. package/build-module/components/inserter/block-types-tab.js +12 -6
  112. package/build-module/components/inserter/block-types-tab.js.map +1 -1
  113. package/build-module/components/inserter/index.js +2 -1
  114. package/build-module/components/inserter/index.js.map +1 -1
  115. package/build-module/components/inspector-controls/groups.js +2 -0
  116. package/build-module/components/inspector-controls/groups.js.map +1 -1
  117. package/build-module/components/inspector-controls-tabs/styles-tab.js +2 -0
  118. package/build-module/components/inspector-controls-tabs/styles-tab.js.map +1 -1
  119. package/build-module/components/list-view/block-select-button.js +7 -2
  120. package/build-module/components/list-view/block-select-button.js.map +1 -1
  121. package/build-module/components/list-view/block.js +14 -22
  122. package/build-module/components/list-view/block.js.map +1 -1
  123. package/build-module/components/list-view/drop-indicator.js +36 -10
  124. package/build-module/components/list-view/drop-indicator.js.map +1 -1
  125. package/build-module/components/list-view/index.js +11 -5
  126. package/build-module/components/list-view/index.js.map +1 -1
  127. package/build-module/components/list-view/leaf.js +2 -1
  128. package/build-module/components/list-view/leaf.js.map +1 -1
  129. package/build-module/components/list-view/use-block-selection.js +1 -1
  130. package/build-module/components/list-view/use-block-selection.js.map +1 -1
  131. package/build-module/components/media-replace-flow/index.js +5 -5
  132. package/build-module/components/media-replace-flow/index.js.map +1 -1
  133. package/build-module/components/navigable-toolbar/index.js +12 -4
  134. package/build-module/components/navigable-toolbar/index.js.map +1 -1
  135. package/build-module/components/off-canvas-editor/appender.js +1 -5
  136. package/build-module/components/off-canvas-editor/appender.js.map +1 -1
  137. package/build-module/hooks/duotone.js +28 -5
  138. package/build-module/hooks/duotone.js.map +1 -1
  139. package/build-module/hooks/utils.js +16 -4
  140. package/build-module/hooks/utils.js.map +1 -1
  141. package/build-module/private-apis.js +7 -1
  142. package/build-module/private-apis.js.map +1 -1
  143. package/build-module/store/actions.js +7 -0
  144. package/build-module/store/actions.js.map +1 -1
  145. package/build-module/utils/object.js +4 -4
  146. package/build-module/utils/object.js.map +1 -1
  147. package/build-module/utils/transform-styles/index.js +2 -2
  148. package/build-module/utils/transform-styles/index.js.map +1 -1
  149. package/build-module/utils/use-should-contextual-toolbar-show.js +56 -0
  150. package/build-module/utils/use-should-contextual-toolbar-show.js.map +1 -0
  151. package/build-style/content-rtl.css +9 -6
  152. package/build-style/content.css +9 -6
  153. package/build-style/style-rtl.css +223 -46
  154. package/build-style/style.css +223 -46
  155. package/package.json +32 -32
  156. package/src/components/block-info-slot-fill/index.js +24 -0
  157. package/src/components/block-inspector/index.js +3 -0
  158. package/src/components/block-list/block.native.js +2 -3
  159. package/src/components/block-list/content.scss +16 -15
  160. package/src/components/block-mobile-toolbar/test/block-actions-menu.native.js +9 -9
  161. package/src/components/block-mover/style.scss +10 -4
  162. package/src/components/block-mover/test/index.native.js +4 -4
  163. package/src/components/block-toolbar/index.js +4 -3
  164. package/src/components/block-toolbar/style.scss +56 -33
  165. package/src/components/block-tools/block-contextual-toolbar.js +94 -11
  166. package/src/components/block-tools/selected-block-popover.js +11 -44
  167. package/src/components/block-tools/style.scss +157 -3
  168. package/src/components/editor-styles/index.js +9 -5
  169. package/src/components/font-sizes/fluid-utils.js +31 -14
  170. package/src/components/font-sizes/test/fluid-utils.js +5 -16
  171. package/src/components/global-styles/border-panel.js +1 -30
  172. package/src/components/global-styles/color-panel.js +13 -13
  173. package/src/components/global-styles/color-panel.native.js +207 -0
  174. package/src/components/global-styles/dimensions-panel.js +17 -7
  175. package/src/components/global-styles/effects-panel.js +2 -2
  176. package/src/components/global-styles/filters-panel.js +90 -17
  177. package/src/components/global-styles/style.scss +2 -1
  178. package/src/components/global-styles/test/typography-utils.js +63 -22
  179. package/src/components/global-styles/test/use-global-styles-output.js +126 -4
  180. package/src/components/global-styles/typography-panel.js +37 -11
  181. package/src/components/global-styles/use-global-styles-output.js +64 -64
  182. package/src/components/index.js +1 -0
  183. package/src/components/inserter/block-types-tab.js +9 -6
  184. package/src/components/inserter/index.js +1 -1
  185. package/src/components/inspector-controls/groups.js +2 -0
  186. package/src/components/inspector-controls-tabs/styles-tab.js +1 -0
  187. package/src/components/list-view/block-select-button.js +6 -1
  188. package/src/components/list-view/block.js +23 -31
  189. package/src/components/list-view/drop-indicator.js +67 -22
  190. package/src/components/list-view/index.js +8 -1
  191. package/src/components/list-view/leaf.js +1 -0
  192. package/src/components/list-view/style.scss +15 -3
  193. package/src/components/list-view/use-block-selection.js +1 -1
  194. package/src/components/media-replace-flow/README.md +3 -2
  195. package/src/components/media-replace-flow/index.js +4 -5
  196. package/src/components/navigable-toolbar/index.js +12 -3
  197. package/src/components/off-canvas-editor/appender.js +1 -4
  198. package/src/components/url-popover/test/__snapshots__/index.js.snap +3 -3
  199. package/src/hooks/duotone.js +46 -25
  200. package/src/hooks/test/anchor.js +113 -0
  201. package/src/hooks/test/color.js +0 -9
  202. package/src/hooks/test/use-typography-props.js +2 -2
  203. package/src/hooks/test/utils.js +20 -101
  204. package/src/hooks/utils.js +20 -3
  205. package/src/private-apis.js +6 -0
  206. package/src/store/actions.js +7 -0
  207. package/src/utils/object.js +4 -4
  208. package/src/utils/test/object.js +21 -21
  209. package/src/utils/transform-styles/index.js +2 -2
  210. package/src/utils/use-should-contextual-toolbar-show.js +75 -0
  211. package/tsconfig.json +1 -0
  212. package/build/hooks/color-panel.native.js +0 -77
  213. package/build/hooks/color-panel.native.js.map +0 -1
  214. package/build-module/hooks/color-panel.native.js +0 -62
  215. package/build-module/hooks/color-panel.native.js.map +0 -1
  216. package/src/hooks/color-panel.native.js +0 -63
@@ -0,0 +1,113 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { applyFilters } from '@wordpress/hooks';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import '../anchor';
10
+
11
+ const noop = () => {};
12
+
13
+ describe( 'anchor', () => {
14
+ const blockSettings = {
15
+ save: noop,
16
+ category: 'text',
17
+ title: 'block title',
18
+ };
19
+
20
+ describe( 'addAttribute()', () => {
21
+ const registerBlockType = applyFilters.bind(
22
+ null,
23
+ 'blocks.registerBlockType'
24
+ );
25
+
26
+ it( 'should do nothing if the block settings do not define anchor support', () => {
27
+ const settings = registerBlockType( blockSettings );
28
+
29
+ expect( settings.attributes ).toBe( undefined );
30
+ } );
31
+
32
+ it( 'should assign a new anchor attribute', () => {
33
+ const settings = registerBlockType( {
34
+ ...blockSettings,
35
+ supports: {
36
+ anchor: true,
37
+ },
38
+ } );
39
+
40
+ expect( settings.attributes ).toHaveProperty( 'anchor' );
41
+ } );
42
+
43
+ it( 'should not override attributes defined in settings', () => {
44
+ const settings = registerBlockType( {
45
+ ...blockSettings,
46
+ supports: {
47
+ anchor: true,
48
+ },
49
+ attributes: {
50
+ anchor: {
51
+ type: 'string',
52
+ default: 'testAnchor',
53
+ },
54
+ },
55
+ } );
56
+
57
+ expect( settings.attributes.anchor ).toEqual( {
58
+ type: 'string',
59
+ default: 'testAnchor',
60
+ } );
61
+ } );
62
+ } );
63
+
64
+ describe( 'addSaveProps', () => {
65
+ const getSaveContentExtraProps = applyFilters.bind(
66
+ null,
67
+ 'blocks.getSaveContent.extraProps'
68
+ );
69
+
70
+ it( 'should do nothing if the block settings do not define anchor support', () => {
71
+ const attributes = { anchor: 'foo' };
72
+ const extraProps = getSaveContentExtraProps(
73
+ {},
74
+ blockSettings,
75
+ attributes
76
+ );
77
+
78
+ expect( extraProps ).not.toHaveProperty( 'id' );
79
+ } );
80
+
81
+ it( 'should inject anchor attribute ID', () => {
82
+ const attributes = { anchor: 'foo' };
83
+ const extraProps = getSaveContentExtraProps(
84
+ {},
85
+ {
86
+ ...blockSettings,
87
+ supports: {
88
+ anchor: true,
89
+ },
90
+ },
91
+ attributes
92
+ );
93
+
94
+ expect( extraProps.id ).toBe( 'foo' );
95
+ } );
96
+
97
+ it( 'should remove an anchor attribute ID when field is cleared', () => {
98
+ const attributes = { anchor: '' };
99
+ const extraProps = getSaveContentExtraProps(
100
+ {},
101
+ {
102
+ ...blockSettings,
103
+ supports: {
104
+ anchor: true,
105
+ },
106
+ },
107
+ attributes
108
+ );
109
+
110
+ expect( extraProps.id ).toBe( null );
111
+ } );
112
+ } );
113
+ } );
@@ -12,17 +12,8 @@ import { registerBlockType, unregisterBlockType } from '@wordpress/blocks';
12
12
  * Internal dependencies
13
13
  */
14
14
  import BlockEditorProvider from '../../components/provider';
15
- import { cleanEmptyObject } from '../utils';
16
15
  import { withColorPaletteStyles } from '../color';
17
16
 
18
- describe( 'cleanEmptyObject', () => {
19
- it( 'should remove nested keys', () => {
20
- expect( cleanEmptyObject( { color: { text: undefined } } ) ).toEqual(
21
- undefined
22
- );
23
- } );
24
- } );
25
-
26
17
  describe( 'withColorPaletteStyles', () => {
27
18
  const settings = {
28
19
  __experimentalFeatures: {
@@ -44,7 +44,7 @@ describe( 'getTypographyClassesAndStyles', () => {
44
44
  style: {
45
45
  letterSpacing: '22px',
46
46
  fontSize:
47
- 'clamp(1.5rem, 1.5rem + ((1vw - 0.48rem) * 0.962), 2rem)',
47
+ 'clamp(1.25rem, 1.25rem + ((1vw - 0.2rem) * 0.938), 2rem)',
48
48
  textTransform: 'uppercase',
49
49
  },
50
50
  } );
@@ -70,7 +70,7 @@ describe( 'getTypographyClassesAndStyles', () => {
70
70
  style: {
71
71
  textDecoration: 'underline',
72
72
  fontSize:
73
- 'clamp(1.5rem, 1.5rem + ((1vw - 0.48rem) * 0.962), 2rem)',
73
+ 'clamp(1.25rem, 1.25rem + ((1vw - 0.2rem) * 0.938), 2rem)',
74
74
  textTransform: 'uppercase',
75
75
  },
76
76
  } );
@@ -1,113 +1,32 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import { applyFilters } from '@wordpress/hooks';
5
-
6
1
  /**
7
2
  * Internal dependencies
8
3
  */
9
- import '../anchor';
4
+ import { cleanEmptyObject } from '../utils';
10
5
 
11
- const noop = () => {};
12
-
13
- describe( 'anchor', () => {
14
- const blockSettings = {
15
- save: noop,
16
- category: 'text',
17
- title: 'block title',
18
- };
19
-
20
- describe( 'addAttribute()', () => {
21
- const registerBlockType = applyFilters.bind(
22
- null,
23
- 'blocks.registerBlockType'
6
+ describe( 'cleanEmptyObject', () => {
7
+ it( 'should remove nested keys', () => {
8
+ expect( cleanEmptyObject( { color: { text: undefined } } ) ).toEqual(
9
+ undefined
24
10
  );
11
+ } );
25
12
 
26
- it( 'should do nothing if the block settings do not define anchor support', () => {
27
- const settings = registerBlockType( blockSettings );
28
-
29
- expect( settings.attributes ).toBe( undefined );
30
- } );
31
-
32
- it( 'should assign a new anchor attribute', () => {
33
- const settings = registerBlockType( {
34
- ...blockSettings,
35
- supports: {
36
- anchor: true,
37
- },
38
- } );
39
-
40
- expect( settings.attributes ).toHaveProperty( 'anchor' );
41
- } );
42
-
43
- it( 'should not override attributes defined in settings', () => {
44
- const settings = registerBlockType( {
45
- ...blockSettings,
46
- supports: {
47
- anchor: true,
48
- },
49
- attributes: {
50
- anchor: {
51
- type: 'string',
52
- default: 'testAnchor',
53
- },
54
- },
55
- } );
56
-
57
- expect( settings.attributes.anchor ).toEqual( {
58
- type: 'string',
59
- default: 'testAnchor',
60
- } );
13
+ it( 'should remove partial nested keys', () => {
14
+ expect(
15
+ cleanEmptyObject( {
16
+ color: { text: undefined },
17
+ typography: { fontSize: '10px' },
18
+ } )
19
+ ).toEqual( {
20
+ typography: { fontSize: '10px' },
61
21
  } );
62
22
  } );
63
23
 
64
- describe( 'addSaveProps', () => {
65
- const getSaveContentExtraProps = applyFilters.bind(
66
- null,
67
- 'blocks.getSaveContent.extraProps'
24
+ it( 'should not remove falsy nested keys', () => {
25
+ expect( cleanEmptyObject( { color: { text: false } } ) ).not.toEqual(
26
+ undefined
27
+ );
28
+ expect( cleanEmptyObject( { color: { text: '' } } ) ).not.toEqual(
29
+ undefined
68
30
  );
69
-
70
- it( 'should do nothing if the block settings do not define anchor support', () => {
71
- const attributes = { anchor: 'foo' };
72
- const extraProps = getSaveContentExtraProps(
73
- {},
74
- blockSettings,
75
- attributes
76
- );
77
-
78
- expect( extraProps ).not.toHaveProperty( 'id' );
79
- } );
80
-
81
- it( 'should inject anchor attribute ID', () => {
82
- const attributes = { anchor: 'foo' };
83
- const extraProps = getSaveContentExtraProps(
84
- {},
85
- {
86
- ...blockSettings,
87
- supports: {
88
- anchor: true,
89
- },
90
- },
91
- attributes
92
- );
93
-
94
- expect( extraProps.id ).toBe( 'foo' );
95
- } );
96
-
97
- it( 'should remove an anchor attribute ID when field is cleared', () => {
98
- const attributes = { anchor: '' };
99
- const extraProps = getSaveContentExtraProps(
100
- {},
101
- {
102
- ...blockSettings,
103
- supports: {
104
- anchor: true,
105
- },
106
- },
107
- attributes
108
- );
109
-
110
- expect( extraProps.id ).toBe( null );
111
- } );
112
31
  } );
113
32
  } );
@@ -14,7 +14,7 @@ import { useMemo } from '@wordpress/element';
14
14
  */
15
15
  import { useSetting } from '../components';
16
16
  import { useSettingsForBlockElement } from '../components/global-styles/hooks';
17
- import { immutableSet } from '../utils/object';
17
+ import { setImmutably } from '../utils/object';
18
18
 
19
19
  /**
20
20
  * Removed falsy values from nested object.
@@ -33,7 +33,7 @@ export const cleanEmptyObject = ( object ) => {
33
33
  const cleanedNestedObjects = Object.fromEntries(
34
34
  Object.entries( object )
35
35
  .map( ( [ key, value ] ) => [ key, cleanEmptyObject( value ) ] )
36
- .filter( ( [ , value ] ) => Boolean( value ) )
36
+ .filter( ( [ , value ] ) => value !== undefined )
37
37
  );
38
38
  return isEmpty( cleanedNestedObjects ) ? undefined : cleanedNestedObjects;
39
39
  };
@@ -82,7 +82,7 @@ export function transformStyles(
82
82
  if ( styleValue ) {
83
83
  returnBlock = {
84
84
  ...returnBlock,
85
- attributes: immutableSet(
85
+ attributes: setImmutably(
86
86
  returnBlock.attributes,
87
87
  path,
88
88
  styleValue
@@ -150,9 +150,14 @@ export function useBlockSettings( name, parentLayout ) {
150
150
  const borderWidth = useSetting( 'border.width' );
151
151
  const customColorsEnabled = useSetting( 'color.custom' );
152
152
  const customColors = useSetting( 'color.palette.custom' );
153
+ const customDuotone = useSetting( 'color.customDuotone' );
153
154
  const themeColors = useSetting( 'color.palette.theme' );
154
155
  const defaultColors = useSetting( 'color.palette.default' );
155
156
  const defaultPalette = useSetting( 'color.defaultPalette' );
157
+ const defaultDuotone = useSetting( 'color.defaultDuotone' );
158
+ const userDuotonePalette = useSetting( 'color.duotone.custom' );
159
+ const themeDuotonePalette = useSetting( 'color.duotone.theme' );
160
+ const defaultDuotonePalette = useSetting( 'color.duotone.default' );
156
161
  const userGradientPalette = useSetting( 'color.gradients.custom' );
157
162
  const themeGradientPalette = useSetting( 'color.gradients.theme' );
158
163
  const defaultGradientPalette = useSetting( 'color.gradients.default' );
@@ -175,10 +180,17 @@ export function useBlockSettings( name, parentLayout ) {
175
180
  theme: themeGradientPalette,
176
181
  default: defaultGradientPalette,
177
182
  },
183
+ duotone: {
184
+ custom: userDuotonePalette,
185
+ theme: themeDuotonePalette,
186
+ default: defaultDuotonePalette,
187
+ },
178
188
  defaultGradients,
179
189
  defaultPalette,
190
+ defaultDuotone,
180
191
  custom: customColorsEnabled,
181
192
  customGradient: areCustomGradientsEnabled,
193
+ customDuotone,
182
194
  background: isBackgroundEnabled,
183
195
  link: isLinkEnabled,
184
196
  text: isTextEnabled,
@@ -245,9 +257,14 @@ export function useBlockSettings( name, parentLayout ) {
245
257
  borderWidth,
246
258
  customColorsEnabled,
247
259
  customColors,
260
+ customDuotone,
248
261
  themeColors,
249
262
  defaultColors,
250
263
  defaultPalette,
264
+ defaultDuotone,
265
+ userDuotonePalette,
266
+ themeDuotonePalette,
267
+ defaultDuotonePalette,
251
268
  userGradientPalette,
252
269
  themeGradientPalette,
253
270
  defaultGradientPalette,
@@ -9,6 +9,9 @@ import LeafMoreMenu from './components/off-canvas-editor/leaf-more-menu';
9
9
  import ResizableBoxPopover from './components/resizable-box-popover';
10
10
  import { ComposedPrivateInserter as PrivateInserter } from './components/inserter';
11
11
  import { PrivateListView } from './components/list-view';
12
+ import BlockInfo from './components/block-info-slot-fill';
13
+ import { useShouldContextualToolbarShow } from './utils/use-should-contextual-toolbar-show';
14
+ import { cleanEmptyObject } from './hooks/utils';
12
15
 
13
16
  /**
14
17
  * Private @wordpress/block-editor APIs.
@@ -22,4 +25,7 @@ lock( privateApis, {
22
25
  PrivateInserter,
23
26
  PrivateListView,
24
27
  ResizableBoxPopover,
28
+ BlockInfo,
29
+ useShouldContextualToolbarShow,
30
+ cleanEmptyObject,
25
31
  } );
@@ -543,6 +543,9 @@ export function moveBlockToPosition(
543
543
  /**
544
544
  * Action that inserts a single block, optionally at a specific index respective a root block list.
545
545
  *
546
+ * Only allowed blocks are inserted. The action may fail silently for blocks that are not allowed or if
547
+ * a templateLock is active on the block list.
548
+ *
546
549
  * @param {Object} block Block object to insert.
547
550
  * @param {?number} index Index at which block should be inserted.
548
551
  * @param {?string} rootClientId Optional root client ID of block list on which to insert.
@@ -572,12 +575,16 @@ export function insertBlock(
572
575
  /**
573
576
  * Action that inserts an array of blocks, optionally at a specific index respective a root block list.
574
577
  *
578
+ * Only allowed blocks are inserted. The action may fail silently for blocks that are not allowed or if
579
+ * a templateLock is active on the block list.
580
+ *
575
581
  * @param {Object[]} blocks Block objects to insert.
576
582
  * @param {?number} index Index at which block should be inserted.
577
583
  * @param {?string} rootClientId Optional root client ID of block list on which to insert.
578
584
  * @param {?boolean} updateSelection If true block selection will be updated. If false, block selection will not change. Defaults to true.
579
585
  * @param {0|-1|null} initialPosition Initial focus position. Setting it to null prevent focusing the inserted block.
580
586
  * @param {?Object} meta Optional Meta values to be passed to the action object.
587
+ *
581
588
  * @return {Object} Action object.
582
589
  */
583
590
  export const insertBlocks =
@@ -42,16 +42,16 @@ function cloneObject( object ) {
42
42
  }
43
43
 
44
44
  /**
45
- * Perform an immutable set.
46
- * Handles nullish initial values.
47
- * Clones all nested objects in the specified object.
45
+ * Immutably sets a value inside an object. Like `lodash#set`, but returning a
46
+ * new object. Treats nullish initial values as empty objects. Clones any
47
+ * nested objects.
48
48
  *
49
49
  * @param {Object} object Object to set a value in.
50
50
  * @param {number|string|Array} path Path in the object to modify.
51
51
  * @param {*} value New value to set.
52
52
  * @return {Object} Cloned object with the new value set.
53
53
  */
54
- export function immutableSet( object, path, value ) {
54
+ export function setImmutably( object, path, value ) {
55
55
  const normalizedPath = normalizePath( path );
56
56
  const newObject = object ? cloneObject( object ) : {};
57
57
 
@@ -1,42 +1,42 @@
1
1
  /**
2
2
  * Internal dependencies
3
3
  */
4
- import { immutableSet } from '../object';
4
+ import { setImmutably } from '../object';
5
5
 
6
- describe( 'immutableSet', () => {
6
+ describe( 'setImmutably', () => {
7
7
  describe( 'handling falsy values properly', () => {
8
8
  it( 'should create a new object if `undefined` is passed', () => {
9
- const result = immutableSet( undefined, 'test', 1 );
9
+ const result = setImmutably( undefined, 'test', 1 );
10
10
 
11
11
  expect( result ).toEqual( { test: 1 } );
12
12
  } );
13
13
 
14
14
  it( 'should create a new object if `null` is passed', () => {
15
- const result = immutableSet( null, 'test', 1 );
15
+ const result = setImmutably( null, 'test', 1 );
16
16
 
17
17
  expect( result ).toEqual( { test: 1 } );
18
18
  } );
19
19
 
20
20
  it( 'should create a new object if `false` is passed', () => {
21
- const result = immutableSet( false, 'test', 1 );
21
+ const result = setImmutably( false, 'test', 1 );
22
22
 
23
23
  expect( result ).toEqual( { test: 1 } );
24
24
  } );
25
25
 
26
26
  it( 'should create a new object if `0` is passed', () => {
27
- const result = immutableSet( 0, 'test', 1 );
27
+ const result = setImmutably( 0, 'test', 1 );
28
28
 
29
29
  expect( result ).toEqual( { test: 1 } );
30
30
  } );
31
31
 
32
32
  it( 'should create a new object if an empty string is passed', () => {
33
- const result = immutableSet( '', 'test', 1 );
33
+ const result = setImmutably( '', 'test', 1 );
34
34
 
35
35
  expect( result ).toEqual( { test: 1 } );
36
36
  } );
37
37
 
38
38
  it( 'should create a new object if a NaN is passed', () => {
39
- const result = immutableSet( NaN, 'test', 1 );
39
+ const result = setImmutably( NaN, 'test', 1 );
40
40
 
41
41
  expect( result ).toEqual( { test: 1 } );
42
42
  } );
@@ -44,26 +44,26 @@ describe( 'immutableSet', () => {
44
44
 
45
45
  describe( 'manages data assignment properly', () => {
46
46
  it( 'assigns value properly when it does not exist', () => {
47
- const result = immutableSet( {}, 'test', 1 );
47
+ const result = setImmutably( {}, 'test', 1 );
48
48
 
49
49
  expect( result ).toEqual( { test: 1 } );
50
50
  } );
51
51
 
52
52
  it( 'overrides existing values', () => {
53
- const result = immutableSet( { test: 1 }, 'test', 2 );
53
+ const result = setImmutably( { test: 1 }, 'test', 2 );
54
54
 
55
55
  expect( result ).toEqual( { test: 2 } );
56
56
  } );
57
57
 
58
58
  describe( 'with array notation access', () => {
59
59
  it( 'assigns values at deeper levels', () => {
60
- const result = immutableSet( {}, [ 'foo', 'bar', 'baz' ], 5 );
60
+ const result = setImmutably( {}, [ 'foo', 'bar', 'baz' ], 5 );
61
61
 
62
62
  expect( result ).toEqual( { foo: { bar: { baz: 5 } } } );
63
63
  } );
64
64
 
65
65
  it( 'overrides existing values at deeper levels', () => {
66
- const result = immutableSet(
66
+ const result = setImmutably(
67
67
  { foo: { bar: { baz: 1 } } },
68
68
  [ 'foo', 'bar', 'baz' ],
69
69
  5
@@ -73,7 +73,7 @@ describe( 'immutableSet', () => {
73
73
  } );
74
74
 
75
75
  it( 'keeps other properties intact', () => {
76
- const result = immutableSet(
76
+ const result = setImmutably(
77
77
  { foo: { bar: { baz: 1 } } },
78
78
  [ 'foo', 'bar', 'test' ],
79
79
  5
@@ -87,37 +87,37 @@ describe( 'immutableSet', () => {
87
87
 
88
88
  describe( 'for nested falsey values', () => {
89
89
  it( 'overwrites undefined values', () => {
90
- const result = immutableSet( { test: undefined }, 'test', 1 );
90
+ const result = setImmutably( { test: undefined }, 'test', 1 );
91
91
 
92
92
  expect( result ).toEqual( { test: 1 } );
93
93
  } );
94
94
 
95
95
  it( 'overwrites null values', () => {
96
- const result = immutableSet( { test: null }, 'test', 1 );
96
+ const result = setImmutably( { test: null }, 'test', 1 );
97
97
 
98
98
  expect( result ).toEqual( { test: 1 } );
99
99
  } );
100
100
 
101
101
  it( 'overwrites false values', () => {
102
- const result = immutableSet( { test: false }, 'test', 1 );
102
+ const result = setImmutably( { test: false }, 'test', 1 );
103
103
 
104
104
  expect( result ).toEqual( { test: 1 } );
105
105
  } );
106
106
 
107
107
  it( 'overwrites `0` values', () => {
108
- const result = immutableSet( { test: 0 }, 'test', 1 );
108
+ const result = setImmutably( { test: 0 }, 'test', 1 );
109
109
 
110
110
  expect( result ).toEqual( { test: 1 } );
111
111
  } );
112
112
 
113
113
  it( 'overwrites empty string values', () => {
114
- const result = immutableSet( { test: '' }, 'test', 1 );
114
+ const result = setImmutably( { test: '' }, 'test', 1 );
115
115
 
116
116
  expect( result ).toEqual( { test: 1 } );
117
117
  } );
118
118
 
119
119
  it( 'overwrites NaN values', () => {
120
- const result = immutableSet( { test: NaN }, 'test', 1 );
120
+ const result = setImmutably( { test: NaN }, 'test', 1 );
121
121
 
122
122
  expect( result ).toEqual( { test: 1 } );
123
123
  } );
@@ -127,14 +127,14 @@ describe( 'immutableSet', () => {
127
127
  describe( 'does not mutate the original object', () => {
128
128
  it( 'clones the object at the first level', () => {
129
129
  const input = {};
130
- const result = immutableSet( input, 'test', 1 );
130
+ const result = setImmutably( input, 'test', 1 );
131
131
 
132
132
  expect( result ).not.toBe( input );
133
133
  } );
134
134
 
135
135
  it( 'clones the object at deeper levels', () => {
136
136
  const input = { foo: { bar: { baz: 1 } } };
137
- const result = immutableSet( input, [ 'foo', 'bar', 'baz' ], 2 );
137
+ const result = setImmutably( input, [ 'foo', 'bar', 'baz' ], 2 );
138
138
 
139
139
  expect( result ).not.toBe( input );
140
140
  expect( result.foo ).not.toBe( input.foo );
@@ -13,8 +13,8 @@ import wrap from './transforms/wrap';
13
13
  /**
14
14
  * Applies a series of CSS rule transforms to wrap selectors inside a given class and/or rewrite URLs depending on the parameters passed.
15
15
  *
16
- * @param {Array} styles CSS rules.
17
- * @param {string} wrapperClassName Wrapper Class Name.
16
+ * @param {Object|Array} styles CSS rules.
17
+ * @param {string} wrapperClassName Wrapper Class Name.
18
18
  * @return {Array} converted rules.
19
19
  */
20
20
  const transformStyles = ( styles, wrapperClassName = '' ) => {
@@ -0,0 +1,75 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect } from '@wordpress/data';
5
+ import { isUnmodifiedDefaultBlock } from '@wordpress/blocks';
6
+ import { useViewportMatch } from '@wordpress/compose';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import { store as blockEditorStore } from '../store';
12
+ import { unlock } from '../lock-unlock';
13
+
14
+ /**
15
+ * Returns true if the contextual block toolbar should show, or false if it should be hidden.
16
+ *
17
+ * @param {string} clientId The client ID of the block.
18
+ *
19
+ * @return {boolean} Whether the block toolbar is hidden.
20
+ */
21
+ export function useShouldContextualToolbarShow( clientId ) {
22
+ const isLargeViewport = useViewportMatch( 'medium' );
23
+
24
+ const { shouldShowContextualToolbar, canFocusHiddenToolbar } = useSelect(
25
+ ( select ) => {
26
+ const {
27
+ __unstableGetEditorMode,
28
+ isMultiSelecting,
29
+ isTyping,
30
+ isBlockInterfaceHidden,
31
+ getBlock,
32
+ getSettings,
33
+ isNavigationMode,
34
+ } = unlock( select( blockEditorStore ) );
35
+
36
+ const isEditMode = __unstableGetEditorMode() === 'edit';
37
+ const hasFixedToolbar = getSettings().hasFixedToolbar;
38
+ const isDistractionFree = getSettings().isDistractionFree;
39
+ const hasClientId = !! clientId;
40
+ const isEmptyDefaultBlock = isUnmodifiedDefaultBlock(
41
+ getBlock( clientId ) || {}
42
+ );
43
+
44
+ const _shouldShowContextualToolbar =
45
+ isEditMode &&
46
+ ! hasFixedToolbar &&
47
+ ( ! isDistractionFree || isNavigationMode() ) &&
48
+ isLargeViewport &&
49
+ ! isMultiSelecting() &&
50
+ ! isTyping() &&
51
+ hasClientId &&
52
+ ! isEmptyDefaultBlock &&
53
+ ! isBlockInterfaceHidden();
54
+
55
+ const _canFocusHiddenToolbar =
56
+ isEditMode &&
57
+ hasClientId &&
58
+ ! _shouldShowContextualToolbar &&
59
+ ! hasFixedToolbar &&
60
+ ! isDistractionFree &&
61
+ ! isEmptyDefaultBlock;
62
+
63
+ return {
64
+ shouldShowContextualToolbar: _shouldShowContextualToolbar,
65
+ canFocusHiddenToolbar: _canFocusHiddenToolbar,
66
+ };
67
+ },
68
+ [ clientId, isLargeViewport ]
69
+ );
70
+
71
+ return {
72
+ shouldShowContextualToolbar,
73
+ canFocusHiddenToolbar,
74
+ };
75
+ }
package/tsconfig.json CHANGED
@@ -23,6 +23,7 @@
23
23
  { "path": "../icons" },
24
24
  { "path": "../is-shallow-equal" },
25
25
  { "path": "../keycodes" },
26
+ { "path": "../notices" },
26
27
  { "path": "../style-engine" },
27
28
  { "path": "../token-list" },
28
29
  { "path": "../url" },