@wordpress/block-editor 10.1.1-next.4d3b314fd5.0 → 10.2.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 (80) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/block-controls/slot.js +2 -2
  3. package/build/components/block-controls/slot.js.map +1 -1
  4. package/build/components/block-inspector/index.js +4 -5
  5. package/build/components/block-inspector/index.js.map +1 -1
  6. package/build/components/block-parent-selector/index.js +2 -2
  7. package/build/components/block-parent-selector/index.js.map +1 -1
  8. package/build/components/block-popover/inbetween.js +3 -1
  9. package/build/components/block-popover/inbetween.js.map +1 -1
  10. package/build/components/block-popover/index.js +20 -16
  11. package/build/components/block-popover/index.js.map +1 -1
  12. package/build/components/block-settings-menu/block-settings-dropdown.js +5 -5
  13. package/build/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  14. package/build/components/image-editor/use-transform-image.js +2 -2
  15. package/build/components/image-editor/use-transform-image.js.map +1 -1
  16. package/build/components/inserter/block-types-tab.js +1 -1
  17. package/build/components/inserter/block-types-tab.js.map +1 -1
  18. package/build/components/inserter/search-items.js +2 -17
  19. package/build/components/inserter/search-items.js.map +1 -1
  20. package/build/components/inspector-controls/slot.js +2 -1
  21. package/build/components/inspector-controls/slot.js.map +1 -1
  22. package/build/components/rich-text/index.js +17 -0
  23. package/build/components/rich-text/index.js.map +1 -1
  24. package/build/components/spacing-sizes-control/index.js +10 -2
  25. package/build/components/spacing-sizes-control/index.js.map +1 -1
  26. package/build/components/spacing-sizes-control/spacing-input-control.js +5 -4
  27. package/build/components/spacing-sizes-control/spacing-input-control.js.map +1 -1
  28. package/build/store/reducer.js +5 -3
  29. package/build/store/reducer.js.map +1 -1
  30. package/build-module/components/block-controls/slot.js +3 -3
  31. package/build-module/components/block-controls/slot.js.map +1 -1
  32. package/build-module/components/block-inspector/index.js +5 -6
  33. package/build-module/components/block-inspector/index.js.map +1 -1
  34. package/build-module/components/block-parent-selector/index.js +2 -2
  35. package/build-module/components/block-parent-selector/index.js.map +1 -1
  36. package/build-module/components/block-popover/inbetween.js +3 -1
  37. package/build-module/components/block-popover/inbetween.js.map +1 -1
  38. package/build-module/components/block-popover/index.js +20 -16
  39. package/build-module/components/block-popover/index.js.map +1 -1
  40. package/build-module/components/block-settings-menu/block-settings-dropdown.js +7 -7
  41. package/build-module/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  42. package/build-module/components/image-editor/use-transform-image.js +2 -2
  43. package/build-module/components/image-editor/use-transform-image.js.map +1 -1
  44. package/build-module/components/inserter/block-types-tab.js +3 -3
  45. package/build-module/components/inserter/block-types-tab.js.map +1 -1
  46. package/build-module/components/inserter/search-items.js +3 -17
  47. package/build-module/components/inserter/search-items.js.map +1 -1
  48. package/build-module/components/inspector-controls/slot.js +3 -2
  49. package/build-module/components/inspector-controls/slot.js.map +1 -1
  50. package/build-module/components/rich-text/index.js +17 -0
  51. package/build-module/components/rich-text/index.js.map +1 -1
  52. package/build-module/components/spacing-sizes-control/index.js +10 -3
  53. package/build-module/components/spacing-sizes-control/index.js.map +1 -1
  54. package/build-module/components/spacing-sizes-control/spacing-input-control.js +6 -5
  55. package/build-module/components/spacing-sizes-control/spacing-input-control.js.map +1 -1
  56. package/build-module/store/reducer.js +5 -4
  57. package/build-module/store/reducer.js.map +1 -1
  58. package/build-style/style-rtl.css +28 -23
  59. package/build-style/style.css +28 -23
  60. package/package.json +28 -29
  61. package/src/components/block-controls/slot.js +3 -3
  62. package/src/components/block-inspector/index.js +6 -10
  63. package/src/components/block-parent-selector/index.js +2 -2
  64. package/src/components/block-popover/inbetween.js +1 -1
  65. package/src/components/block-popover/index.js +37 -21
  66. package/src/components/block-settings-menu/block-settings-dropdown.js +7 -7
  67. package/src/components/block-switcher/test/__snapshots__/index.js.snap +104 -33
  68. package/src/components/block-switcher/test/index.js +121 -61
  69. package/src/components/button-block-appender/style.scss +3 -1
  70. package/src/components/image-editor/use-transform-image.js +2 -2
  71. package/src/components/inserter/block-types-tab.js +3 -3
  72. package/src/components/inserter/search-items.js +3 -15
  73. package/src/components/inserter/test/search-items.js +4 -0
  74. package/src/components/inspector-controls/slot.js +6 -2
  75. package/src/components/responsive-block-control/test/index.js +73 -118
  76. package/src/components/rich-text/index.js +22 -0
  77. package/src/components/spacing-sizes-control/index.js +15 -3
  78. package/src/components/spacing-sizes-control/spacing-input-control.js +8 -7
  79. package/src/components/spacing-sizes-control/style.scss +28 -24
  80. package/src/store/reducer.js +4 -4
@@ -1,14 +1,14 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { shallow, mount } from 'enzyme';
4
+ import { render, screen, within } from '@testing-library/react';
5
+ import userEvent from '@testing-library/user-event';
5
6
 
6
7
  /**
7
8
  * WordPress dependencies
8
9
  */
9
10
  import { useSelect } from '@wordpress/data';
10
11
  import { registerBlockType, unregisterBlockType } from '@wordpress/blocks';
11
- import { Button } from '@wordpress/components';
12
12
  import { copy } from '@wordpress/icons';
13
13
 
14
14
  /**
@@ -17,23 +17,25 @@ import { copy } from '@wordpress/icons';
17
17
  import { BlockSwitcher, BlockSwitcherDropdownMenu } from '../';
18
18
 
19
19
  jest.mock( '@wordpress/data/src/components/use-select', () => jest.fn() );
20
- jest.mock( '../../block-title/use-block-display-title', () => jest.fn() );
20
+ jest.mock( '../../block-title/use-block-display-title', () =>
21
+ jest.fn().mockReturnValue( 'Block Name' )
22
+ );
21
23
 
22
24
  describe( 'BlockSwitcher', () => {
23
25
  test( 'should not render block switcher without blocks', () => {
24
26
  useSelect.mockImplementation( () => ( {} ) );
25
- const wrapper = shallow( <BlockSwitcher /> );
26
- expect( wrapper.html() ).toBeNull();
27
+ const { container } = render( <BlockSwitcher /> );
28
+ expect( container ).toBeEmptyDOMElement();
27
29
  } );
28
30
 
29
31
  test( 'should not render block switcher with null blocks', () => {
30
32
  useSelect.mockImplementation( () => ( { blocks: [ null ] } ) );
31
- const wrapper = shallow(
33
+ const { container } = render(
32
34
  <BlockSwitcher
33
35
  clientIds={ [ 'a1303fd6-3e60-4fff-a770-0e0ea656c5b9' ] }
34
36
  />
35
37
  );
36
- expect( wrapper.html() ).toBeNull();
38
+ expect( container ).toBeEmptyDOMElement();
37
39
  } );
38
40
  } );
39
41
  describe( 'BlockSwitcherDropdownMenu', () => {
@@ -122,10 +124,10 @@ describe( 'BlockSwitcherDropdownMenu', () => {
122
124
  ],
123
125
  canRemove: true,
124
126
  } ) );
125
- const wrapper = shallow(
127
+ const { container } = render(
126
128
  <BlockSwitcherDropdownMenu blocks={ [ headingBlock1 ] } />
127
129
  );
128
- expect( wrapper ).toMatchSnapshot();
130
+ expect( container ).toMatchSnapshot();
129
131
  } );
130
132
 
131
133
  test( 'should render disabled block switcher with multi block of different types when no transforms', () => {
@@ -133,12 +135,12 @@ describe( 'BlockSwitcherDropdownMenu', () => {
133
135
  possibleBlockTransformations: [],
134
136
  icon: copy,
135
137
  } ) );
136
- const wrapper = shallow(
138
+ const { container } = render(
137
139
  <BlockSwitcherDropdownMenu
138
140
  blocks={ [ headingBlock1, textBlock ] }
139
141
  />
140
142
  );
141
- expect( wrapper ).toMatchSnapshot();
143
+ expect( container ).toMatchSnapshot();
142
144
  } );
143
145
 
144
146
  test( 'should render enabled block switcher with multi block when transforms exist', () => {
@@ -149,12 +151,12 @@ describe( 'BlockSwitcherDropdownMenu', () => {
149
151
  ],
150
152
  canRemove: true,
151
153
  } ) );
152
- const wrapper = shallow(
154
+ const { container } = render(
153
155
  <BlockSwitcherDropdownMenu
154
156
  blocks={ [ headingBlock1, headingBlock2 ] }
155
157
  />
156
158
  );
157
- expect( wrapper ).toMatchSnapshot();
159
+ expect( container ).toMatchSnapshot();
158
160
  } );
159
161
 
160
162
  describe( 'Dropdown', () => {
@@ -166,70 +168,128 @@ describe( 'BlockSwitcherDropdownMenu', () => {
166
168
  canRemove: true,
167
169
  } ) );
168
170
  } );
169
- const getDropdown = () =>
170
- mount(
171
- <BlockSwitcherDropdownMenu blocks={ [ headingBlock1 ] } />
172
- ).find( 'Dropdown' );
173
171
 
174
172
  test( 'should dropdown exist', () => {
175
- expect( getDropdown() ).toHaveLength( 1 );
176
- } );
173
+ render(
174
+ <BlockSwitcherDropdownMenu blocks={ [ headingBlock1 ] } />
175
+ );
177
176
 
178
- describe( '.renderToggle', () => {
179
- const onToggleStub = jest.fn();
180
- const mockKeyDown = {
181
- preventDefault: () => {},
182
- code: 'ArrowDown',
183
- };
177
+ expect(
178
+ screen.getByRole( 'button', {
179
+ name: 'Block Name',
180
+ expanded: false,
181
+ } )
182
+ ).toBeVisible();
183
+ } );
184
184
 
185
- afterEach( () => {
186
- onToggleStub.mockReset();
185
+ test( 'should simulate a keydown event, which should open transform toggle.', async () => {
186
+ const user = userEvent.setup( {
187
+ advanceTimers: jest.advanceTimersByTime,
187
188
  } );
188
189
 
189
- test( 'should simulate a keydown event, which should call onToggle and open transform toggle.', () => {
190
- const toggleClosed = mount(
191
- getDropdown().props().renderToggle( {
192
- onToggle: onToggleStub,
193
- isOpen: false,
194
- } )
195
- );
196
- const iconButtonClosed = toggleClosed.find( Button );
190
+ render(
191
+ <BlockSwitcherDropdownMenu blocks={ [ headingBlock1 ] } />
192
+ );
193
+
194
+ expect(
195
+ screen.getByRole( 'button', {
196
+ name: 'Block Name',
197
+ expanded: false,
198
+ } )
199
+ ).toBeVisible();
200
+ expect(
201
+ screen.queryByRole( 'menu', {
202
+ name: 'Block Name',
203
+ } )
204
+ ).not.toBeInTheDocument();
205
+
206
+ await user.type(
207
+ screen.getByRole( 'button', {
208
+ name: 'Block Name',
209
+ expanded: false,
210
+ } ),
211
+ '[ArrowDown]'
212
+ );
197
213
 
198
- iconButtonClosed.simulate( 'keydown', mockKeyDown );
214
+ expect(
215
+ screen.getByRole( 'button', {
216
+ name: 'Block Name',
217
+ expanded: true,
218
+ } )
219
+ ).toBeVisible();
199
220
 
200
- expect( onToggleStub ).toHaveBeenCalledTimes( 1 );
221
+ const menu = screen.getByRole( 'menu', {
222
+ name: 'Block Name',
201
223
  } );
224
+ expect( menu ).toBeInTheDocument();
225
+ expect( menu ).not.toBeVisible();
226
+ } );
202
227
 
203
- test( 'should simulate a click event, which should call onToggle.', () => {
204
- const toggleOpen = mount(
205
- getDropdown().props().renderToggle( {
206
- onToggle: onToggleStub,
207
- isOpen: true,
208
- } )
209
- );
210
- const iconButtonOpen = toggleOpen.find( Button );
228
+ test( 'should simulate a click event, which should call onToggle.', async () => {
229
+ const user = userEvent.setup( {
230
+ advanceTimers: jest.advanceTimersByTime,
231
+ } );
232
+
233
+ render(
234
+ <BlockSwitcherDropdownMenu blocks={ [ headingBlock1 ] } />
235
+ );
236
+
237
+ expect(
238
+ screen.getByRole( 'button', {
239
+ name: 'Block Name',
240
+ expanded: false,
241
+ } )
242
+ ).toBeVisible();
243
+ expect(
244
+ screen.queryByRole( 'menu', {
245
+ name: 'Block Name',
246
+ } )
247
+ ).not.toBeInTheDocument();
248
+
249
+ await user.click(
250
+ screen.getByRole( 'button', {
251
+ name: 'Block Name',
252
+ expanded: false,
253
+ } )
254
+ );
211
255
 
212
- iconButtonOpen.simulate( 'keydown', mockKeyDown );
256
+ expect(
257
+ screen.getByRole( 'button', {
258
+ name: 'Block Name',
259
+ expanded: true,
260
+ } )
261
+ ).toBeVisible();
213
262
 
214
- expect( onToggleStub ).toHaveBeenCalledTimes( 0 );
263
+ const menu = screen.getByRole( 'menu', {
264
+ name: 'Block Name',
215
265
  } );
266
+ expect( menu ).toBeInTheDocument();
267
+ expect( menu ).not.toBeVisible();
216
268
  } );
217
269
 
218
- describe( '.renderContent', () => {
219
- test( 'should create the transform items for the chosen block. A heading block will have 3 items', () => {
220
- const onCloseStub = jest.fn();
221
- const content = shallow(
222
- <div>
223
- { getDropdown()
224
- .props()
225
- .renderContent( { onClose: onCloseStub } ) }
226
- </div>
227
- );
228
- const blockList = content.find( 'BlockTransformationsMenu' );
229
- expect(
230
- blockList.prop( 'possibleBlockTransformations' )
231
- ).toHaveLength( 1 );
270
+ test( 'should create the transform items for the chosen block.', async () => {
271
+ const user = userEvent.setup( {
272
+ advanceTimers: jest.advanceTimersByTime,
232
273
  } );
274
+
275
+ render(
276
+ <BlockSwitcherDropdownMenu blocks={ [ headingBlock1 ] } />
277
+ );
278
+
279
+ await user.click(
280
+ screen.getByRole( 'button', {
281
+ name: 'Block Name',
282
+ expanded: false,
283
+ } )
284
+ );
285
+
286
+ expect(
287
+ within(
288
+ screen.getByRole( 'menu', {
289
+ name: 'Block Name',
290
+ } )
291
+ ).getAllByRole( 'menuitem' )
292
+ ).toHaveLength( 1 );
233
293
  } );
234
294
  } );
235
295
  } );
@@ -35,7 +35,9 @@
35
35
  // When the appender shows up in empty container blocks, such as Group and Columns, add an extra click state.
36
36
  .block-list-appender:only-child {
37
37
  .is-layout-constrained.block-editor-block-list__block:not(.is-selected) > &,
38
- .is-layout-flow.block-editor-block-list__block:not(.is-selected) > & {
38
+ .is-layout-flow.block-editor-block-list__block:not(.is-selected) > &,
39
+ .is-layout-constrained.block-editor-block-list__block:not(.is-selected) > .block-editor-block-list__layout > &,
40
+ .is-layout-flow.block-editor-block-list__block:not(.is-selected) > .block-editor-block-list__layout > & {
39
41
  pointer-events: none;
40
42
 
41
43
  &::after {
@@ -41,7 +41,7 @@ function useTransformState( { url, naturalWidth, naturalHeight } ) {
41
41
  if ( angle === 0 ) {
42
42
  setEditedUrl();
43
43
  setRotation( angle );
44
- setAspect( 1 / aspect );
44
+ setAspect( naturalWidth / naturalHeight );
45
45
  setPosition( {
46
46
  x: -( position.y * naturalAspectRatio ),
47
47
  y: position.x * naturalAspectRatio,
@@ -80,7 +80,7 @@ function useTransformState( { url, naturalWidth, naturalHeight } ) {
80
80
  canvas.toBlob( ( blob ) => {
81
81
  setEditedUrl( URL.createObjectURL( blob ) );
82
82
  setRotation( angle );
83
- setAspect( 1 / aspect );
83
+ setAspect( canvas.width / canvas.height );
84
84
  setPosition( {
85
85
  x: -( position.y * naturalAspectRatio ),
86
86
  y: position.x * naturalAspectRatio,
@@ -1,14 +1,14 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { map, flow, groupBy, orderBy } from 'lodash';
4
+ import { map, groupBy, orderBy } from 'lodash';
5
5
 
6
6
  /**
7
7
  * WordPress dependencies
8
8
  */
9
9
  import { __, _x } from '@wordpress/i18n';
10
10
  import { useMemo, useEffect } from '@wordpress/element';
11
- import { useAsyncList } from '@wordpress/compose';
11
+ import { pipe, useAsyncList } from '@wordpress/compose';
12
12
 
13
13
  /**
14
14
  * Internal dependencies
@@ -53,7 +53,7 @@ export function BlockTypesTab( {
53
53
  }, [ items ] );
54
54
 
55
55
  const itemsPerCategory = useMemo( () => {
56
- return flow(
56
+ return pipe(
57
57
  ( itemList ) =>
58
58
  itemList.filter(
59
59
  ( item ) => item.category && item.category !== 'reusable'
@@ -1,9 +1,8 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { noCase } from 'change-case';
5
4
  import removeAccents from 'remove-accents';
6
- import { find } from 'lodash';
5
+ import { find, words } from 'lodash';
7
6
 
8
7
  // Default search helpers.
9
8
  const defaultGetName = ( item ) => item.name || '';
@@ -36,17 +35,6 @@ function normalizeSearchInput( input = '' ) {
36
35
  return input;
37
36
  }
38
37
 
39
- /**
40
- * Extracts words from an input string.
41
- *
42
- * @param {string} input The input string.
43
- *
44
- * @return {Array} Words, extracted from the input string.
45
- */
46
- function extractWords( input = '' ) {
47
- return noCase( input ).split( ' ' ).filter( Boolean );
48
- }
49
-
50
38
  /**
51
39
  * Converts the search term into a list of normalized terms.
52
40
  *
@@ -55,7 +43,7 @@ function extractWords( input = '' ) {
55
43
  * @return {string[]} The normalized list of search terms.
56
44
  */
57
45
  export const getNormalizedSearchTerms = ( input = '' ) => {
58
- return extractWords( normalizeSearchInput( input ) );
46
+ return words( normalizeSearchInput( input ) );
59
47
  };
60
48
 
61
49
  const removeMatchingTerms = ( unmatchedTerms, unprocessedTerms ) => {
@@ -162,7 +150,7 @@ export function getItemSearchRank( item, searchTerm, config = {} ) {
162
150
  category,
163
151
  collection,
164
152
  ].join( ' ' );
165
- const normalizedSearchTerms = extractWords( normalizedSearchInput );
153
+ const normalizedSearchTerms = words( normalizedSearchInput );
166
154
  const unmatchedTerms = removeMatchingTerms(
167
155
  normalizedSearchTerms,
168
156
  terms
@@ -42,6 +42,10 @@ describe( 'getNormalizedSearchTerms', () => {
42
42
  getNormalizedSearchTerms( ' Média & Text Tag-Cloud > 123' )
43
43
  ).toEqual( [ 'media', 'text', 'tag', 'cloud', '123' ] );
44
44
  } );
45
+
46
+ it( 'should support non-latin letters', () => {
47
+ expect( getNormalizedSearchTerms( 'მედია' ) ).toEqual( [ 'მედია' ] );
48
+ } );
45
49
  } );
46
50
 
47
51
  describe( 'getItemSearchRank', () => {
@@ -1,7 +1,10 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { __experimentalUseSlot as useSlot } from '@wordpress/components';
4
+ import {
5
+ __experimentalUseSlot as useSlot,
6
+ __experimentalUseSlotFills as useSlotFills,
7
+ } from '@wordpress/components';
5
8
  import warning from '@wordpress/warning';
6
9
 
7
10
  /**
@@ -18,12 +21,13 @@ export default function InspectorControlsSlot( {
18
21
  } ) {
19
22
  const Slot = groups[ group ]?.Slot;
20
23
  const slot = useSlot( Slot?.__unstableName );
24
+ const fills = useSlotFills( Slot?.__unstableName );
21
25
  if ( ! Slot || ! slot ) {
22
26
  warning( `Unknown InspectorControl group "${ group }" provided.` );
23
27
  return null;
24
28
  }
25
29
 
26
- const hasFills = Boolean( slot.fills && slot.fills.length );
30
+ const hasFills = Boolean( fills && fills.length );
27
31
  if ( ! hasFills ) {
28
32
  return null;
29
33
  }