@wordpress/block-editor 15.18.0 → 15.19.1-next.v.202605131006.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 +6 -0
- package/build/components/block-controls/fill.cjs.map +2 -2
- package/build/components/block-inspector/edit-contents.cjs +7 -1
- package/build/components/block-inspector/edit-contents.cjs.map +2 -2
- package/build/components/block-toolbar/edit-section-button.cjs +7 -1
- package/build/components/block-toolbar/edit-section-button.cjs.map +2 -2
- package/build/components/block-variation-transforms/index.cjs +2 -2
- package/build/components/block-variation-transforms/index.cjs.map +2 -2
- package/build/components/block-visibility/modal.cjs +0 -10
- package/build/components/block-visibility/modal.cjs.map +3 -3
- package/build/components/dimensions-tool/scale-tool.cjs +2 -2
- package/build/components/dimensions-tool/scale-tool.cjs.map +2 -2
- package/build/components/global-styles/state-control.cjs +111 -37
- package/build/components/global-styles/state-control.cjs.map +3 -3
- package/build/components/gradients/use-gradient.cjs +2 -2
- package/build/components/gradients/use-gradient.cjs.map +2 -2
- package/build/components/iframe/use-scale-canvas.cjs.map +2 -2
- package/build/components/inserter/index.cjs +41 -43
- package/build/components/inserter/index.cjs.map +2 -2
- package/build/components/inserter/menu.cjs +30 -2
- package/build/components/inserter/menu.cjs.map +3 -3
- package/build/components/inserter/tips.cjs +1 -1
- package/build/components/inserter/tips.cjs.map +2 -2
- package/build/components/rich-text/event-listeners/index.cjs.map +2 -2
- package/build/store/actions.cjs +2 -2
- package/build/store/actions.cjs.map +2 -2
- package/build/store/reducer.cjs +8 -30
- package/build/store/reducer.cjs.map +2 -2
- package/build/store/selectors.cjs.map +2 -2
- package/build-module/components/block-controls/fill.mjs.map +2 -2
- package/build-module/components/block-inspector/edit-contents.mjs +7 -1
- package/build-module/components/block-inspector/edit-contents.mjs.map +2 -2
- package/build-module/components/block-toolbar/edit-section-button.mjs +7 -1
- package/build-module/components/block-toolbar/edit-section-button.mjs.map +2 -2
- package/build-module/components/block-variation-transforms/index.mjs +2 -2
- package/build-module/components/block-variation-transforms/index.mjs.map +2 -2
- package/build-module/components/block-visibility/modal.mjs +0 -10
- package/build-module/components/block-visibility/modal.mjs.map +3 -3
- package/build-module/components/dimensions-tool/scale-tool.mjs +2 -2
- package/build-module/components/dimensions-tool/scale-tool.mjs.map +2 -2
- package/build-module/components/global-styles/state-control.mjs +119 -40
- package/build-module/components/global-styles/state-control.mjs.map +2 -2
- package/build-module/components/gradients/use-gradient.mjs +2 -2
- package/build-module/components/gradients/use-gradient.mjs.map +2 -2
- package/build-module/components/iframe/use-scale-canvas.mjs.map +2 -2
- package/build-module/components/inserter/index.mjs +41 -43
- package/build-module/components/inserter/index.mjs.map +2 -2
- package/build-module/components/inserter/menu.mjs +31 -2
- package/build-module/components/inserter/menu.mjs.map +2 -2
- package/build-module/components/inserter/tips.mjs +1 -1
- package/build-module/components/inserter/tips.mjs.map +2 -2
- package/build-module/components/rich-text/event-listeners/index.mjs.map +2 -2
- package/build-module/store/actions.mjs +2 -2
- package/build-module/store/actions.mjs.map +2 -2
- package/build-module/store/reducer.mjs +8 -30
- package/build-module/store/reducer.mjs.map +2 -2
- package/build-module/store/selectors.mjs.map +2 -2
- package/build-style/style-rtl.css +29 -3
- package/build-style/style.css +29 -3
- package/build-types/components/block-context/index.d.ts +9 -16
- package/build-types/components/block-context/index.d.ts.map +1 -1
- package/build-types/utils/dom.d.ts +7 -7
- package/build-types/utils/dom.d.ts.map +1 -1
- package/package.json +39 -39
- package/src/components/block-controls/fill.js +1 -0
- package/src/components/block-inspector/edit-contents.js +4 -2
- package/src/components/block-manager/style.scss +3 -2
- package/src/components/block-toolbar/edit-section-button.js +5 -1
- package/src/components/block-variation-transforms/index.js +2 -2
- package/src/components/block-visibility/modal.js +0 -1
- package/src/components/dimensions-tool/scale-tool.js +2 -2
- package/src/components/global-styles/state-control.js +152 -49
- package/src/components/global-styles/style.scss +9 -0
- package/src/components/gradients/use-gradient.js +3 -1
- package/src/components/iframe/use-scale-canvas.js +0 -4
- package/src/components/inner-blocks/README.md +5 -1
- package/src/components/inner-blocks/index.native.js +1 -1
- package/src/components/inserter/index.js +58 -69
- package/src/components/inserter/menu.js +32 -1
- package/src/components/inserter/style.scss +18 -3
- package/src/components/inserter/tips.js +1 -1
- package/src/components/rich-text/event-listeners/index.js +0 -1
- package/src/store/actions.js +12 -6
- package/src/store/reducer.js +11 -39
- package/src/store/selectors.js +6 -0
- package/src/store/test/reducer.js +39 -0
|
@@ -1,75 +1,178 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { __
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
5
|
import { check, chevronDown } from '@wordpress/icons';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
DropdownMenu,
|
|
8
|
+
MenuGroup,
|
|
9
|
+
MenuItem,
|
|
10
|
+
privateApis as componentsPrivateApis,
|
|
11
|
+
} from '@wordpress/components';
|
|
12
|
+
import { Stack } from '@wordpress/ui';
|
|
7
13
|
|
|
8
14
|
/**
|
|
9
|
-
*
|
|
10
|
-
|
|
15
|
+
* Internal dependencies
|
|
16
|
+
*/
|
|
17
|
+
import { unlock } from '../../lock-unlock';
|
|
18
|
+
|
|
19
|
+
const { Badge: WCBadge } = unlock( componentsPrivateApis );
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* State control for managing viewport and pseudo-state styles.
|
|
23
|
+
* Displays a dropdown menu with separate groups for each selector.
|
|
11
24
|
*
|
|
12
|
-
* @param {Object} props
|
|
13
|
-
* @param {Array} props.
|
|
14
|
-
* @param {
|
|
15
|
-
* @param {
|
|
25
|
+
* @param {Object} props Component props.
|
|
26
|
+
* @param {Array} props.viewportStates Array of available viewport states.
|
|
27
|
+
* @param {Array} props.pseudoStates Array of available pseudo states.
|
|
28
|
+
* @param {string} props.viewportValue Currently selected viewport value.
|
|
29
|
+
* @param {string} props.pseudoStateValue Currently selected pseudo state value.
|
|
30
|
+
* @param {Function} props.onChangeViewport Callback when viewport selection changes.
|
|
31
|
+
* @param {Function} props.onChangePseudoState Callback when pseudo state selection changes.
|
|
16
32
|
* @return {Element|null} State control component.
|
|
17
33
|
*/
|
|
18
34
|
export default function StateControl( {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
35
|
+
viewportStates = [],
|
|
36
|
+
pseudoStates = [],
|
|
37
|
+
viewportValue = 'default',
|
|
38
|
+
pseudoStateValue = 'default',
|
|
39
|
+
onChangeViewport,
|
|
40
|
+
onChangePseudoState,
|
|
22
41
|
} ) {
|
|
23
|
-
if ( !
|
|
42
|
+
if ( ! viewportStates.length && ! pseudoStates.length ) {
|
|
24
43
|
return null;
|
|
25
44
|
}
|
|
26
45
|
|
|
27
|
-
const
|
|
46
|
+
const viewportOptions = [
|
|
47
|
+
{ label: __( 'Default' ), value: 'default' },
|
|
48
|
+
...viewportStates.map( ( state ) => ( {
|
|
49
|
+
label: state.label,
|
|
50
|
+
value: state.value,
|
|
51
|
+
} ) ),
|
|
52
|
+
];
|
|
53
|
+
const pseudoStateOptions = [
|
|
28
54
|
{ label: __( 'Default' ), value: 'default' },
|
|
29
|
-
...
|
|
55
|
+
...pseudoStates.map( ( state ) => ( {
|
|
30
56
|
label: state.label,
|
|
31
57
|
value: state.value,
|
|
32
58
|
} ) ),
|
|
33
59
|
];
|
|
34
60
|
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
61
|
+
const hasViewportOptions = viewportStates.length > 0;
|
|
62
|
+
const hasPseudoStateOptions = pseudoStates.length > 0;
|
|
63
|
+
const triggerLabel = __( 'States' );
|
|
64
|
+
const activeStates = [];
|
|
65
|
+
|
|
66
|
+
if ( hasViewportOptions && viewportValue !== 'default' ) {
|
|
67
|
+
const selectedViewport = viewportOptions.find(
|
|
68
|
+
( option ) => option.value === viewportValue
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
if ( selectedViewport ) {
|
|
72
|
+
activeStates.push( {
|
|
73
|
+
key: `viewport-${ selectedViewport.value }`,
|
|
74
|
+
label: selectedViewport.label,
|
|
75
|
+
} );
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if ( hasPseudoStateOptions && pseudoStateValue !== 'default' ) {
|
|
80
|
+
const selectedPseudoState = pseudoStateOptions.find(
|
|
81
|
+
( option ) => option.value === pseudoStateValue
|
|
38
82
|
);
|
|
39
|
-
|
|
40
|
-
|
|
83
|
+
|
|
84
|
+
if ( selectedPseudoState ) {
|
|
85
|
+
activeStates.push( {
|
|
86
|
+
key: `pseudo-${ selectedPseudoState.value }`,
|
|
87
|
+
label: selectedPseudoState.label,
|
|
88
|
+
} );
|
|
89
|
+
}
|
|
90
|
+
}
|
|
41
91
|
|
|
42
92
|
return (
|
|
43
|
-
<
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
getCurrentStateLabel()
|
|
49
|
-
) }
|
|
50
|
-
text={ getCurrentStateLabel() }
|
|
51
|
-
toggleProps={ {
|
|
52
|
-
size: 'compact',
|
|
53
|
-
variant: 'tertiary',
|
|
54
|
-
iconPosition: 'right',
|
|
55
|
-
} }
|
|
93
|
+
<Stack
|
|
94
|
+
direction="column"
|
|
95
|
+
gap="sm"
|
|
96
|
+
align="flex-end"
|
|
97
|
+
className="block-editor-global-styles-state-control"
|
|
56
98
|
>
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
99
|
+
<DropdownMenu
|
|
100
|
+
icon={ chevronDown }
|
|
101
|
+
label={ triggerLabel }
|
|
102
|
+
popoverProps={ {
|
|
103
|
+
placement: 'right-start',
|
|
104
|
+
} }
|
|
105
|
+
text={ triggerLabel }
|
|
106
|
+
toggleProps={ {
|
|
107
|
+
size: 'compact',
|
|
108
|
+
variant: 'tertiary',
|
|
109
|
+
iconPosition: 'right',
|
|
110
|
+
} }
|
|
111
|
+
>
|
|
112
|
+
{ ( { onClose } ) => (
|
|
113
|
+
<>
|
|
114
|
+
{ hasViewportOptions && (
|
|
115
|
+
<MenuGroup label={ __( 'Viewport' ) }>
|
|
116
|
+
{ viewportOptions.map( ( option ) => (
|
|
117
|
+
<MenuItem
|
|
118
|
+
key={ `viewport-${ option.value }` }
|
|
119
|
+
onClick={ () => {
|
|
120
|
+
onChangeViewport?.( option.value );
|
|
121
|
+
if ( ! hasPseudoStateOptions ) {
|
|
122
|
+
onClose();
|
|
123
|
+
}
|
|
124
|
+
} }
|
|
125
|
+
icon={
|
|
126
|
+
viewportValue === option.value
|
|
127
|
+
? check
|
|
128
|
+
: null
|
|
129
|
+
}
|
|
130
|
+
>
|
|
131
|
+
{ option.label }
|
|
132
|
+
</MenuItem>
|
|
133
|
+
) ) }
|
|
134
|
+
</MenuGroup>
|
|
135
|
+
) }
|
|
136
|
+
{ hasPseudoStateOptions && (
|
|
137
|
+
<MenuGroup label={ __( 'Pseudo state' ) }>
|
|
138
|
+
{ pseudoStateOptions.map( ( option ) => (
|
|
139
|
+
<MenuItem
|
|
140
|
+
key={ `pseudo-${ option.value }` }
|
|
141
|
+
onClick={ () => {
|
|
142
|
+
onChangePseudoState?.(
|
|
143
|
+
option.value
|
|
144
|
+
);
|
|
145
|
+
if ( ! hasViewportOptions ) {
|
|
146
|
+
onClose();
|
|
147
|
+
}
|
|
148
|
+
} }
|
|
149
|
+
icon={
|
|
150
|
+
pseudoStateValue === option.value
|
|
151
|
+
? check
|
|
152
|
+
: null
|
|
153
|
+
}
|
|
154
|
+
>
|
|
155
|
+
{ option.label }
|
|
156
|
+
</MenuItem>
|
|
157
|
+
) ) }
|
|
158
|
+
</MenuGroup>
|
|
159
|
+
) }
|
|
160
|
+
</>
|
|
161
|
+
) }
|
|
162
|
+
</DropdownMenu>
|
|
163
|
+
<Stack
|
|
164
|
+
className="block-editor-global-styles-state-control__badges"
|
|
165
|
+
direction="row"
|
|
166
|
+
justify="flex-start"
|
|
167
|
+
gap="xs"
|
|
168
|
+
wrap="wrap"
|
|
169
|
+
>
|
|
170
|
+
{ activeStates.map( ( activeState ) => (
|
|
171
|
+
<WCBadge key={ activeState.key } intent="info">
|
|
172
|
+
{ activeState.label }
|
|
173
|
+
</WCBadge>
|
|
174
|
+
) ) }
|
|
175
|
+
</Stack>
|
|
176
|
+
</Stack>
|
|
74
177
|
);
|
|
75
178
|
}
|
|
@@ -23,6 +23,15 @@
|
|
|
23
23
|
text-align: right;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
.block-editor-global-styles-state-control {
|
|
27
|
+
// Ensure alignment with block heading.
|
|
28
|
+
margin-top: -$grid-unit-05;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.block-editor-global-styles-state-control__badges {
|
|
32
|
+
min-height: $grid-unit-30;
|
|
33
|
+
}
|
|
34
|
+
|
|
26
35
|
.block-editor-global-styles-filters-panel__dropdown,
|
|
27
36
|
.block-editor-global-styles__shadow-dropdown {
|
|
28
37
|
display: block;
|
|
@@ -54,7 +54,7 @@ export function getGradientSlugByValue( gradients, value ) {
|
|
|
54
54
|
return gradient && gradient.slug;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
function useGradient( {
|
|
58
58
|
gradientAttribute = 'gradient',
|
|
59
59
|
customGradientAttribute = 'customGradient',
|
|
60
60
|
} = {} ) {
|
|
@@ -120,3 +120,5 @@ export function __experimentalUseGradient( {
|
|
|
120
120
|
}
|
|
121
121
|
return { gradientClass, gradientValue, setGradient };
|
|
122
122
|
}
|
|
123
|
+
|
|
124
|
+
export { useGradient as __experimentalUseGradient };
|
|
@@ -286,10 +286,6 @@ export function useScaleCanvas( {
|
|
|
286
286
|
|
|
287
287
|
iframeDocument.documentElement.classList.remove( 'zoom-out-animation' );
|
|
288
288
|
|
|
289
|
-
// Set the final scroll position that was just animated to.
|
|
290
|
-
// Disable reason: Eslint isn't smart enough to know that this is a
|
|
291
|
-
// DOM element. https://github.com/facebook/react/issues/31483
|
|
292
|
-
// eslint-disable-next-line react-compiler/react-compiler
|
|
293
289
|
iframeDocument.documentElement.scrollTop =
|
|
294
290
|
transitionToRef.current.scrollTop;
|
|
295
291
|
|
|
@@ -205,4 +205,8 @@ const DEFAULT_BLOCK = { name: 'core/paragraph', attributes: { content: 'Lorem ip
|
|
|
205
205
|
### `directInsert`
|
|
206
206
|
|
|
207
207
|
- **Type:** `Boolean`
|
|
208
|
-
- **Default:**
|
|
208
|
+
- **Default:** `undefined`.
|
|
209
|
+
|
|
210
|
+
When `true`, the appender inserts `defaultBlock` directly and skips the inserter dropdown, **including any registered inserter variations** of that block type. Use this to opt out of the variation picker; otherwise leave unset.
|
|
211
|
+
|
|
212
|
+
Note: redundant when `allowedBlocks` resolves to a single block type with no variations, the appender already inserts directly.
|
|
@@ -35,7 +35,7 @@ import { MAX_NESTING_DEPTH } from './constants';
|
|
|
35
35
|
* returns. Optionally, you can also pass any other props through this hook, and
|
|
36
36
|
* they will be merged and returned.
|
|
37
37
|
*
|
|
38
|
-
* @see https://github.com/WordPress/gutenberg/blob/
|
|
38
|
+
* @see https://github.com/WordPress/gutenberg/blob/trunk/packages/block-editor/src/components/inner-blocks/README.md
|
|
39
39
|
*
|
|
40
40
|
* @param {Object} props Optional. Props to pass to the element. Must contain
|
|
41
41
|
* the ref if one is defined.
|
|
@@ -144,7 +144,6 @@ class Inserter extends Component {
|
|
|
144
144
|
clientId,
|
|
145
145
|
isAppender,
|
|
146
146
|
showInserterHelpPanel,
|
|
147
|
-
|
|
148
147
|
// This prop is experimental to give some time for the quick inserter to mature
|
|
149
148
|
// Feel free to make them stable after a few releases.
|
|
150
149
|
__experimentalIsQuick: isQuick,
|
|
@@ -194,13 +193,13 @@ class Inserter extends Component {
|
|
|
194
193
|
const {
|
|
195
194
|
position,
|
|
196
195
|
hasSingleBlockType,
|
|
197
|
-
|
|
196
|
+
blockToInsert,
|
|
198
197
|
insertOnlyAllowedBlock,
|
|
199
198
|
__experimentalIsQuick: isQuick,
|
|
200
199
|
onSelectOrClose,
|
|
201
200
|
} = this.props;
|
|
202
201
|
|
|
203
|
-
if ( hasSingleBlockType ||
|
|
202
|
+
if ( hasSingleBlockType || blockToInsert ) {
|
|
204
203
|
return this.renderToggle( { onToggle: insertOnlyAllowedBlock } );
|
|
205
204
|
}
|
|
206
205
|
|
|
@@ -230,26 +229,35 @@ export default compose( [
|
|
|
230
229
|
hasInserterItems,
|
|
231
230
|
getAllowedBlocks,
|
|
232
231
|
getDirectInsertBlock,
|
|
232
|
+
getBlockListSettings,
|
|
233
233
|
} = select( blockEditorStore );
|
|
234
|
-
|
|
235
234
|
const { getBlockVariations, getBlockType } = select( blocksStore );
|
|
236
235
|
|
|
237
236
|
rootClientId =
|
|
238
237
|
rootClientId || getBlockRootClientId( clientId ) || undefined;
|
|
239
238
|
|
|
240
239
|
const allowedBlocks = getAllowedBlocks( rootClientId );
|
|
241
|
-
|
|
242
240
|
const directInsertBlock =
|
|
243
241
|
shouldDirectInsert && getDirectInsertBlock( rootClientId );
|
|
242
|
+
const { defaultBlock } = getBlockListSettings( rootClientId ) ?? {};
|
|
244
243
|
|
|
245
244
|
const hasSingleBlockType =
|
|
246
245
|
allowedBlocks?.length === 1 &&
|
|
247
246
|
getBlockVariations( allowedBlocks[ 0 ].name, 'inserter' )
|
|
248
247
|
?.length === 0;
|
|
248
|
+
const allowedBlockType = hasSingleBlockType
|
|
249
|
+
? allowedBlocks[ 0 ]
|
|
250
|
+
: null;
|
|
249
251
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
252
|
+
// Single-block-type parents get adjacent-attribute copying
|
|
253
|
+
// without needing to set `directInsert: true`.
|
|
254
|
+
let blockToInsert = directInsertBlock || null;
|
|
255
|
+
if (
|
|
256
|
+
! blockToInsert &&
|
|
257
|
+
hasSingleBlockType &&
|
|
258
|
+
defaultBlock?.name === allowedBlockType.name
|
|
259
|
+
) {
|
|
260
|
+
blockToInsert = defaultBlock;
|
|
253
261
|
}
|
|
254
262
|
|
|
255
263
|
const defaultBlockType = directInsertBlock
|
|
@@ -265,7 +273,7 @@ export default compose( [
|
|
|
265
273
|
hasSingleBlockType,
|
|
266
274
|
blockTitle: allowedBlockType ? allowedBlockType.title : '',
|
|
267
275
|
allowedBlockType,
|
|
268
|
-
|
|
276
|
+
blockToInsert,
|
|
269
277
|
appenderLabel,
|
|
270
278
|
rootClientId,
|
|
271
279
|
};
|
|
@@ -280,70 +288,57 @@ export default compose( [
|
|
|
280
288
|
isAppender,
|
|
281
289
|
hasSingleBlockType,
|
|
282
290
|
allowedBlockType,
|
|
283
|
-
|
|
291
|
+
blockToInsert,
|
|
284
292
|
onSelectOrClose,
|
|
285
293
|
selectBlockOnInsert,
|
|
286
294
|
} = ownProps;
|
|
287
295
|
|
|
288
|
-
if ( ! hasSingleBlockType && !
|
|
296
|
+
if ( ! hasSingleBlockType && ! blockToInsert ) {
|
|
289
297
|
return;
|
|
290
298
|
}
|
|
291
299
|
|
|
292
|
-
|
|
293
|
-
const { getBlock, getPreviousBlockClientId } =
|
|
294
|
-
select( blockEditorStore );
|
|
300
|
+
const blockName = blockToInsert?.name ?? allowedBlockType.name;
|
|
295
301
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
( ! clientId && ! rootClientId )
|
|
299
|
-
) {
|
|
302
|
+
function getAdjacentBlockAttributes( attributesToCopy ) {
|
|
303
|
+
if ( ! attributesToCopy?.length ) {
|
|
300
304
|
return {};
|
|
301
305
|
}
|
|
302
306
|
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
//
|
|
307
|
-
//
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
if ( parentBlock?.innerBlocks?.length ) {
|
|
312
|
-
const lastInnerBlock =
|
|
313
|
-
parentBlock.innerBlocks[
|
|
314
|
-
parentBlock.innerBlocks.length - 1
|
|
315
|
-
];
|
|
316
|
-
|
|
317
|
-
if (
|
|
318
|
-
directInsertBlock &&
|
|
319
|
-
directInsertBlock?.name === lastInnerBlock.name
|
|
320
|
-
) {
|
|
321
|
-
adjacentAttributes = lastInnerBlock.attributes;
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
} else {
|
|
325
|
-
// Otherwise, attempt to get attributes from the
|
|
326
|
-
// previous block relative to the current clientId.
|
|
307
|
+
const { getBlock, getPreviousBlockClientId } =
|
|
308
|
+
select( blockEditorStore );
|
|
309
|
+
|
|
310
|
+
// Find the adjacent block of the same type whose attributes
|
|
311
|
+
// should be copied: previous sibling when inserting next to
|
|
312
|
+
// an existing block, otherwise the last child of the root.
|
|
313
|
+
let adjacentAttributes;
|
|
314
|
+
if ( clientId ) {
|
|
327
315
|
const currentBlock = getBlock( clientId );
|
|
328
316
|
const previousBlock = getBlock(
|
|
329
317
|
getPreviousBlockClientId( clientId )
|
|
330
318
|
);
|
|
331
|
-
|
|
332
319
|
if ( currentBlock?.name === previousBlock?.name ) {
|
|
333
|
-
adjacentAttributes =
|
|
334
|
-
|
|
320
|
+
adjacentAttributes = previousBlock?.attributes;
|
|
321
|
+
}
|
|
322
|
+
} else if ( rootClientId ) {
|
|
323
|
+
const lastInnerBlock =
|
|
324
|
+
getBlock( rootClientId )?.innerBlocks?.at( -1 );
|
|
325
|
+
if ( lastInnerBlock?.name === blockName ) {
|
|
326
|
+
adjacentAttributes = lastInnerBlock.attributes;
|
|
335
327
|
}
|
|
336
328
|
}
|
|
337
329
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
result[ attribute ] =
|
|
342
|
-
adjacentAttributes[ attribute ];
|
|
343
|
-
}
|
|
344
|
-
} );
|
|
330
|
+
if ( ! adjacentAttributes ) {
|
|
331
|
+
return {};
|
|
332
|
+
}
|
|
345
333
|
|
|
346
|
-
return
|
|
334
|
+
return Object.fromEntries(
|
|
335
|
+
attributesToCopy
|
|
336
|
+
.filter( ( attr ) => attr in adjacentAttributes )
|
|
337
|
+
.map( ( attr ) => [
|
|
338
|
+
attr,
|
|
339
|
+
adjacentAttributes[ attr ],
|
|
340
|
+
] )
|
|
341
|
+
);
|
|
347
342
|
}
|
|
348
343
|
|
|
349
344
|
function getInsertionIndex() {
|
|
@@ -375,33 +370,27 @@ export default compose( [
|
|
|
375
370
|
|
|
376
371
|
const { insertBlock } = dispatch( blockEditorStore );
|
|
377
372
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
// Attempt to augment the directInsertBlock with attributes from an adjacent block.
|
|
373
|
+
// Attempt to augment the inserted block with attributes from an adjacent block.
|
|
381
374
|
// This ensures styling from nearby blocks is preserved in the newly inserted block.
|
|
382
375
|
// See: https://github.com/WordPress/gutenberg/issues/37904
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
);
|
|
376
|
+
const newAttributes = getAdjacentBlockAttributes(
|
|
377
|
+
blockToInsert?.attributesToCopy
|
|
378
|
+
);
|
|
387
379
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
} else {
|
|
393
|
-
blockToInsert = createBlock( allowedBlockType.name );
|
|
394
|
-
}
|
|
380
|
+
const newBlock = createBlock( blockName, {
|
|
381
|
+
...( blockToInsert?.attributes || {} ),
|
|
382
|
+
...newAttributes,
|
|
383
|
+
} );
|
|
395
384
|
|
|
396
385
|
insertBlock(
|
|
397
|
-
|
|
386
|
+
newBlock,
|
|
398
387
|
getInsertionIndex(),
|
|
399
388
|
rootClientId,
|
|
400
389
|
selectBlockOnInsert
|
|
401
390
|
);
|
|
402
391
|
|
|
403
392
|
if ( onSelectOrClose ) {
|
|
404
|
-
onSelectOrClose(
|
|
393
|
+
onSelectOrClose( newBlock );
|
|
405
394
|
}
|
|
406
395
|
|
|
407
396
|
const message = sprintf(
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
forwardRef,
|
|
11
11
|
useState,
|
|
12
12
|
useCallback,
|
|
13
|
+
useEffect,
|
|
13
14
|
useMemo,
|
|
14
15
|
useRef,
|
|
15
16
|
useLayoutEffect,
|
|
@@ -169,6 +170,30 @@ function InserterMenu(
|
|
|
169
170
|
|
|
170
171
|
const showMediaPanel = selectedTab === 'media' && !! selectedMediaCategory;
|
|
171
172
|
|
|
173
|
+
const [ isScrolled, setIsScrolled ] = useState( false );
|
|
174
|
+
const blocksPanelRef = useRef( null );
|
|
175
|
+
const patternsPanelRef = useRef( null );
|
|
176
|
+
const mediaPanelRef = useRef( null );
|
|
177
|
+
useEffect( () => {
|
|
178
|
+
const handleScroll = ( event ) => {
|
|
179
|
+
setIsScrolled( event.currentTarget.scrollTop > 0 );
|
|
180
|
+
};
|
|
181
|
+
const panels = [
|
|
182
|
+
blocksPanelRef.current,
|
|
183
|
+
patternsPanelRef.current,
|
|
184
|
+
mediaPanelRef.current,
|
|
185
|
+
].filter( Boolean );
|
|
186
|
+
panels.forEach( ( panel ) =>
|
|
187
|
+
panel.addEventListener( 'scroll', handleScroll )
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
return () => {
|
|
191
|
+
panels.forEach( ( panel ) =>
|
|
192
|
+
panel.removeEventListener( 'scroll', handleScroll )
|
|
193
|
+
);
|
|
194
|
+
};
|
|
195
|
+
}, [] );
|
|
196
|
+
|
|
172
197
|
const inserterSearch = useMemo( () => {
|
|
173
198
|
if ( selectedTab === 'media' ) {
|
|
174
199
|
return null;
|
|
@@ -177,7 +202,9 @@ function InserterMenu(
|
|
|
177
202
|
return (
|
|
178
203
|
<>
|
|
179
204
|
<SearchControl
|
|
180
|
-
className=
|
|
205
|
+
className={ clsx( 'block-editor-inserter__search', {
|
|
206
|
+
'is-scrolled': isScrolled,
|
|
207
|
+
} ) }
|
|
181
208
|
onChange={ ( value ) => {
|
|
182
209
|
if ( hoveredItem ) {
|
|
183
210
|
setHoveredItem( null );
|
|
@@ -220,6 +247,7 @@ function InserterMenu(
|
|
|
220
247
|
rootClientId,
|
|
221
248
|
__experimentalInsertionIndex,
|
|
222
249
|
isAppender,
|
|
250
|
+
isScrolled,
|
|
223
251
|
] );
|
|
224
252
|
|
|
225
253
|
const blocksTab = useMemo( () => {
|
|
@@ -344,6 +372,7 @@ function InserterMenu(
|
|
|
344
372
|
{
|
|
345
373
|
name: 'blocks',
|
|
346
374
|
title: __( 'Blocks' ),
|
|
375
|
+
panelRef: blocksPanelRef,
|
|
347
376
|
panel: (
|
|
348
377
|
<>
|
|
349
378
|
{ inserterSearch }
|
|
@@ -356,6 +385,7 @@ function InserterMenu(
|
|
|
356
385
|
{
|
|
357
386
|
name: 'patterns',
|
|
358
387
|
title: __( 'Patterns' ),
|
|
388
|
+
panelRef: patternsPanelRef,
|
|
359
389
|
panel: (
|
|
360
390
|
<>
|
|
361
391
|
{ inserterSearch }
|
|
@@ -368,6 +398,7 @@ function InserterMenu(
|
|
|
368
398
|
{
|
|
369
399
|
name: 'media',
|
|
370
400
|
title: __( 'Media' ),
|
|
401
|
+
panelRef: mediaPanelRef,
|
|
371
402
|
panel: (
|
|
372
403
|
<>
|
|
373
404
|
{ inserterSearch }
|
|
@@ -119,7 +119,18 @@ $block-inserter-tabs-height: 44px;
|
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
.block-editor-inserter__search {
|
|
122
|
-
padding: $grid-unit-20
|
|
122
|
+
padding: $grid-unit-20;
|
|
123
|
+
position: sticky;
|
|
124
|
+
top: 0;
|
|
125
|
+
z-index: 2;
|
|
126
|
+
background-color: $white;
|
|
127
|
+
border-bottom: 1px solid transparent;
|
|
128
|
+
@media not ( prefers-reduced-motion ) {
|
|
129
|
+
transition: border-bottom-color 0.1s linear;
|
|
130
|
+
}
|
|
131
|
+
&.is-scrolled {
|
|
132
|
+
border-bottom-color: $gray-200;
|
|
133
|
+
}
|
|
123
134
|
}
|
|
124
135
|
|
|
125
136
|
.block-editor-inserter__no-tab-container {
|
|
@@ -138,7 +149,7 @@ $block-inserter-tabs-height: 44px;
|
|
|
138
149
|
|
|
139
150
|
display: inline-flex;
|
|
140
151
|
align-items: center;
|
|
141
|
-
padding:
|
|
152
|
+
padding: 0 $grid-unit-20;
|
|
142
153
|
}
|
|
143
154
|
|
|
144
155
|
.block-editor-inserter__panel-content {
|
|
@@ -224,12 +235,16 @@ $block-inserter-tabs-height: 44px;
|
|
|
224
235
|
.block-editor-inserter__media-tabs-container,
|
|
225
236
|
.block-editor-inserter__block-patterns-tabs-container {
|
|
226
237
|
flex-grow: 1;
|
|
227
|
-
padding: $grid-unit-20;
|
|
238
|
+
padding: 0 $grid-unit-20 $grid-unit-20;
|
|
228
239
|
display: flex;
|
|
229
240
|
flex-direction: column;
|
|
230
241
|
justify-content: space-between;
|
|
231
242
|
}
|
|
232
243
|
|
|
244
|
+
.block-editor-inserter__media-tabs-container {
|
|
245
|
+
padding-top: $grid-unit-20;
|
|
246
|
+
}
|
|
247
|
+
|
|
233
248
|
.block-editor-inserter__category-tablist {
|
|
234
249
|
margin-bottom: $grid-unit-10;
|
|
235
250
|
}
|
|
@@ -36,7 +36,6 @@ const allEventListeners = [
|
|
|
36
36
|
export function useEventListeners( props ) {
|
|
37
37
|
const propsRef = useRef( props );
|
|
38
38
|
useInsertionEffect( () => {
|
|
39
|
-
// eslint-disable-next-line react-compiler/react-compiler -- false positive, see https://github.com/facebook/react/issues/29196
|
|
40
39
|
propsRef.current = props;
|
|
41
40
|
} );
|
|
42
41
|
const refEffects = useMemo(
|