@wordpress/block-library 9.34.1-next.2f1c7c01b.0 → 9.35.1-next.16d95556a.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/block/edit.js +2 -2
- package/build/block/edit.js.map +2 -2
- package/build/block-keyboard-shortcuts/index.js +17 -7
- package/build/block-keyboard-shortcuts/index.js.map +2 -2
- package/build/cover/deprecated.js +15 -3
- package/build/cover/deprecated.js.map +2 -2
- package/build/cover/edit/inspector-controls.js +1 -1
- package/build/cover/edit/inspector-controls.js.map +2 -2
- package/build/cover/transforms.js +10 -2
- package/build/cover/transforms.js.map +2 -2
- package/build/embed/icons.js +2 -2
- package/build/embed/icons.js.map +2 -2
- package/build/embed/variations.js +3 -3
- package/build/embed/variations.js.map +2 -2
- package/build/heading/index.js +3 -1
- package/build/heading/index.js.map +3 -3
- package/build/heading/transforms.js +10 -3
- package/build/heading/transforms.js.map +2 -2
- package/build/heading/variations.js +55 -0
- package/build/heading/variations.js.map +7 -0
- package/build/html/edit.js +54 -44
- package/build/html/edit.js.map +3 -3
- package/build/html/modal.js +328 -0
- package/build/html/modal.js.map +7 -0
- package/build/html/utils.js +72 -0
- package/build/html/utils.js.map +7 -0
- package/build/navigation-link/edit.js +25 -10
- package/build/navigation-link/edit.js.map +2 -2
- package/build/navigation-link/link-ui/index.js +8 -3
- package/build/navigation-link/link-ui/index.js.map +2 -2
- package/build/navigation-link/shared/controls.js +42 -7
- package/build/navigation-link/shared/controls.js.map +2 -2
- package/build/navigation-link/shared/use-entity-binding.js +31 -2
- package/build/navigation-link/shared/use-entity-binding.js.map +3 -3
- package/build/paragraph/block.json +1 -3
- package/build/paragraph/deprecated.js +65 -12
- package/build/paragraph/deprecated.js.map +2 -2
- package/build/paragraph/edit.js +14 -25
- package/build/paragraph/edit.js.map +2 -2
- package/build/paragraph/index.js +3 -1
- package/build/paragraph/index.js.map +3 -3
- package/build/paragraph/save.js +3 -3
- package/build/paragraph/save.js.map +2 -2
- package/build/paragraph/transforms.js +7 -1
- package/build/paragraph/transforms.js.map +2 -2
- package/build/paragraph/variations.js +57 -0
- package/build/paragraph/variations.js.map +7 -0
- package/build/pullquote/block.json +3 -2
- package/build/pullquote/transforms.js +0 -31
- package/build/pullquote/transforms.js.map +2 -2
- package/build/quote/transforms.js +0 -20
- package/build/quote/transforms.js.map +2 -2
- package/build-module/block/edit.js +2 -2
- package/build-module/block/edit.js.map +2 -2
- package/build-module/block-keyboard-shortcuts/index.js +17 -7
- package/build-module/block-keyboard-shortcuts/index.js.map +2 -2
- package/build-module/cover/deprecated.js +15 -3
- package/build-module/cover/deprecated.js.map +2 -2
- package/build-module/cover/edit/inspector-controls.js +1 -1
- package/build-module/cover/edit/inspector-controls.js.map +2 -2
- package/build-module/cover/transforms.js +10 -2
- package/build-module/cover/transforms.js.map +2 -2
- package/build-module/embed/icons.js +2 -2
- package/build-module/embed/icons.js.map +2 -2
- package/build-module/embed/variations.js +3 -3
- package/build-module/embed/variations.js.map +2 -2
- package/build-module/heading/index.js +3 -1
- package/build-module/heading/index.js.map +2 -2
- package/build-module/heading/transforms.js +10 -3
- package/build-module/heading/transforms.js.map +2 -2
- package/build-module/heading/variations.js +34 -0
- package/build-module/heading/variations.js.map +7 -0
- package/build-module/html/edit.js +62 -51
- package/build-module/html/edit.js.map +2 -2
- package/build-module/html/modal.js +304 -0
- package/build-module/html/modal.js.map +7 -0
- package/build-module/html/utils.js +46 -0
- package/build-module/html/utils.js.map +7 -0
- package/build-module/navigation-link/edit.js +25 -10
- package/build-module/navigation-link/edit.js.map +2 -2
- package/build-module/navigation-link/link-ui/index.js +8 -3
- package/build-module/navigation-link/link-ui/index.js.map +2 -2
- package/build-module/navigation-link/shared/controls.js +42 -7
- package/build-module/navigation-link/shared/controls.js.map +2 -2
- package/build-module/navigation-link/shared/use-entity-binding.js +35 -3
- package/build-module/navigation-link/shared/use-entity-binding.js.map +2 -2
- package/build-module/paragraph/block.json +1 -3
- package/build-module/paragraph/deprecated.js +65 -12
- package/build-module/paragraph/deprecated.js.map +2 -2
- package/build-module/paragraph/edit.js +14 -26
- package/build-module/paragraph/edit.js.map +2 -2
- package/build-module/paragraph/index.js +3 -1
- package/build-module/paragraph/index.js.map +2 -2
- package/build-module/paragraph/save.js +3 -3
- package/build-module/paragraph/save.js.map +2 -2
- package/build-module/paragraph/transforms.js +7 -1
- package/build-module/paragraph/transforms.js.map +2 -2
- package/build-module/paragraph/variations.js +36 -0
- package/build-module/paragraph/variations.js.map +7 -0
- package/build-module/pullquote/block.json +3 -2
- package/build-module/pullquote/transforms.js +0 -31
- package/build-module/pullquote/transforms.js.map +2 -2
- package/build-module/quote/transforms.js +0 -20
- package/build-module/quote/transforms.js.map +2 -2
- package/build-style/accordion-heading/style-rtl.css +19 -3
- package/build-style/accordion-heading/style.css +19 -3
- package/build-style/accordion-panel/style-rtl.css +4 -1
- package/build-style/accordion-panel/style.css +4 -1
- package/build-style/common-rtl.css +3 -3
- package/build-style/common.css +3 -3
- package/build-style/editor-rtl.css +62 -21
- package/build-style/editor.css +62 -21
- package/build-style/embed/style-rtl.css +5 -0
- package/build-style/embed/style.css +5 -0
- package/build-style/html/editor-rtl.css +55 -21
- package/build-style/html/editor.css +55 -21
- package/build-style/navigation-link/editor-rtl.css +7 -0
- package/build-style/navigation-link/editor.css +7 -0
- package/build-style/style-rtl.css +31 -7
- package/build-style/style.css +31 -7
- package/package.json +37 -37
- package/src/accordion-heading/style.scss +40 -7
- package/src/accordion-panel/style.scss +6 -1
- package/src/block/edit.js +2 -2
- package/src/block-keyboard-shortcuts/index.js +23 -9
- package/src/common.scss +6 -5
- package/src/cover/deprecated.js +15 -3
- package/src/cover/edit/inspector-controls.js +1 -1
- package/src/cover/transforms.js +10 -2
- package/src/embed/icons.js +2 -4
- package/src/embed/style.scss +6 -0
- package/src/embed/variations.js +3 -3
- package/src/heading/index.js +2 -0
- package/src/heading/test/__snapshots__/transforms.native.js.snap +0 -6
- package/src/heading/test/transforms.native.js +1 -5
- package/src/heading/transforms.js +10 -3
- package/src/heading/variations.js +37 -0
- package/src/html/edit.js +62 -56
- package/src/html/editor.scss +69 -10
- package/src/html/modal.js +290 -0
- package/src/html/test/utils.js +234 -0
- package/src/html/utils.js +75 -0
- package/src/navigation-link/edit.js +44 -13
- package/src/navigation-link/editor.scss +7 -0
- package/src/navigation-link/index.php +65 -2
- package/src/navigation-link/link-ui/index.js +9 -8
- package/src/navigation-link/shared/controls.js +70 -12
- package/src/navigation-link/shared/test/controls.js +5 -0
- package/src/navigation-link/shared/test/use-entity-binding.js +14 -1
- package/src/navigation-link/shared/use-entity-binding.js +57 -9
- package/src/paragraph/block.json +1 -3
- package/src/paragraph/deprecated.js +87 -20
- package/src/paragraph/edit.js +7 -18
- package/src/paragraph/edit.native.js +18 -6
- package/src/paragraph/index.js +2 -0
- package/src/paragraph/save.js +4 -3
- package/src/paragraph/test/__snapshots__/transforms.native.js.snap +0 -6
- package/src/paragraph/test/edit.native.js +5 -5
- package/src/paragraph/test/transforms.native.js +0 -1
- package/src/paragraph/transforms.js +7 -1
- package/src/paragraph/variations.js +39 -0
- package/src/pullquote/block.json +3 -2
- package/src/pullquote/test/__snapshots__/transforms.native.js.snap +5 -5
- package/src/pullquote/test/transforms.native.js +1 -1
- package/src/pullquote/transforms.js +0 -31
- package/src/quote/test/__snapshots__/transforms.native.js.snap +0 -6
- package/src/quote/test/transforms.native.js +1 -5
- package/src/quote/transforms.js +0 -25
- package/src/utils/transformation-categories.native.js +0 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/src/pullquote/test/edit.native.js +0 -73
|
@@ -87,10 +87,11 @@ export function Controls( { attributes, setAttributes, clientId } ) {
|
|
|
87
87
|
}, [ url ] );
|
|
88
88
|
|
|
89
89
|
// Use the entity binding hook internally
|
|
90
|
-
const { hasUrlBinding, clearBinding } =
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
const { hasUrlBinding, isBoundEntityAvailable, clearBinding } =
|
|
91
|
+
useEntityBinding( {
|
|
92
|
+
clientId,
|
|
93
|
+
attributes,
|
|
94
|
+
} );
|
|
94
95
|
|
|
95
96
|
// Get direct store dispatch to bypass setBoundAttributes wrapper
|
|
96
97
|
const { updateBlockAttributes } = useDispatch( blockEditorStore );
|
|
@@ -111,8 +112,7 @@ export function Controls( { attributes, setAttributes, clientId } ) {
|
|
|
111
112
|
};
|
|
112
113
|
|
|
113
114
|
useEffect( () => {
|
|
114
|
-
//
|
|
115
|
-
// only want to focus the input if the url is not bound to an entity.
|
|
115
|
+
// Only want to focus the input if the url is not bound to an entity.
|
|
116
116
|
if ( ! hasUrlBinding && shouldFocusURLInputRef.current ) {
|
|
117
117
|
// focuses and highlights the url input value, giving the user
|
|
118
118
|
// the ability to delete the value quickly or edit it.
|
|
@@ -165,12 +165,28 @@ export function Controls( { attributes, setAttributes, clientId } ) {
|
|
|
165
165
|
__next40pxDefaultSize
|
|
166
166
|
id={ inputId }
|
|
167
167
|
label={ __( 'Link' ) }
|
|
168
|
-
value={
|
|
168
|
+
value={ ( () => {
|
|
169
|
+
if ( hasUrlBinding && ! isBoundEntityAvailable ) {
|
|
170
|
+
return '';
|
|
171
|
+
}
|
|
172
|
+
return inputValue ? safeDecodeURI( inputValue ) : '';
|
|
173
|
+
} )() }
|
|
169
174
|
autoComplete="off"
|
|
170
175
|
type="url"
|
|
171
176
|
disabled={ hasUrlBinding }
|
|
177
|
+
aria-invalid={
|
|
178
|
+
hasUrlBinding && ! isBoundEntityAvailable
|
|
179
|
+
? 'true'
|
|
180
|
+
: undefined
|
|
181
|
+
}
|
|
182
|
+
aria-describedby={ helpTextId }
|
|
183
|
+
className={
|
|
184
|
+
hasUrlBinding && ! isBoundEntityAvailable
|
|
185
|
+
? 'navigation-link-control__input-with-error-suffix'
|
|
186
|
+
: undefined
|
|
187
|
+
}
|
|
172
188
|
onChange={ ( newValue ) => {
|
|
173
|
-
if (
|
|
189
|
+
if ( isBoundEntityAvailable ) {
|
|
174
190
|
return;
|
|
175
191
|
}
|
|
176
192
|
|
|
@@ -180,13 +196,13 @@ export function Controls( { attributes, setAttributes, clientId } ) {
|
|
|
180
196
|
setInputValue( newValue );
|
|
181
197
|
} }
|
|
182
198
|
onFocus={ () => {
|
|
183
|
-
if (
|
|
199
|
+
if ( isBoundEntityAvailable ) {
|
|
184
200
|
return;
|
|
185
201
|
}
|
|
186
202
|
lastURLRef.current = url;
|
|
187
203
|
} }
|
|
188
204
|
onBlur={ () => {
|
|
189
|
-
if (
|
|
205
|
+
if ( isBoundEntityAvailable ) {
|
|
190
206
|
return;
|
|
191
207
|
}
|
|
192
208
|
|
|
@@ -204,11 +220,19 @@ export function Controls( { attributes, setAttributes, clientId } ) {
|
|
|
204
220
|
} );
|
|
205
221
|
} }
|
|
206
222
|
help={
|
|
207
|
-
hasUrlBinding && (
|
|
208
|
-
<
|
|
223
|
+
hasUrlBinding && ! isBoundEntityAvailable ? (
|
|
224
|
+
<MissingEntityHelpText
|
|
225
|
+
id={ helpTextId }
|
|
209
226
|
type={ attributes.type }
|
|
210
227
|
kind={ attributes.kind }
|
|
211
228
|
/>
|
|
229
|
+
) : (
|
|
230
|
+
isBoundEntityAvailable && (
|
|
231
|
+
<BindingHelpText
|
|
232
|
+
type={ attributes.type }
|
|
233
|
+
kind={ attributes.kind }
|
|
234
|
+
/>
|
|
235
|
+
)
|
|
212
236
|
)
|
|
213
237
|
}
|
|
214
238
|
suffix={
|
|
@@ -225,6 +249,11 @@ export function Controls( { attributes, setAttributes, clientId } ) {
|
|
|
225
249
|
showTooltip
|
|
226
250
|
label={ __( 'Unsync and edit' ) }
|
|
227
251
|
__next40pxDefaultSize
|
|
252
|
+
className={
|
|
253
|
+
hasUrlBinding && ! isBoundEntityAvailable
|
|
254
|
+
? 'navigation-link-control__error-suffix-button'
|
|
255
|
+
: undefined
|
|
256
|
+
}
|
|
228
257
|
/>
|
|
229
258
|
)
|
|
230
259
|
}
|
|
@@ -306,3 +335,32 @@ function BindingHelpText( { type, kind } ) {
|
|
|
306
335
|
entityType
|
|
307
336
|
);
|
|
308
337
|
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Component to display error help text for missing entity bindings.
|
|
341
|
+
*
|
|
342
|
+
* @param {Object} props - Component props
|
|
343
|
+
* @param {string} props.id - ID for the help text element (for aria-describedby)
|
|
344
|
+
* @param {string} props.type - The entity type
|
|
345
|
+
* @param {string} props.kind - The entity kind
|
|
346
|
+
* @return {JSX.Element} Error help text component
|
|
347
|
+
*/
|
|
348
|
+
function MissingEntityHelpText( { id, type, kind } ) {
|
|
349
|
+
const entityType = getEntityTypeName( type, kind );
|
|
350
|
+
return (
|
|
351
|
+
<span
|
|
352
|
+
id={ id }
|
|
353
|
+
className="navigation-link-control__error-text"
|
|
354
|
+
role="alert"
|
|
355
|
+
aria-live="polite"
|
|
356
|
+
>
|
|
357
|
+
{ sprintf(
|
|
358
|
+
/* translators: %s is the entity type (e.g., "page", "post", "category") */
|
|
359
|
+
__(
|
|
360
|
+
'Synced %s is missing. Please update or remove this link.'
|
|
361
|
+
),
|
|
362
|
+
entityType
|
|
363
|
+
) }
|
|
364
|
+
</span>
|
|
365
|
+
);
|
|
366
|
+
}
|
|
@@ -28,6 +28,7 @@ jest.mock( '../../../utils/hooks', () => ( {
|
|
|
28
28
|
jest.mock( '../use-entity-binding', () => ( {
|
|
29
29
|
useEntityBinding: jest.fn( () => ( {
|
|
30
30
|
hasUrlBinding: false,
|
|
31
|
+
isBoundEntityAvailable: false,
|
|
31
32
|
clearBinding: jest.fn(),
|
|
32
33
|
} ) ),
|
|
33
34
|
} ) );
|
|
@@ -202,6 +203,7 @@ describe( 'Controls', () => {
|
|
|
202
203
|
const { useEntityBinding } = require( '../use-entity-binding' );
|
|
203
204
|
useEntityBinding.mockReturnValue( {
|
|
204
205
|
hasUrlBinding: true,
|
|
206
|
+
isBoundEntityAvailable: true,
|
|
205
207
|
clearBinding: jest.fn(),
|
|
206
208
|
} );
|
|
207
209
|
|
|
@@ -225,6 +227,7 @@ describe( 'Controls', () => {
|
|
|
225
227
|
const { useEntityBinding } = require( '../use-entity-binding' );
|
|
226
228
|
useEntityBinding.mockReturnValue( {
|
|
227
229
|
hasUrlBinding: true,
|
|
230
|
+
isBoundEntityAvailable: true,
|
|
228
231
|
clearBinding: jest.fn(),
|
|
229
232
|
} );
|
|
230
233
|
|
|
@@ -262,6 +265,7 @@ describe( 'Controls', () => {
|
|
|
262
265
|
const { useEntityBinding } = require( '../use-entity-binding' );
|
|
263
266
|
useEntityBinding.mockReturnValue( {
|
|
264
267
|
hasUrlBinding: true,
|
|
268
|
+
isBoundEntityAvailable: true,
|
|
265
269
|
clearBinding: jest.fn(),
|
|
266
270
|
} );
|
|
267
271
|
|
|
@@ -285,6 +289,7 @@ describe( 'Controls', () => {
|
|
|
285
289
|
const { useEntityBinding } = require( '../use-entity-binding' );
|
|
286
290
|
useEntityBinding.mockReturnValue( {
|
|
287
291
|
hasUrlBinding: true,
|
|
292
|
+
isBoundEntityAvailable: true,
|
|
288
293
|
clearBinding: jest.fn(),
|
|
289
294
|
} );
|
|
290
295
|
|
|
@@ -18,12 +18,23 @@ import {
|
|
|
18
18
|
// Mock the entire @wordpress/block-editor module
|
|
19
19
|
jest.mock( '@wordpress/block-editor', () => ( {
|
|
20
20
|
useBlockBindingsUtils: jest.fn(),
|
|
21
|
+
useBlockEditingMode: jest.fn(),
|
|
21
22
|
} ) );
|
|
22
23
|
|
|
24
|
+
// Mock useSelect specifically to avoid needing to set up full data store
|
|
25
|
+
jest.mock( '@wordpress/data/src/components/use-select', () => {
|
|
26
|
+
const mock = jest.fn();
|
|
27
|
+
return mock;
|
|
28
|
+
} );
|
|
29
|
+
|
|
23
30
|
/**
|
|
24
31
|
* WordPress dependencies
|
|
25
32
|
*/
|
|
26
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
useBlockBindingsUtils,
|
|
35
|
+
useBlockEditingMode,
|
|
36
|
+
} from '@wordpress/block-editor';
|
|
37
|
+
import { useSelect } from '@wordpress/data';
|
|
27
38
|
|
|
28
39
|
describe( 'useEntityBinding', () => {
|
|
29
40
|
const mockUpdateBlockBindings = jest.fn();
|
|
@@ -33,6 +44,8 @@ describe( 'useEntityBinding', () => {
|
|
|
33
44
|
useBlockBindingsUtils.mockReturnValue( {
|
|
34
45
|
updateBlockBindings: mockUpdateBlockBindings,
|
|
35
46
|
} );
|
|
47
|
+
useBlockEditingMode.mockReturnValue( 'default' );
|
|
48
|
+
useSelect.mockReturnValue( true );
|
|
36
49
|
} );
|
|
37
50
|
|
|
38
51
|
describe( 'hasUrlBinding', () => {
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { useCallback } from '@wordpress/element';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
useBlockBindingsUtils,
|
|
7
|
+
useBlockEditingMode,
|
|
8
|
+
} from '@wordpress/block-editor';
|
|
9
|
+
import { useSelect } from '@wordpress/data';
|
|
10
|
+
import { store as coreStore } from '@wordpress/core-data';
|
|
6
11
|
|
|
7
12
|
/**
|
|
8
13
|
* Builds entity binding configuration for navigation link URLs.
|
|
@@ -16,7 +21,7 @@ import { useBlockBindingsUtils } from '@wordpress/block-editor';
|
|
|
16
21
|
* @throws {Error} If kind is not 'post-type' or 'taxonomy'
|
|
17
22
|
*/
|
|
18
23
|
export function buildNavigationLinkEntityBinding( kind ) {
|
|
19
|
-
// Validate kind parameter exists
|
|
24
|
+
// Validate kind parameter exists.
|
|
20
25
|
if ( kind === undefined ) {
|
|
21
26
|
throw new Error(
|
|
22
27
|
'buildNavigationLinkEntityBinding requires a kind parameter. ' +
|
|
@@ -24,7 +29,7 @@ export function buildNavigationLinkEntityBinding( kind ) {
|
|
|
24
29
|
);
|
|
25
30
|
}
|
|
26
31
|
|
|
27
|
-
// Validate kind parameter value
|
|
32
|
+
// Validate kind parameter value.
|
|
28
33
|
if ( kind !== 'post-type' && kind !== 'taxonomy' ) {
|
|
29
34
|
throw new Error(
|
|
30
35
|
`Invalid kind "${ kind }" provided to buildNavigationLinkEntityBinding. ` +
|
|
@@ -57,7 +62,8 @@ export function buildNavigationLinkEntityBinding( kind ) {
|
|
|
57
62
|
*/
|
|
58
63
|
export function useEntityBinding( { clientId, attributes } ) {
|
|
59
64
|
const { updateBlockBindings } = useBlockBindingsUtils( clientId );
|
|
60
|
-
const { metadata, id, kind } = attributes;
|
|
65
|
+
const { metadata, id, kind, type } = attributes;
|
|
66
|
+
const blockEditingMode = useBlockEditingMode();
|
|
61
67
|
|
|
62
68
|
const hasUrlBinding = !! metadata?.bindings?.url && !! id;
|
|
63
69
|
const expectedSource =
|
|
@@ -65,6 +71,47 @@ export function useEntityBinding( { clientId, attributes } ) {
|
|
|
65
71
|
const hasCorrectBinding =
|
|
66
72
|
hasUrlBinding && metadata?.bindings?.url?.source === expectedSource;
|
|
67
73
|
|
|
74
|
+
// Check if the bound entity is available (not deleted).
|
|
75
|
+
const isBoundEntityAvailable = useSelect(
|
|
76
|
+
( select ) => {
|
|
77
|
+
// First check: metadata/binding must exist
|
|
78
|
+
if ( ! hasCorrectBinding || ! id ) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const isPostType = kind === 'post-type';
|
|
83
|
+
const isTaxonomy = kind === 'taxonomy';
|
|
84
|
+
|
|
85
|
+
// Only check entity availability for post types and taxonomies.
|
|
86
|
+
if ( ! isPostType && ! isTaxonomy ) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Skip check in disabled contexts to avoid unnecessary requests.
|
|
91
|
+
if ( blockEditingMode === 'disabled' ) {
|
|
92
|
+
return true; // Assume available in disabled contexts.
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Second check: entity must exist
|
|
96
|
+
const { getEntityRecord, hasFinishedResolution } =
|
|
97
|
+
select( coreStore );
|
|
98
|
+
|
|
99
|
+
// Use the correct entity type based on kind.
|
|
100
|
+
const entityType = isTaxonomy ? 'taxonomy' : 'postType';
|
|
101
|
+
const entityRecord = getEntityRecord( entityType, type, id );
|
|
102
|
+
const hasResolved = hasFinishedResolution( 'getEntityRecord', [
|
|
103
|
+
entityType,
|
|
104
|
+
type,
|
|
105
|
+
id,
|
|
106
|
+
] );
|
|
107
|
+
|
|
108
|
+
// If resolution has finished and entityRecord is undefined, the entity was deleted.
|
|
109
|
+
// Return true if entity exists, false if deleted.
|
|
110
|
+
return hasResolved ? entityRecord !== undefined : true;
|
|
111
|
+
},
|
|
112
|
+
[ kind, type, id, hasCorrectBinding, blockEditingMode ]
|
|
113
|
+
);
|
|
114
|
+
|
|
68
115
|
const clearBinding = useCallback( () => {
|
|
69
116
|
if ( hasUrlBinding ) {
|
|
70
117
|
updateBlockBindings( { url: undefined } );
|
|
@@ -73,11 +120,11 @@ export function useEntityBinding( { clientId, attributes } ) {
|
|
|
73
120
|
|
|
74
121
|
const createBinding = useCallback(
|
|
75
122
|
( updatedAttributes ) => {
|
|
76
|
-
// Use updated attributes if provided, otherwise fall back to closure attributes
|
|
77
|
-
// updatedAttributes needed to access the most up-to-date data when called synchronously
|
|
123
|
+
// Use updated attributes if provided, otherwise fall back to closure attributes.
|
|
124
|
+
// updatedAttributes needed to access the most up-to-date data when called synchronously.
|
|
78
125
|
const kindToUse = updatedAttributes?.kind ?? kind;
|
|
79
126
|
|
|
80
|
-
// Avoid creating binding if no kind is provided
|
|
127
|
+
// Avoid creating binding if no kind is provided.
|
|
81
128
|
if ( ! kindToUse ) {
|
|
82
129
|
return;
|
|
83
130
|
}
|
|
@@ -91,14 +138,15 @@ export function useEntityBinding( { clientId, attributes } ) {
|
|
|
91
138
|
'Failed to create entity binding:',
|
|
92
139
|
error.message
|
|
93
140
|
);
|
|
94
|
-
// Don't create binding if validation fails
|
|
141
|
+
// Don't create binding if validation fails.
|
|
95
142
|
}
|
|
96
143
|
},
|
|
97
|
-
[ updateBlockBindings, kind
|
|
144
|
+
[ updateBlockBindings, kind ]
|
|
98
145
|
);
|
|
99
146
|
|
|
100
147
|
return {
|
|
101
148
|
hasUrlBinding: hasCorrectBinding,
|
|
149
|
+
isBoundEntityAvailable,
|
|
102
150
|
clearBinding,
|
|
103
151
|
createBinding,
|
|
104
152
|
};
|
package/src/paragraph/block.json
CHANGED
|
@@ -8,9 +8,6 @@
|
|
|
8
8
|
"keywords": [ "text" ],
|
|
9
9
|
"textdomain": "default",
|
|
10
10
|
"attributes": {
|
|
11
|
-
"align": {
|
|
12
|
-
"type": "string"
|
|
13
|
-
},
|
|
14
11
|
"content": {
|
|
15
12
|
"type": "rich-text",
|
|
16
13
|
"source": "rich-text",
|
|
@@ -58,6 +55,7 @@
|
|
|
58
55
|
"typography": {
|
|
59
56
|
"fontSize": true,
|
|
60
57
|
"lineHeight": true,
|
|
58
|
+
"textAlign": true,
|
|
61
59
|
"__experimentalFontFamily": true,
|
|
62
60
|
"__experimentalTextDecoration": true,
|
|
63
61
|
"__experimentalFontStyle": true,
|
|
@@ -90,9 +90,62 @@ const migrateCustomColorsAndFontSizes = ( attributes ) => {
|
|
|
90
90
|
};
|
|
91
91
|
};
|
|
92
92
|
|
|
93
|
+
const migrateTextAlign = ( attributes ) => {
|
|
94
|
+
const { align, ...restAttributes } = attributes;
|
|
95
|
+
if ( ! align ) {
|
|
96
|
+
return attributes;
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
...restAttributes,
|
|
100
|
+
style: {
|
|
101
|
+
...attributes.style,
|
|
102
|
+
typography: {
|
|
103
|
+
...attributes.style?.typography,
|
|
104
|
+
textAlign: align,
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
|
|
93
110
|
const { style, ...restBlockAttributes } = blockAttributes;
|
|
94
111
|
|
|
95
112
|
const deprecated = [
|
|
113
|
+
// Version with `align` attribute.
|
|
114
|
+
{
|
|
115
|
+
supports: {
|
|
116
|
+
className: false,
|
|
117
|
+
typography: {
|
|
118
|
+
fontSize: true,
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
attributes: blockAttributes,
|
|
122
|
+
isEligible( attributes ) {
|
|
123
|
+
return (
|
|
124
|
+
!! attributes.align ||
|
|
125
|
+
!! attributes.className?.match(
|
|
126
|
+
/\bhas-text-align-(left|center|right)\b/
|
|
127
|
+
)
|
|
128
|
+
);
|
|
129
|
+
},
|
|
130
|
+
save( { attributes } ) {
|
|
131
|
+
const { align, content, dropCap, direction } = attributes;
|
|
132
|
+
const className = clsx( {
|
|
133
|
+
'has-drop-cap':
|
|
134
|
+
align === ( isRTL() ? 'left' : 'right' ) ||
|
|
135
|
+
align === 'center'
|
|
136
|
+
? false
|
|
137
|
+
: dropCap,
|
|
138
|
+
[ `has-text-align-${ align }` ]: align,
|
|
139
|
+
} );
|
|
140
|
+
|
|
141
|
+
return (
|
|
142
|
+
<p { ...useBlockProps.save( { className, dir: direction } ) }>
|
|
143
|
+
<RichText.Content value={ content } />
|
|
144
|
+
</p>
|
|
145
|
+
);
|
|
146
|
+
},
|
|
147
|
+
migrate: migrateTextAlign,
|
|
148
|
+
},
|
|
96
149
|
// Version without drop cap on aligned text.
|
|
97
150
|
{
|
|
98
151
|
supports,
|
|
@@ -108,6 +161,7 @@ const deprecated = [
|
|
|
108
161
|
type: 'number',
|
|
109
162
|
},
|
|
110
163
|
},
|
|
164
|
+
migrate: migrateTextAlign,
|
|
111
165
|
save( { attributes } ) {
|
|
112
166
|
const { align, content, dropCap, direction } = attributes;
|
|
113
167
|
const className = clsx( {
|
|
@@ -140,7 +194,11 @@ const deprecated = [
|
|
|
140
194
|
type: 'number',
|
|
141
195
|
},
|
|
142
196
|
},
|
|
143
|
-
migrate
|
|
197
|
+
migrate( attributes ) {
|
|
198
|
+
return migrateCustomColorsAndFontSizes(
|
|
199
|
+
migrateTextAlign( attributes )
|
|
200
|
+
);
|
|
201
|
+
},
|
|
144
202
|
save( { attributes } ) {
|
|
145
203
|
const {
|
|
146
204
|
align,
|
|
@@ -205,7 +263,11 @@ const deprecated = [
|
|
|
205
263
|
type: 'number',
|
|
206
264
|
},
|
|
207
265
|
},
|
|
208
|
-
migrate
|
|
266
|
+
migrate( attributes ) {
|
|
267
|
+
return migrateCustomColorsAndFontSizes(
|
|
268
|
+
migrateTextAlign( attributes )
|
|
269
|
+
);
|
|
270
|
+
},
|
|
209
271
|
save( { attributes } ) {
|
|
210
272
|
const {
|
|
211
273
|
align,
|
|
@@ -273,7 +335,11 @@ const deprecated = [
|
|
|
273
335
|
type: 'string',
|
|
274
336
|
},
|
|
275
337
|
},
|
|
276
|
-
migrate
|
|
338
|
+
migrate( attributes ) {
|
|
339
|
+
return migrateCustomColorsAndFontSizes(
|
|
340
|
+
migrateTextAlign( attributes )
|
|
341
|
+
);
|
|
342
|
+
},
|
|
277
343
|
save( { attributes } ) {
|
|
278
344
|
const {
|
|
279
345
|
width,
|
|
@@ -363,21 +429,24 @@ const deprecated = [
|
|
|
363
429
|
);
|
|
364
430
|
},
|
|
365
431
|
migrate( attributes ) {
|
|
366
|
-
return migrateCustomColorsAndFontSizes(
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
customTextColor:
|
|
372
|
-
attributes.textColor && '#' === attributes.textColor[ 0 ]
|
|
373
|
-
? attributes.textColor
|
|
374
|
-
: undefined,
|
|
375
|
-
customBackgroundColor:
|
|
376
|
-
attributes.backgroundColor &&
|
|
377
|
-
'#' === attributes.backgroundColor[ 0 ]
|
|
378
|
-
? attributes.backgroundColor
|
|
432
|
+
return migrateCustomColorsAndFontSizes(
|
|
433
|
+
migrateTextAlign( {
|
|
434
|
+
...attributes,
|
|
435
|
+
customFontSize: Number.isFinite( attributes.fontSize )
|
|
436
|
+
? attributes.fontSize
|
|
379
437
|
: undefined,
|
|
380
|
-
|
|
438
|
+
customTextColor:
|
|
439
|
+
attributes.textColor &&
|
|
440
|
+
'#' === attributes.textColor[ 0 ]
|
|
441
|
+
? attributes.textColor
|
|
442
|
+
: undefined,
|
|
443
|
+
customBackgroundColor:
|
|
444
|
+
attributes.backgroundColor &&
|
|
445
|
+
'#' === attributes.backgroundColor[ 0 ]
|
|
446
|
+
? attributes.backgroundColor
|
|
447
|
+
: undefined,
|
|
448
|
+
} )
|
|
449
|
+
);
|
|
381
450
|
},
|
|
382
451
|
},
|
|
383
452
|
{
|
|
@@ -393,9 +462,7 @@ const deprecated = [
|
|
|
393
462
|
save( { attributes } ) {
|
|
394
463
|
return <RawHTML>{ attributes.content }</RawHTML>;
|
|
395
464
|
},
|
|
396
|
-
migrate( attributes )
|
|
397
|
-
return attributes;
|
|
398
|
-
},
|
|
465
|
+
migrate: ( attributes ) => attributes,
|
|
399
466
|
},
|
|
400
467
|
];
|
|
401
468
|
|
package/src/paragraph/edit.js
CHANGED
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
__experimentalToolsPanelItem as ToolsPanelItem,
|
|
14
14
|
} from '@wordpress/components';
|
|
15
15
|
import {
|
|
16
|
-
AlignmentControl,
|
|
17
16
|
BlockControls,
|
|
18
17
|
InspectorControls,
|
|
19
18
|
RichText,
|
|
@@ -58,10 +57,11 @@ function DropCapControl( { clientId, attributes, setAttributes, name } ) {
|
|
|
58
57
|
return null;
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
const {
|
|
60
|
+
const { style, dropCap } = attributes;
|
|
61
|
+
const textAlign = style?.typography?.textAlign;
|
|
62
62
|
|
|
63
63
|
let helpText;
|
|
64
|
-
if ( hasDropCapDisabled(
|
|
64
|
+
if ( hasDropCapDisabled( textAlign ) ) {
|
|
65
65
|
helpText = __( 'Not available for aligned text.' );
|
|
66
66
|
} else if ( dropCap ) {
|
|
67
67
|
helpText = __( 'Showing large initial letter.' );
|
|
@@ -91,7 +91,7 @@ function DropCapControl( { clientId, attributes, setAttributes, name } ) {
|
|
|
91
91
|
checked={ !! dropCap }
|
|
92
92
|
onChange={ () => setAttributes( { dropCap: ! dropCap } ) }
|
|
93
93
|
help={ helpText }
|
|
94
|
-
disabled={ hasDropCapDisabled(
|
|
94
|
+
disabled={ hasDropCapDisabled( textAlign ) }
|
|
95
95
|
/>
|
|
96
96
|
</ToolsPanelItem>
|
|
97
97
|
</InspectorControls>
|
|
@@ -108,12 +108,12 @@ function ParagraphBlock( {
|
|
|
108
108
|
isSelected: isSingleSelected,
|
|
109
109
|
name,
|
|
110
110
|
} ) {
|
|
111
|
-
const {
|
|
111
|
+
const { content, direction, dropCap, placeholder, style } = attributes;
|
|
112
|
+
const textAlign = style?.typography?.textAlign;
|
|
112
113
|
const blockProps = useBlockProps( {
|
|
113
114
|
ref: useOnEnter( { clientId, content } ),
|
|
114
115
|
className: clsx( {
|
|
115
|
-
'has-drop-cap': hasDropCapDisabled(
|
|
116
|
-
[ `has-text-align-${ align }` ]: align,
|
|
116
|
+
'has-drop-cap': hasDropCapDisabled( textAlign ) ? false : dropCap,
|
|
117
117
|
} ),
|
|
118
118
|
style: { direction },
|
|
119
119
|
} );
|
|
@@ -123,17 +123,6 @@ function ParagraphBlock( {
|
|
|
123
123
|
<>
|
|
124
124
|
{ blockEditingMode === 'default' && (
|
|
125
125
|
<BlockControls group="block">
|
|
126
|
-
<AlignmentControl
|
|
127
|
-
value={ align }
|
|
128
|
-
onChange={ ( newAlign ) =>
|
|
129
|
-
setAttributes( {
|
|
130
|
-
align: newAlign,
|
|
131
|
-
dropCap: hasDropCapDisabled( newAlign )
|
|
132
|
-
? false
|
|
133
|
-
: dropCap,
|
|
134
|
-
} )
|
|
135
|
-
}
|
|
136
|
-
/>
|
|
137
126
|
<ParagraphRTLControl
|
|
138
127
|
direction={ direction }
|
|
139
128
|
setDirection={ ( newDirection ) =>
|
|
@@ -29,7 +29,8 @@ function ParagraphBlock( {
|
|
|
29
29
|
return !! select( blockEditorStore ).getSettings().isRTL;
|
|
30
30
|
}, [] );
|
|
31
31
|
|
|
32
|
-
const {
|
|
32
|
+
const { content, placeholder, style: attributesStyle } = attributes;
|
|
33
|
+
const textAlign = attributesStyle?.typography?.textAlign;
|
|
33
34
|
|
|
34
35
|
const styles = {
|
|
35
36
|
...( style?.baseColors && {
|
|
@@ -40,9 +41,20 @@ function ParagraphBlock( {
|
|
|
40
41
|
...style,
|
|
41
42
|
};
|
|
42
43
|
|
|
43
|
-
const onAlignmentChange = useCallback(
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
const onAlignmentChange = useCallback(
|
|
45
|
+
( nextAlign ) => {
|
|
46
|
+
setAttributes( {
|
|
47
|
+
style: {
|
|
48
|
+
...attributesStyle,
|
|
49
|
+
typography: {
|
|
50
|
+
...attributesStyle?.typography,
|
|
51
|
+
textAlign: nextAlign,
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
} );
|
|
55
|
+
},
|
|
56
|
+
[ attributesStyle, setAttributes ]
|
|
57
|
+
);
|
|
46
58
|
|
|
47
59
|
const parentTextAlignment = allowedParentBlockAlignments.includes(
|
|
48
60
|
parentBlockAlignment
|
|
@@ -50,13 +62,13 @@ function ParagraphBlock( {
|
|
|
50
62
|
? parentBlockAlignment
|
|
51
63
|
: undefined;
|
|
52
64
|
|
|
53
|
-
const textAlignment =
|
|
65
|
+
const textAlignment = textAlign || parentTextAlignment;
|
|
54
66
|
|
|
55
67
|
return (
|
|
56
68
|
<>
|
|
57
69
|
<BlockControls group="block">
|
|
58
70
|
<AlignmentControl
|
|
59
|
-
value={
|
|
71
|
+
value={ textAlign }
|
|
60
72
|
isRTL={ isRTL }
|
|
61
73
|
onChange={ onAlignmentChange }
|
|
62
74
|
/>
|
package/src/paragraph/index.js
CHANGED
|
@@ -13,6 +13,7 @@ import edit from './edit';
|
|
|
13
13
|
import metadata from './block.json';
|
|
14
14
|
import save from './save';
|
|
15
15
|
import transforms from './transforms';
|
|
16
|
+
import variations from './variations';
|
|
16
17
|
|
|
17
18
|
const { name } = metadata;
|
|
18
19
|
|
|
@@ -54,6 +55,7 @@ export const settings = {
|
|
|
54
55
|
},
|
|
55
56
|
edit,
|
|
56
57
|
save,
|
|
58
|
+
variations,
|
|
57
59
|
};
|
|
58
60
|
|
|
59
61
|
export const init = () => initBlock( { name, metadata, settings } );
|
package/src/paragraph/save.js
CHANGED
|
@@ -10,13 +10,14 @@ import { RichText, useBlockProps } from '@wordpress/block-editor';
|
|
|
10
10
|
import { isRTL } from '@wordpress/i18n';
|
|
11
11
|
|
|
12
12
|
export default function save( { attributes } ) {
|
|
13
|
-
const {
|
|
13
|
+
const { content, dropCap, direction, style } = attributes;
|
|
14
|
+
const textAlign = style?.typography?.textAlign;
|
|
14
15
|
const className = clsx( {
|
|
15
16
|
'has-drop-cap':
|
|
16
|
-
|
|
17
|
+
textAlign === ( isRTL() ? 'left' : 'right' ) ||
|
|
18
|
+
textAlign === 'center'
|
|
17
19
|
? false
|
|
18
20
|
: dropCap,
|
|
19
|
-
[ `has-text-align-${ align }` ]: align,
|
|
20
21
|
} );
|
|
21
22
|
|
|
22
23
|
return (
|
|
@@ -44,12 +44,6 @@ exports[`Paragraph block transforms to Preformatted block 1`] = `
|
|
|
44
44
|
<!-- /wp:preformatted -->"
|
|
45
45
|
`;
|
|
46
46
|
|
|
47
|
-
exports[`Paragraph block transforms to Pullquote block 1`] = `
|
|
48
|
-
"<!-- wp:pullquote -->
|
|
49
|
-
<figure class="wp-block-pullquote"><blockquote><p>Example text</p></blockquote></figure>
|
|
50
|
-
<!-- /wp:pullquote -->"
|
|
51
|
-
`;
|
|
52
|
-
|
|
53
47
|
exports[`Paragraph block transforms to Quote block 1`] = `
|
|
54
48
|
"<!-- wp:quote -->
|
|
55
49
|
<blockquote class="wp-block-quote"><!-- wp:paragraph -->
|