@wordpress/block-editor 9.5.0 → 9.6.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.
- package/CHANGELOG.md +2 -0
- package/build/components/block-lock/modal.js +2 -2
- package/build/components/block-lock/modal.js.map +1 -1
- package/build/components/block-mobile-toolbar/block-actions-menu.native.js +1 -1
- package/build/components/block-mobile-toolbar/block-actions-menu.native.js.map +1 -1
- package/build/components/block-mover/mover-description.js +95 -32
- package/build/components/block-mover/mover-description.js.map +1 -1
- package/build/components/block-settings-menu-controls/index.js +1 -1
- package/build/components/block-settings-menu-controls/index.js.map +1 -1
- package/build/components/block-styles/preview.native.js +1 -3
- package/build/components/block-styles/preview.native.js.map +1 -1
- package/build/components/block-tools/block-selection-button.js +1 -7
- package/build/components/block-tools/block-selection-button.js.map +1 -1
- package/build/components/block-tools/index.js +4 -1
- package/build/components/block-tools/index.js.map +1 -1
- package/build/components/block-types-list/index.native.js +65 -23
- package/build/components/block-types-list/index.native.js.map +1 -1
- package/build/components/colors-gradients/control.js +1 -0
- package/build/components/colors-gradients/control.js.map +1 -1
- package/build/components/colors-gradients/dropdown.js +5 -2
- package/build/components/colors-gradients/dropdown.js.map +1 -1
- package/build/components/image-editor/cropper.js +4 -3
- package/build/components/image-editor/cropper.js.map +1 -1
- package/build/components/image-editor/index.js +3 -1
- package/build/components/image-editor/index.js.map +1 -1
- package/build/components/inserter/block-types-tab.native.js +30 -16
- package/build/components/inserter/block-types-tab.native.js.map +1 -1
- package/build/components/inserter/preview-panel.js +8 -8
- package/build/components/inserter/preview-panel.js.map +1 -1
- package/build/components/inserter/reusable-blocks-tab.native.js +5 -1
- package/build/components/inserter/reusable-blocks-tab.native.js.map +1 -1
- package/build/components/inserter/search-results.native.js +5 -2
- package/build/components/inserter/search-results.native.js.map +1 -1
- package/build/components/inserter/utils.native.js +21 -0
- package/build/components/inserter/utils.native.js.map +1 -1
- package/build/components/inserter-list-item/index.js +5 -1
- package/build/components/inserter-list-item/index.js.map +1 -1
- package/build/components/list-view/branch.js +1 -7
- package/build/components/list-view/branch.js.map +1 -1
- package/build/components/observe-typing/index.js +22 -8
- package/build/components/observe-typing/index.js.map +1 -1
- package/build/components/rich-text/format-toolbar-container.js +61 -12
- package/build/components/rich-text/format-toolbar-container.js.map +1 -1
- package/build/components/rich-text/index.js +2 -1
- package/build/components/rich-text/index.js.map +1 -1
- package/build/components/rich-text/use-format-types.js +36 -16
- package/build/components/rich-text/use-format-types.js.map +1 -1
- package/build/components/writing-flow/use-tab-nav.js +1 -1
- package/build/components/writing-flow/use-tab-nav.js.map +1 -1
- package/build/hooks/layout.js +14 -2
- package/build/hooks/layout.js.map +1 -1
- package/build/hooks/style.js +41 -31
- package/build/hooks/style.js.map +1 -1
- package/build/layouts/flow.js +26 -3
- package/build/layouts/flow.js.map +1 -1
- package/build-module/components/block-lock/modal.js +2 -2
- package/build-module/components/block-lock/modal.js.map +1 -1
- package/build-module/components/block-mobile-toolbar/block-actions-menu.native.js +2 -2
- package/build-module/components/block-mobile-toolbar/block-actions-menu.native.js.map +1 -1
- package/build-module/components/block-mover/mover-description.js +97 -33
- package/build-module/components/block-mover/mover-description.js.map +1 -1
- package/build-module/components/block-settings-menu-controls/index.js +2 -2
- package/build-module/components/block-settings-menu-controls/index.js.map +1 -1
- package/build-module/components/block-styles/preview.native.js +2 -3
- package/build-module/components/block-styles/preview.native.js.map +1 -1
- package/build-module/components/block-tools/block-selection-button.js +1 -7
- package/build-module/components/block-tools/block-selection-button.js.map +1 -1
- package/build-module/components/block-tools/index.js +4 -1
- package/build-module/components/block-tools/index.js.map +1 -1
- package/build-module/components/block-types-list/index.native.js +67 -25
- package/build-module/components/block-types-list/index.native.js.map +1 -1
- package/build-module/components/colors-gradients/control.js +1 -0
- package/build-module/components/colors-gradients/control.js.map +1 -1
- package/build-module/components/colors-gradients/dropdown.js +6 -3
- package/build-module/components/colors-gradients/dropdown.js.map +1 -1
- package/build-module/components/image-editor/cropper.js +4 -3
- package/build-module/components/image-editor/cropper.js.map +1 -1
- package/build-module/components/image-editor/index.js +3 -1
- package/build-module/components/image-editor/index.js.map +1 -1
- package/build-module/components/inserter/block-types-tab.native.js +31 -15
- package/build-module/components/inserter/block-types-tab.native.js.map +1 -1
- package/build-module/components/inserter/preview-panel.js +9 -9
- package/build-module/components/inserter/preview-panel.js.map +1 -1
- package/build-module/components/inserter/reusable-blocks-tab.native.js +6 -2
- package/build-module/components/inserter/reusable-blocks-tab.native.js.map +1 -1
- package/build-module/components/inserter/search-results.native.js +6 -3
- package/build-module/components/inserter/search-results.native.js.map +1 -1
- package/build-module/components/inserter/utils.native.js +19 -0
- package/build-module/components/inserter/utils.native.js.map +1 -1
- package/build-module/components/inserter-list-item/index.js +4 -1
- package/build-module/components/inserter-list-item/index.js.map +1 -1
- package/build-module/components/list-view/branch.js +1 -6
- package/build-module/components/list-view/branch.js.map +1 -1
- package/build-module/components/observe-typing/index.js +22 -8
- package/build-module/components/observe-typing/index.js.map +1 -1
- package/build-module/components/rich-text/format-toolbar-container.js +58 -12
- package/build-module/components/rich-text/format-toolbar-container.js.map +1 -1
- package/build-module/components/rich-text/index.js +2 -1
- package/build-module/components/rich-text/index.js.map +1 -1
- package/build-module/components/rich-text/use-format-types.js +37 -18
- package/build-module/components/rich-text/use-format-types.js.map +1 -1
- package/build-module/components/writing-flow/use-tab-nav.js +1 -1
- package/build-module/components/writing-flow/use-tab-nav.js.map +1 -1
- package/build-module/hooks/layout.js +14 -2
- package/build-module/hooks/layout.js.map +1 -1
- package/build-module/hooks/style.js +44 -35
- package/build-module/hooks/style.js.map +1 -1
- package/build-module/layouts/flow.js +25 -3
- package/build-module/layouts/flow.js.map +1 -1
- package/build-style/style-rtl.css +2 -2
- package/build-style/style.css +2 -2
- package/package.json +28 -28
- package/src/components/block-lock/modal.js +5 -5
- package/src/components/block-mobile-toolbar/block-actions-menu.native.js +3 -3
- package/src/components/block-mover/mover-description.js +131 -48
- package/src/components/block-mover/test/mover-description.js +55 -3
- package/src/components/block-settings-menu-controls/index.js +2 -2
- package/src/components/block-styles/preview.native.js +2 -2
- package/src/components/block-tools/block-selection-button.js +0 -5
- package/src/components/block-tools/index.js +4 -1
- package/src/components/block-types-list/index.native.js +76 -24
- package/src/components/block-types-list/style.native.scss +18 -0
- package/src/components/color-palette/test/__snapshots__/control.js.snap +0 -4
- package/src/components/colors/test/__snapshots__/with-colors.js.snap +1 -1
- package/src/components/colors/test/with-colors.js +1 -1
- package/src/components/colors-gradients/control.js +1 -0
- package/src/components/colors-gradients/dropdown.js +8 -2
- package/src/components/colors-gradients/style.scss +7 -8
- package/src/components/image-editor/cropper.js +9 -3
- package/src/components/image-editor/index.js +2 -0
- package/src/components/inserter/block-types-tab.native.js +42 -21
- package/src/components/inserter/preview-panel.js +6 -14
- package/src/components/inserter/reusable-blocks-tab.native.js +4 -2
- package/src/components/inserter/search-results.native.js +4 -2
- package/src/components/inserter/test/block-types-tab.native.js +2 -0
- package/src/components/inserter/test/utils.native.js +37 -0
- package/src/components/inserter/utils.native.js +11 -0
- package/src/components/inserter-list-item/index.js +4 -1
- package/src/components/list-view/branch.js +1 -6
- package/src/components/observe-typing/index.js +17 -14
- package/src/components/rich-text/format-toolbar-container.js +63 -14
- package/src/components/rich-text/index.js +1 -0
- package/src/components/rich-text/use-format-types.js +38 -17
- package/src/components/writing-flow/use-tab-nav.js +1 -1
- package/src/hooks/layout.js +14 -3
- package/src/hooks/style.js +46 -39
- package/src/layouts/flow.js +23 -1
|
@@ -53,6 +53,8 @@ export default function BlockTools( {
|
|
|
53
53
|
} = useDispatch( blockEditorStore );
|
|
54
54
|
|
|
55
55
|
function onKeyDown( event ) {
|
|
56
|
+
if ( event.defaultPrevented ) return;
|
|
57
|
+
|
|
56
58
|
if ( isMatch( 'core/block-editor/move-up', event ) ) {
|
|
57
59
|
const clientIds = getSelectedBlockClientIds();
|
|
58
60
|
if ( clientIds.length ) {
|
|
@@ -93,12 +95,13 @@ export default function BlockTools( {
|
|
|
93
95
|
}
|
|
94
96
|
} else if ( isMatch( 'core/block-editor/unselect', event ) ) {
|
|
95
97
|
const clientIds = getSelectedBlockClientIds();
|
|
96
|
-
if ( clientIds.length
|
|
98
|
+
if ( clientIds.length ) {
|
|
97
99
|
event.preventDefault();
|
|
98
100
|
clearSelectedBlock();
|
|
99
101
|
event.target.ownerDocument.defaultView
|
|
100
102
|
.getSelection()
|
|
101
103
|
.removeAllRanges();
|
|
104
|
+
__unstableContentRef?.current.focus();
|
|
102
105
|
}
|
|
103
106
|
}
|
|
104
107
|
}
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
import {
|
|
5
5
|
Dimensions,
|
|
6
6
|
FlatList,
|
|
7
|
+
SectionList,
|
|
7
8
|
StyleSheet,
|
|
9
|
+
Text,
|
|
8
10
|
TouchableWithoutFeedback,
|
|
9
11
|
View,
|
|
10
12
|
} from 'react-native';
|
|
@@ -13,7 +15,11 @@ import {
|
|
|
13
15
|
* WordPress dependencies
|
|
14
16
|
*/
|
|
15
17
|
import { useState, useEffect } from '@wordpress/element';
|
|
16
|
-
import { BottomSheet, InserterButton } from '@wordpress/components';
|
|
18
|
+
import { BottomSheet, Gradient, InserterButton } from '@wordpress/components';
|
|
19
|
+
import {
|
|
20
|
+
usePreferredColorScheme,
|
|
21
|
+
usePreferredColorSchemeStyle,
|
|
22
|
+
} from '@wordpress/compose';
|
|
17
23
|
|
|
18
24
|
/**
|
|
19
25
|
* Internal dependencies
|
|
@@ -24,7 +30,7 @@ const MIN_COL_NUM = 3;
|
|
|
24
30
|
|
|
25
31
|
export default function BlockTypesList( {
|
|
26
32
|
name,
|
|
27
|
-
|
|
33
|
+
sections,
|
|
28
34
|
onSelect,
|
|
29
35
|
listProps,
|
|
30
36
|
initialNumToRender = 3,
|
|
@@ -80,33 +86,79 @@ export default function BlockTypesList( {
|
|
|
80
86
|
listProps.contentContainerStyle
|
|
81
87
|
);
|
|
82
88
|
|
|
89
|
+
const renderSection = ( { item } ) => {
|
|
90
|
+
return (
|
|
91
|
+
<TouchableWithoutFeedback accessible={ false }>
|
|
92
|
+
<FlatList
|
|
93
|
+
data={ item.list }
|
|
94
|
+
key={ `InserterUI-${ name }-${ numberOfColumns }` } // Re-render when numberOfColumns changes.
|
|
95
|
+
numColumns={ numberOfColumns }
|
|
96
|
+
ItemSeparatorComponent={ () => (
|
|
97
|
+
<TouchableWithoutFeedback accessible={ false }>
|
|
98
|
+
<View
|
|
99
|
+
style={
|
|
100
|
+
styles[ 'block-types-list__row-separator' ]
|
|
101
|
+
}
|
|
102
|
+
/>
|
|
103
|
+
</TouchableWithoutFeedback>
|
|
104
|
+
) }
|
|
105
|
+
scrollEnabled={ false }
|
|
106
|
+
renderItem={ renderListItem }
|
|
107
|
+
/>
|
|
108
|
+
</TouchableWithoutFeedback>
|
|
109
|
+
);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const renderListItem = ( { item } ) => {
|
|
113
|
+
return (
|
|
114
|
+
<InserterButton
|
|
115
|
+
item={ item }
|
|
116
|
+
itemWidth={ itemWidth }
|
|
117
|
+
maxWidth={ maxWidth }
|
|
118
|
+
onSelect={ onSelect }
|
|
119
|
+
/>
|
|
120
|
+
);
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const colorScheme = usePreferredColorScheme();
|
|
124
|
+
const sectionHeaderGradientValue =
|
|
125
|
+
colorScheme === 'light'
|
|
126
|
+
? 'linear-gradient(#fff 70%, rgba(255, 255, 255, 0))'
|
|
127
|
+
: 'linear-gradient(#2e2e2e 70%, rgba(46, 46, 46, 0))';
|
|
128
|
+
const sectionHeaderTitleStyles = usePreferredColorSchemeStyle(
|
|
129
|
+
styles[ 'block-types-list__section-header-title' ],
|
|
130
|
+
styles[ 'block-types-list__section-header-title--dark' ]
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
const renderSectionHeader = ( { section: { metadata } } ) => {
|
|
134
|
+
if ( ! metadata?.icon || ! metadata?.title ) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<TouchableWithoutFeedback accessible={ false }>
|
|
140
|
+
<Gradient
|
|
141
|
+
gradientValue={ sectionHeaderGradientValue }
|
|
142
|
+
style={ styles[ 'block-types-list__section-header' ] }
|
|
143
|
+
>
|
|
144
|
+
{ metadata?.icon }
|
|
145
|
+
<Text style={ sectionHeaderTitleStyles }>
|
|
146
|
+
{ metadata?.title }
|
|
147
|
+
</Text>
|
|
148
|
+
</Gradient>
|
|
149
|
+
</TouchableWithoutFeedback>
|
|
150
|
+
);
|
|
151
|
+
};
|
|
152
|
+
|
|
83
153
|
return (
|
|
84
|
-
<
|
|
154
|
+
<SectionList
|
|
85
155
|
onLayout={ onLayout }
|
|
86
|
-
key={ `InserterUI-${ name }-${ numberOfColumns }` } // Re-render when numberOfColumns changes.
|
|
87
156
|
testID={ `InserterUI-${ name }` }
|
|
88
157
|
keyboardShouldPersistTaps="always"
|
|
89
|
-
|
|
90
|
-
data={ items }
|
|
158
|
+
sections={ sections }
|
|
91
159
|
initialNumToRender={ initialNumToRender }
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
<View
|
|
95
|
-
style={ styles[ 'block-types-list__row-separator' ] }
|
|
96
|
-
/>
|
|
97
|
-
</TouchableWithoutFeedback>
|
|
98
|
-
) }
|
|
99
|
-
keyExtractor={ ( item ) => item.id }
|
|
100
|
-
renderItem={ ( { item } ) => (
|
|
101
|
-
<InserterButton
|
|
102
|
-
{ ...{
|
|
103
|
-
item,
|
|
104
|
-
itemWidth,
|
|
105
|
-
maxWidth,
|
|
106
|
-
onSelect,
|
|
107
|
-
} }
|
|
108
|
-
/>
|
|
109
|
-
) }
|
|
160
|
+
renderItem={ renderSection }
|
|
161
|
+
renderSectionHeader={ renderSectionHeader }
|
|
110
162
|
{ ...listProps }
|
|
111
163
|
contentContainerStyle={ {
|
|
112
164
|
...contentContainerStyle,
|
|
@@ -5,3 +5,21 @@
|
|
|
5
5
|
.block-types-list__column {
|
|
6
6
|
padding: $grid-unit-20;
|
|
7
7
|
}
|
|
8
|
+
|
|
9
|
+
.block-types-list__section-header {
|
|
10
|
+
align-items: center;
|
|
11
|
+
flex-direction: row;
|
|
12
|
+
justify-content: center;
|
|
13
|
+
padding-bottom: 16;
|
|
14
|
+
padding-top: 32;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.block-types-list__section-header-title {
|
|
18
|
+
color: $black;
|
|
19
|
+
font-size: 16px;
|
|
20
|
+
margin-left: 10px;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.block-types-list__section-header-title--dark {
|
|
24
|
+
color: $white;
|
|
25
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
|
-
exports[`createCustomColorsHOC provides the
|
|
3
|
+
exports[`createCustomColorsHOC provides the wrapped component with color values and setter functions as props 1`] = `
|
|
4
4
|
<Component
|
|
5
5
|
attributes={
|
|
6
6
|
Object {
|
|
@@ -9,7 +9,7 @@ import { shallow, mount } from 'enzyme';
|
|
|
9
9
|
import { createCustomColorsHOC } from '../with-colors';
|
|
10
10
|
|
|
11
11
|
describe( 'createCustomColorsHOC', () => {
|
|
12
|
-
it( 'provides the
|
|
12
|
+
it( 'provides the wrapped component with color values and setter functions as props', () => {
|
|
13
13
|
const withCustomColors = createCustomColorsHOC( [
|
|
14
14
|
{ name: 'Red', slug: 'red', color: 'ff0000' },
|
|
15
15
|
] );
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
ColorIndicator,
|
|
12
12
|
Dropdown,
|
|
13
13
|
FlexItem,
|
|
14
|
+
__experimentalDropdownContentWrapper as DropdownContentWrapper,
|
|
14
15
|
__experimentalHStack as HStack,
|
|
15
16
|
__experimentalToolsPanelItem as ToolsPanelItem,
|
|
16
17
|
} from '@wordpress/components';
|
|
@@ -155,10 +156,15 @@ export default function ColorGradientSettingsDropdown( {
|
|
|
155
156
|
<Dropdown
|
|
156
157
|
popoverProps={ popoverProps }
|
|
157
158
|
className="block-editor-tools-panel-color-gradient-settings__dropdown"
|
|
158
|
-
contentClassName="block-editor-panel-color-gradient-settings__dropdown-content"
|
|
159
159
|
renderToggle={ renderToggle( toggleSettings ) }
|
|
160
160
|
renderContent={ () => (
|
|
161
|
-
<
|
|
161
|
+
<DropdownContentWrapper paddingSize="medium">
|
|
162
|
+
<div className="block-editor-panel-color-gradient-settings__dropdown-content">
|
|
163
|
+
<ColorGradientControl
|
|
164
|
+
{ ...controlProps }
|
|
165
|
+
/>
|
|
166
|
+
</div>
|
|
167
|
+
</DropdownContentWrapper>
|
|
162
168
|
) }
|
|
163
169
|
/>
|
|
164
170
|
</WithToolsPanelItem>
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
// Must equal $color-palette-circle-size from:
|
|
2
|
+
// @wordpress/components/src/circular-option-picker/style.scss
|
|
3
|
+
$swatch-size: 28px;
|
|
4
|
+
$swatch-gap: 12px;
|
|
5
|
+
|
|
1
6
|
.block-editor-color-gradient-control {
|
|
2
7
|
.block-editor-color-gradient-control__color-indicator {
|
|
3
8
|
margin-bottom: $grid-unit-15;
|
|
@@ -18,11 +23,6 @@
|
|
|
18
23
|
}
|
|
19
24
|
|
|
20
25
|
.block-editor-panel-color-gradient-settings {
|
|
21
|
-
|
|
22
|
-
// Must equal $color-palette-circle-size from:
|
|
23
|
-
// @wordpress/components/src/circular-option-picker/style.scss
|
|
24
|
-
$swatch-size: 28px;
|
|
25
|
-
|
|
26
26
|
@media screen and (min-width: $break-medium) {
|
|
27
27
|
.components-circular-option-picker__swatches {
|
|
28
28
|
display: grid;
|
|
@@ -40,11 +40,10 @@
|
|
|
40
40
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
.block-editor-panel-color-gradient-settings__dropdown-content
|
|
44
|
-
width: $
|
|
43
|
+
.block-editor-panel-color-gradient-settings__dropdown-content {
|
|
44
|
+
width: ( $swatch-size * 6 ) + ( $swatch-gap * 5 ); // Ensure the popover perfectly wraps the swatches.
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
48
47
|
.block-editor-panel-color-gradient-settings__color-indicator {
|
|
49
48
|
// Show a diagonal line (crossed out) for empty swatches.
|
|
50
49
|
background: linear-gradient(-45deg, transparent 48%, $gray-300 48%, $gray-300 52%, transparent 52%);
|
|
@@ -23,6 +23,7 @@ export default function ImageCropper( {
|
|
|
23
23
|
clientWidth,
|
|
24
24
|
naturalHeight,
|
|
25
25
|
naturalWidth,
|
|
26
|
+
borderProps,
|
|
26
27
|
} ) {
|
|
27
28
|
const {
|
|
28
29
|
isInProgress,
|
|
@@ -44,10 +45,15 @@ export default function ImageCropper( {
|
|
|
44
45
|
|
|
45
46
|
return (
|
|
46
47
|
<div
|
|
47
|
-
className={ classnames(
|
|
48
|
-
'
|
|
49
|
-
|
|
48
|
+
className={ classnames(
|
|
49
|
+
'wp-block-image__crop-area',
|
|
50
|
+
borderProps?.className,
|
|
51
|
+
{
|
|
52
|
+
'is-applying': isInProgress,
|
|
53
|
+
}
|
|
54
|
+
) }
|
|
50
55
|
style={ {
|
|
56
|
+
...borderProps?.style,
|
|
51
57
|
width: width || clientWidth,
|
|
52
58
|
height: editedHeight,
|
|
53
59
|
} }
|
|
@@ -1,36 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { useMemo } from '@wordpress/element';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Internal dependencies
|
|
8
8
|
*/
|
|
9
9
|
import BlockTypesList from '../block-types-list';
|
|
10
10
|
import useClipboardBlock from './hooks/use-clipboard-block';
|
|
11
|
-
import { store as blockEditorStore } from '../../store';
|
|
12
11
|
import useBlockTypeImpressions from './hooks/use-block-type-impressions';
|
|
13
|
-
import { filterInserterItems } from './utils';
|
|
12
|
+
import { createInserterSection, filterInserterItems } from './utils';
|
|
13
|
+
import useBlockTypesState from './hooks/use-block-types-state';
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
const clipboardBlock = useClipboardBlock( rootClientId );
|
|
17
|
-
|
|
18
|
-
const { blockTypes } = useSelect(
|
|
19
|
-
( select ) => {
|
|
20
|
-
const { getInserterItems } = select( blockEditorStore );
|
|
21
|
-
const blockItems = filterInserterItems(
|
|
22
|
-
getInserterItems( rootClientId )
|
|
23
|
-
);
|
|
15
|
+
const getBlockNamespace = ( item ) => item.name.split( '/' )[ 0 ];
|
|
24
16
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
};
|
|
30
|
-
},
|
|
31
|
-
[ rootClientId ]
|
|
17
|
+
function BlockTypesTab( { onSelect, rootClientId, listProps } ) {
|
|
18
|
+
const [ rawBlockTypes, , collections ] = useBlockTypesState(
|
|
19
|
+
rootClientId,
|
|
20
|
+
onSelect
|
|
32
21
|
);
|
|
33
|
-
|
|
22
|
+
const clipboardBlock = useClipboardBlock( rootClientId );
|
|
23
|
+
const filteredBlockTypes = filterInserterItems( rawBlockTypes );
|
|
24
|
+
const blockTypes = clipboardBlock
|
|
25
|
+
? [ clipboardBlock, ...filteredBlockTypes ]
|
|
26
|
+
: filteredBlockTypes;
|
|
34
27
|
const { items, trackBlockTypeSelected } =
|
|
35
28
|
useBlockTypeImpressions( blockTypes );
|
|
36
29
|
|
|
@@ -39,10 +32,38 @@ function BlockTypesTab( { onSelect, rootClientId, listProps } ) {
|
|
|
39
32
|
onSelect( ...args );
|
|
40
33
|
};
|
|
41
34
|
|
|
35
|
+
const collectionSections = useMemo( () => {
|
|
36
|
+
const result = [];
|
|
37
|
+
Object.keys( collections ).forEach( ( namespace ) => {
|
|
38
|
+
const data = items.filter(
|
|
39
|
+
( item ) => getBlockNamespace( item ) === namespace
|
|
40
|
+
);
|
|
41
|
+
if ( data.length > 0 ) {
|
|
42
|
+
result.push(
|
|
43
|
+
createInserterSection( {
|
|
44
|
+
key: `collection-${ namespace }`,
|
|
45
|
+
metadata: {
|
|
46
|
+
icon: collections[ namespace ].icon,
|
|
47
|
+
title: collections[ namespace ].title,
|
|
48
|
+
},
|
|
49
|
+
items: data,
|
|
50
|
+
} )
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
} );
|
|
54
|
+
|
|
55
|
+
return result;
|
|
56
|
+
}, [ items, collections ] );
|
|
57
|
+
|
|
58
|
+
const sections = [
|
|
59
|
+
createInserterSection( { key: 'default', items } ),
|
|
60
|
+
...collectionSections,
|
|
61
|
+
];
|
|
62
|
+
|
|
42
63
|
return (
|
|
43
64
|
<BlockTypesList
|
|
44
65
|
name="Blocks"
|
|
45
|
-
|
|
66
|
+
sections={ sections }
|
|
46
67
|
onSelect={ handleSelect }
|
|
47
68
|
listProps={ listProps }
|
|
48
69
|
/>
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
isReusableBlock,
|
|
6
6
|
createBlock,
|
|
7
7
|
getBlockFromExample,
|
|
8
|
-
getBlockType,
|
|
9
8
|
} from '@wordpress/blocks';
|
|
10
9
|
import { __ } from '@wordpress/i18n';
|
|
11
10
|
|
|
@@ -16,31 +15,24 @@ import BlockCard from '../block-card';
|
|
|
16
15
|
import BlockPreview from '../block-preview';
|
|
17
16
|
|
|
18
17
|
function InserterPreviewPanel( { item } ) {
|
|
19
|
-
const { name, title, icon, description, initialAttributes } = item;
|
|
20
|
-
const hoveredItemBlockType = getBlockType( name );
|
|
18
|
+
const { name, title, icon, description, initialAttributes, example } = item;
|
|
21
19
|
const isReusable = isReusableBlock( item );
|
|
22
20
|
return (
|
|
23
21
|
<div className="block-editor-inserter__preview-container">
|
|
24
22
|
<div className="block-editor-inserter__preview">
|
|
25
|
-
{ isReusable ||
|
|
23
|
+
{ isReusable || example ? (
|
|
26
24
|
<div className="block-editor-inserter__preview-content">
|
|
27
25
|
<BlockPreview
|
|
28
26
|
__experimentalPadding={ 16 }
|
|
29
|
-
viewportWidth={
|
|
30
|
-
hoveredItemBlockType.example?.viewportWidth ??
|
|
31
|
-
500
|
|
32
|
-
}
|
|
27
|
+
viewportWidth={ example?.viewportWidth ?? 500 }
|
|
33
28
|
blocks={
|
|
34
|
-
|
|
29
|
+
example
|
|
35
30
|
? getBlockFromExample( item.name, {
|
|
36
31
|
attributes: {
|
|
37
|
-
...
|
|
38
|
-
.attributes,
|
|
32
|
+
...example.attributes,
|
|
39
33
|
...initialAttributes,
|
|
40
34
|
},
|
|
41
|
-
innerBlocks:
|
|
42
|
-
hoveredItemBlockType.example
|
|
43
|
-
.innerBlocks,
|
|
35
|
+
innerBlocks: example.innerBlocks,
|
|
44
36
|
} )
|
|
45
37
|
: createBlock( name, initialAttributes )
|
|
46
38
|
}
|
|
@@ -8,7 +8,7 @@ import { useSelect } from '@wordpress/data';
|
|
|
8
8
|
*/
|
|
9
9
|
import BlockTypesList from '../block-types-list';
|
|
10
10
|
import { store as blockEditorStore } from '../../store';
|
|
11
|
-
import { filterInserterItems } from './utils';
|
|
11
|
+
import { createInserterSection, filterInserterItems } from './utils';
|
|
12
12
|
|
|
13
13
|
function ReusableBlocksTab( { onSelect, rootClientId, listProps } ) {
|
|
14
14
|
const { items } = useSelect(
|
|
@@ -23,10 +23,12 @@ function ReusableBlocksTab( { onSelect, rootClientId, listProps } ) {
|
|
|
23
23
|
[ rootClientId ]
|
|
24
24
|
);
|
|
25
25
|
|
|
26
|
+
const sections = [ createInserterSection( { key: 'reuseable', items } ) ];
|
|
27
|
+
|
|
26
28
|
return (
|
|
27
29
|
<BlockTypesList
|
|
28
30
|
name="ReusableBlocks"
|
|
29
|
-
|
|
31
|
+
sections={ sections }
|
|
30
32
|
onSelect={ onSelect }
|
|
31
33
|
listProps={ listProps }
|
|
32
34
|
/>
|
|
@@ -11,7 +11,7 @@ import BlockTypesList from '../block-types-list';
|
|
|
11
11
|
import InserterNoResults from './no-results';
|
|
12
12
|
import { store as blockEditorStore } from '../../store';
|
|
13
13
|
import useBlockTypeImpressions from './hooks/use-block-type-impressions';
|
|
14
|
-
import { filterInserterItems } from './utils';
|
|
14
|
+
import { createInserterSection, filterInserterItems } from './utils';
|
|
15
15
|
|
|
16
16
|
function InserterSearchResults( {
|
|
17
17
|
filterValue,
|
|
@@ -51,7 +51,9 @@ function InserterSearchResults( {
|
|
|
51
51
|
<BlockTypesList
|
|
52
52
|
name="Blocks"
|
|
53
53
|
initialNumToRender={ isFullScreen ? 10 : 3 }
|
|
54
|
-
{
|
|
54
|
+
sections={ [ createInserterSection( { key: 'search', items } ) ] }
|
|
55
|
+
onSelect={ handleSelect }
|
|
56
|
+
listProps={ listProps }
|
|
55
57
|
/>
|
|
56
58
|
);
|
|
57
59
|
}
|
|
@@ -18,6 +18,8 @@ jest.mock( '../hooks/use-clipboard-block' );
|
|
|
18
18
|
jest.mock( '@wordpress/data/src/components/use-select' );
|
|
19
19
|
|
|
20
20
|
const selectMock = {
|
|
21
|
+
getCategories: jest.fn().mockReturnValue( [] ),
|
|
22
|
+
getCollections: jest.fn().mockReturnValue( [] ),
|
|
21
23
|
getInserterItems: jest.fn().mockReturnValue( [] ),
|
|
22
24
|
canInsertBlockType: jest.fn(),
|
|
23
25
|
getBlockType: jest.fn(),
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { createInserterSection } from '../utils';
|
|
5
|
+
|
|
6
|
+
describe( 'createInserterSection', () => {
|
|
7
|
+
it( 'returns the expected object shape', () => {
|
|
8
|
+
const key = 'mock-1';
|
|
9
|
+
const items = [ 1, 2, 3 ];
|
|
10
|
+
const metadata = { icon: 'icon-mock', title: 'Title Mock' };
|
|
11
|
+
|
|
12
|
+
expect( createInserterSection( { key, metadata, items } ) ).toEqual(
|
|
13
|
+
expect.objectContaining( {
|
|
14
|
+
metadata,
|
|
15
|
+
data: [ { key, list: items } ],
|
|
16
|
+
} )
|
|
17
|
+
);
|
|
18
|
+
} );
|
|
19
|
+
|
|
20
|
+
it( 'return always includes metadata', () => {
|
|
21
|
+
const key = 'mock-1';
|
|
22
|
+
const items = [ 1, 2, 3 ];
|
|
23
|
+
|
|
24
|
+
expect( createInserterSection( { key, items } ) ).toEqual(
|
|
25
|
+
expect.objectContaining( {
|
|
26
|
+
metadata: {},
|
|
27
|
+
data: [ { key, list: items } ],
|
|
28
|
+
} )
|
|
29
|
+
);
|
|
30
|
+
} );
|
|
31
|
+
|
|
32
|
+
it( 'requires a unique key', () => {
|
|
33
|
+
expect( () => {
|
|
34
|
+
createInserterSection( { items: [ 1, 2, 3 ] } );
|
|
35
|
+
} ).toThrow( 'A unique key for the section must be provided.' );
|
|
36
|
+
} );
|
|
37
|
+
} );
|
|
@@ -33,3 +33,14 @@ export function filterInserterItems(
|
|
|
33
33
|
blockAllowed( block, { onlyReusable, allowReusable } )
|
|
34
34
|
);
|
|
35
35
|
}
|
|
36
|
+
|
|
37
|
+
export function createInserterSection( { key, metadata = {}, items } ) {
|
|
38
|
+
if ( ! key ) {
|
|
39
|
+
throw new Error( 'A unique key for the section must be provided.' );
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
metadata,
|
|
44
|
+
data: [ { key, list: items } ],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
createBlock,
|
|
12
12
|
createBlocksFromInnerBlocksTemplate,
|
|
13
13
|
} from '@wordpress/blocks';
|
|
14
|
+
import { __experimentalTruncate as Truncate } from '@wordpress/components';
|
|
14
15
|
import { ENTER } from '@wordpress/keycodes';
|
|
15
16
|
|
|
16
17
|
/**
|
|
@@ -135,7 +136,9 @@ function InserterListItem( {
|
|
|
135
136
|
<BlockIcon icon={ item.icon } showColors />
|
|
136
137
|
</span>
|
|
137
138
|
<span className="block-editor-block-types-list__item-title">
|
|
138
|
-
{
|
|
139
|
+
<Truncate numberOfLines={ 3 }>
|
|
140
|
+
{ item.title }
|
|
141
|
+
</Truncate>
|
|
139
142
|
</span>
|
|
140
143
|
</InserterListboxItem>
|
|
141
144
|
</div>
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* External dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { compact } from 'lodash';
|
|
5
|
-
|
|
6
1
|
/**
|
|
7
2
|
* WordPress dependencies
|
|
8
3
|
*/
|
|
@@ -95,7 +90,7 @@ function ListViewBranch( props ) {
|
|
|
95
90
|
|
|
96
91
|
const { expandedState, draggedClientIds } = useListViewContext();
|
|
97
92
|
|
|
98
|
-
const filteredBlocks =
|
|
93
|
+
const filteredBlocks = blocks.filter( Boolean );
|
|
99
94
|
const blockCount = filteredBlocks.length;
|
|
100
95
|
let nextPosition = listPosition;
|
|
101
96
|
|
|
@@ -115,9 +115,13 @@ export function useMouseMoveTypingReset() {
|
|
|
115
115
|
* field, presses ESC or TAB, or moves the mouse in the document.
|
|
116
116
|
*/
|
|
117
117
|
export function useTypingObserver() {
|
|
118
|
-
const isTyping = useSelect( ( select ) =>
|
|
119
|
-
select( blockEditorStore )
|
|
120
|
-
|
|
118
|
+
const { isTyping, hasInlineToolbar } = useSelect( ( select ) => {
|
|
119
|
+
const { isTyping: _isTyping, getSettings } = select( blockEditorStore );
|
|
120
|
+
return {
|
|
121
|
+
isTyping: _isTyping(),
|
|
122
|
+
hasInlineToolbar: getSettings().hasInlineToolbar,
|
|
123
|
+
};
|
|
124
|
+
}, [] );
|
|
121
125
|
const { startTyping, stopTyping } = useDispatch( blockEditorStore );
|
|
122
126
|
|
|
123
127
|
const ref1 = useMouseMoveTypingReset();
|
|
@@ -125,6 +129,7 @@ export function useTypingObserver() {
|
|
|
125
129
|
( node ) => {
|
|
126
130
|
const { ownerDocument } = node;
|
|
127
131
|
const { defaultView } = ownerDocument;
|
|
132
|
+
const selection = defaultView.getSelection();
|
|
128
133
|
|
|
129
134
|
// Listeners to stop typing should only be added when typing.
|
|
130
135
|
// Listeners to start typing should only be added when not typing.
|
|
@@ -170,22 +175,20 @@ export function useTypingObserver() {
|
|
|
170
175
|
* uncollapsed (shift) selection.
|
|
171
176
|
*/
|
|
172
177
|
function stopTypingOnSelectionUncollapse() {
|
|
173
|
-
|
|
174
|
-
const isCollapsed =
|
|
175
|
-
selection.rangeCount > 0 &&
|
|
176
|
-
selection.getRangeAt( 0 ).collapsed;
|
|
177
|
-
|
|
178
|
-
if ( ! isCollapsed ) {
|
|
178
|
+
if ( ! selection.isCollapsed ) {
|
|
179
179
|
stopTyping();
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
node.addEventListener( 'focus', stopTypingOnNonTextField );
|
|
184
184
|
node.addEventListener( 'keydown', stopTypingOnEscapeKey );
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
185
|
+
|
|
186
|
+
if ( ! hasInlineToolbar ) {
|
|
187
|
+
ownerDocument.addEventListener(
|
|
188
|
+
'selectionchange',
|
|
189
|
+
stopTypingOnSelectionUncollapse
|
|
190
|
+
);
|
|
191
|
+
}
|
|
189
192
|
|
|
190
193
|
return () => {
|
|
191
194
|
defaultView.clearTimeout( timerId );
|
|
@@ -242,7 +245,7 @@ export function useTypingObserver() {
|
|
|
242
245
|
node.removeEventListener( 'keydown', startTypingInTextField );
|
|
243
246
|
};
|
|
244
247
|
},
|
|
245
|
-
[ isTyping, startTyping, stopTyping ]
|
|
248
|
+
[ isTyping, hasInlineToolbar, startTyping, stopTyping ]
|
|
246
249
|
);
|
|
247
250
|
|
|
248
251
|
return useMergeRefs( [ ref1, ref2 ] );
|