@wordpress/block-library 8.12.1 → 8.12.2
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/build/avatar/index.js +1 -1
- package/build/buttons/edit.js +5 -1
- package/build/buttons/edit.js.map +1 -1
- package/build/image/edit.js +0 -4
- package/build/image/edit.js.map +1 -1
- package/build/image/image.js +96 -43
- package/build/image/image.js.map +1 -1
- package/build/image/index.js +6 -0
- package/build/image/index.js.map +1 -1
- package/build/image/save.js +6 -1
- package/build/image/save.js.map +1 -1
- package/build/image/utils.js +18 -0
- package/build/image/utils.js.map +1 -1
- package/build/query-pagination-numbers/index.js +1 -1
- package/build/site-tagline/icon.js +1 -1
- package/build/site-tagline/icon.js.map +1 -1
- package/build-module/avatar/index.js +1 -1
- package/build-module/buttons/edit.js +5 -1
- package/build-module/buttons/edit.js.map +1 -1
- package/build-module/image/edit.js +0 -4
- package/build-module/image/edit.js.map +1 -1
- package/build-module/image/image.js +96 -46
- package/build-module/image/image.js.map +1 -1
- package/build-module/image/index.js +6 -0
- package/build-module/image/index.js.map +1 -1
- package/build-module/image/save.js +6 -1
- package/build-module/image/save.js.map +1 -1
- package/build-module/image/utils.js +16 -0
- package/build-module/image/utils.js.map +1 -1
- package/build-module/query-pagination-numbers/index.js +1 -1
- package/build-module/site-tagline/icon.js +1 -1
- package/build-module/site-tagline/icon.js.map +1 -1
- package/package.json +8 -8
- package/src/avatar/block.json +1 -1
- package/src/buttons/edit.js +2 -2
- package/src/image/block.json +6 -0
- package/src/image/edit.js +0 -4
- package/src/image/image.js +130 -62
- package/src/image/save.js +7 -1
- package/src/image/utils.js +16 -0
- package/src/query-pagination-numbers/block.json +1 -1
- package/src/site-tagline/icon.js +1 -1
package/src/image/image.js
CHANGED
|
@@ -4,13 +4,15 @@
|
|
|
4
4
|
import { isBlobURL } from '@wordpress/blob';
|
|
5
5
|
import {
|
|
6
6
|
ExternalLink,
|
|
7
|
-
PanelBody,
|
|
8
7
|
ResizableBox,
|
|
9
8
|
Spinner,
|
|
10
9
|
TextareaControl,
|
|
11
10
|
TextControl,
|
|
12
11
|
ToolbarButton,
|
|
13
12
|
ToolbarGroup,
|
|
13
|
+
__experimentalToolsPanel as ToolsPanel,
|
|
14
|
+
__experimentalToolsPanelItem as ToolsPanelItem,
|
|
15
|
+
__experimentalUseCustomUnits as useCustomUnits,
|
|
14
16
|
} from '@wordpress/components';
|
|
15
17
|
import { useViewportMatch, usePrevious } from '@wordpress/compose';
|
|
16
18
|
import { useSelect, useDispatch } from '@wordpress/data';
|
|
@@ -18,7 +20,6 @@ import {
|
|
|
18
20
|
BlockControls,
|
|
19
21
|
InspectorControls,
|
|
20
22
|
RichText,
|
|
21
|
-
__experimentalImageSizeControl as ImageSizeControl,
|
|
22
23
|
__experimentalImageURLInputUI as ImageURLInputUI,
|
|
23
24
|
MediaReplaceFlow,
|
|
24
25
|
store as blockEditorStore,
|
|
@@ -26,6 +27,7 @@ import {
|
|
|
26
27
|
__experimentalImageEditor as ImageEditor,
|
|
27
28
|
__experimentalGetElementClassName,
|
|
28
29
|
__experimentalUseBorderProps as useBorderProps,
|
|
30
|
+
privateApis as blockEditorPrivateApis,
|
|
29
31
|
} from '@wordpress/block-editor';
|
|
30
32
|
import {
|
|
31
33
|
useEffect,
|
|
@@ -34,7 +36,7 @@ import {
|
|
|
34
36
|
useRef,
|
|
35
37
|
useCallback,
|
|
36
38
|
} from '@wordpress/element';
|
|
37
|
-
import { __, sprintf, isRTL } from '@wordpress/i18n';
|
|
39
|
+
import { __, _x, sprintf, isRTL } from '@wordpress/i18n';
|
|
38
40
|
import { getFilename } from '@wordpress/url';
|
|
39
41
|
import {
|
|
40
42
|
createBlock,
|
|
@@ -53,6 +55,7 @@ import { store as coreStore } from '@wordpress/core-data';
|
|
|
53
55
|
/**
|
|
54
56
|
* Internal dependencies
|
|
55
57
|
*/
|
|
58
|
+
import { unlock } from '../lock-unlock';
|
|
56
59
|
import { createUpgradedEmbedBlock } from '../embed/util';
|
|
57
60
|
import useClientWidth from './use-client-width';
|
|
58
61
|
import { isExternalImage } from './edit';
|
|
@@ -61,6 +64,22 @@ import { isExternalImage } from './edit';
|
|
|
61
64
|
* Module constants
|
|
62
65
|
*/
|
|
63
66
|
import { MIN_SIZE, ALLOWED_MEDIA_TYPES } from './constants';
|
|
67
|
+
import { evalAspectRatio } from './utils';
|
|
68
|
+
|
|
69
|
+
const { DimensionsTool, ResolutionTool } = unlock( blockEditorPrivateApis );
|
|
70
|
+
|
|
71
|
+
const scaleOptions = [
|
|
72
|
+
{
|
|
73
|
+
value: 'cover',
|
|
74
|
+
label: _x( 'Cover', 'Scale option for dimensions control' ),
|
|
75
|
+
help: __( 'Image covers the space evenly.' ),
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
value: 'contain',
|
|
79
|
+
label: _x( 'Contain', 'Scale option for dimensions control' ),
|
|
80
|
+
help: __( 'Image is contained without distortion.' ),
|
|
81
|
+
},
|
|
82
|
+
];
|
|
64
83
|
|
|
65
84
|
export default function Image( {
|
|
66
85
|
temporaryURL,
|
|
@@ -90,6 +109,8 @@ export default function Image( {
|
|
|
90
109
|
title,
|
|
91
110
|
width,
|
|
92
111
|
height,
|
|
112
|
+
aspectRatio,
|
|
113
|
+
scale,
|
|
93
114
|
linkTarget,
|
|
94
115
|
sizeSlug,
|
|
95
116
|
} = attributes;
|
|
@@ -272,8 +293,6 @@ export default function Image( {
|
|
|
272
293
|
|
|
273
294
|
setAttributes( {
|
|
274
295
|
url: newUrl,
|
|
275
|
-
width: undefined,
|
|
276
|
-
height: undefined,
|
|
277
296
|
sizeSlug: newSizeSlug,
|
|
278
297
|
} );
|
|
279
298
|
}
|
|
@@ -329,6 +348,13 @@ export default function Image( {
|
|
|
329
348
|
);
|
|
330
349
|
}
|
|
331
350
|
|
|
351
|
+
// TODO: Can allow more units after figuring out how they should interact
|
|
352
|
+
// with the ResizableBox and ImageEditor components. Calculations later on
|
|
353
|
+
// for those components are currently assuming px units.
|
|
354
|
+
const dimensionsUnitsOptions = useCustomUnits( {
|
|
355
|
+
availableUnits: [ 'px' ],
|
|
356
|
+
} );
|
|
357
|
+
|
|
332
358
|
const controls = (
|
|
333
359
|
<>
|
|
334
360
|
<BlockControls group="block">
|
|
@@ -407,41 +433,78 @@ export default function Image( {
|
|
|
407
433
|
</BlockControls>
|
|
408
434
|
) }
|
|
409
435
|
<InspectorControls>
|
|
410
|
-
<
|
|
436
|
+
<ToolsPanel
|
|
437
|
+
label={ __( 'Settings' ) }
|
|
438
|
+
resetAll={ () =>
|
|
439
|
+
setAttributes( {
|
|
440
|
+
width: undefined,
|
|
441
|
+
height: undefined,
|
|
442
|
+
scale: undefined,
|
|
443
|
+
aspectRatio: undefined,
|
|
444
|
+
} )
|
|
445
|
+
}
|
|
446
|
+
>
|
|
411
447
|
{ ! multiImageSelection && (
|
|
412
|
-
<
|
|
413
|
-
__nextHasNoMarginBottom
|
|
448
|
+
<ToolsPanelItem
|
|
414
449
|
label={ __( 'Alternative text' ) }
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
<ExternalLink href="https://www.w3.org/WAI/tutorials/images/decision-tree">
|
|
420
|
-
{ __(
|
|
421
|
-
'Describe the purpose of the image.'
|
|
422
|
-
) }
|
|
423
|
-
</ExternalLink>
|
|
424
|
-
<br />
|
|
425
|
-
{ __( 'Leave empty if decorative.' ) }
|
|
426
|
-
</>
|
|
450
|
+
isShownByDefault={ true }
|
|
451
|
+
hasValue={ () => alt !== '' }
|
|
452
|
+
onDeselect={ () =>
|
|
453
|
+
setAttributes( { alt: undefined } )
|
|
427
454
|
}
|
|
428
|
-
|
|
455
|
+
>
|
|
456
|
+
<TextareaControl
|
|
457
|
+
label={ __( 'Alternative text' ) }
|
|
458
|
+
value={ alt }
|
|
459
|
+
onChange={ updateAlt }
|
|
460
|
+
help={
|
|
461
|
+
<>
|
|
462
|
+
<ExternalLink href="https://www.w3.org/WAI/tutorials/images/decision-tree">
|
|
463
|
+
{ __(
|
|
464
|
+
'Describe the purpose of the image.'
|
|
465
|
+
) }
|
|
466
|
+
</ExternalLink>
|
|
467
|
+
<br />
|
|
468
|
+
{ __( 'Leave empty if decorative.' ) }
|
|
469
|
+
</>
|
|
470
|
+
}
|
|
471
|
+
__nextHasNoMarginBottom
|
|
472
|
+
/>
|
|
473
|
+
</ToolsPanelItem>
|
|
429
474
|
) }
|
|
430
|
-
<
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
475
|
+
<DimensionsTool
|
|
476
|
+
value={ {
|
|
477
|
+
width: width && `${ width }px`,
|
|
478
|
+
height: height && `${ height }px`,
|
|
479
|
+
scale,
|
|
480
|
+
aspectRatio,
|
|
481
|
+
} }
|
|
482
|
+
onChange={ ( newValue ) => {
|
|
483
|
+
// Rebuilding the object forces setting `undefined`
|
|
484
|
+
// for values that are removed since setAttributes
|
|
485
|
+
// doesn't do anything with keys that aren't set.
|
|
486
|
+
setAttributes( {
|
|
487
|
+
width:
|
|
488
|
+
newValue.width &&
|
|
489
|
+
parseInt( newValue.width, 10 ),
|
|
490
|
+
height:
|
|
491
|
+
newValue.height &&
|
|
492
|
+
parseInt( newValue.height, 10 ),
|
|
493
|
+
scale: newValue.scale,
|
|
494
|
+
aspectRatio: newValue.aspectRatio,
|
|
495
|
+
} );
|
|
496
|
+
} }
|
|
497
|
+
defaultScale="cover"
|
|
498
|
+
defaultAspectRatio="auto"
|
|
499
|
+
scaleOptions={ scaleOptions }
|
|
500
|
+
unitsOptions={ dimensionsUnitsOptions }
|
|
501
|
+
/>
|
|
502
|
+
<ResolutionTool
|
|
503
|
+
value={ sizeSlug }
|
|
504
|
+
onChange={ updateImage }
|
|
505
|
+
options={ imageSizeOptions }
|
|
443
506
|
/>
|
|
444
|
-
</
|
|
507
|
+
</ToolsPanel>
|
|
445
508
|
</InspectorControls>
|
|
446
509
|
<InspectorControls group="advanced">
|
|
447
510
|
<TextControl
|
|
@@ -483,9 +546,6 @@ export default function Image( {
|
|
|
483
546
|
|
|
484
547
|
const borderProps = useBorderProps( attributes );
|
|
485
548
|
const isRounded = attributes.className?.includes( 'is-style-rounded' );
|
|
486
|
-
const hasCustomBorder =
|
|
487
|
-
!! borderProps.className ||
|
|
488
|
-
( borderProps.style && Object.keys( borderProps.style ).length > 0 );
|
|
489
549
|
|
|
490
550
|
let img = (
|
|
491
551
|
// Disable reason: Image itself is not meant to be interactive, but
|
|
@@ -504,25 +564,20 @@ export default function Image( {
|
|
|
504
564
|
} }
|
|
505
565
|
ref={ imageRef }
|
|
506
566
|
className={ borderProps.className }
|
|
507
|
-
style={
|
|
567
|
+
style={ {
|
|
568
|
+
width:
|
|
569
|
+
( width && height ) || aspectRatio ? '100%' : 'inherit',
|
|
570
|
+
height:
|
|
571
|
+
( width && height ) || aspectRatio ? '100%' : 'inherit',
|
|
572
|
+
objectFit: scale,
|
|
573
|
+
...borderProps.style,
|
|
574
|
+
} }
|
|
508
575
|
/>
|
|
509
576
|
{ temporaryURL && <Spinner /> }
|
|
510
577
|
</>
|
|
511
578
|
/* eslint-enable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/click-events-have-key-events */
|
|
512
579
|
);
|
|
513
580
|
|
|
514
|
-
let imageWidthWithinContainer;
|
|
515
|
-
let imageHeightWithinContainer;
|
|
516
|
-
|
|
517
|
-
if ( clientWidth && naturalWidth && naturalHeight ) {
|
|
518
|
-
const exceedMaxWidth = naturalWidth > clientWidth;
|
|
519
|
-
const ratio = naturalHeight / naturalWidth;
|
|
520
|
-
imageWidthWithinContainer = exceedMaxWidth ? clientWidth : naturalWidth;
|
|
521
|
-
imageHeightWithinContainer = exceedMaxWidth
|
|
522
|
-
? clientWidth * ratio
|
|
523
|
-
: naturalHeight;
|
|
524
|
-
}
|
|
525
|
-
|
|
526
581
|
// clientWidth needs to be a number for the image Cropper to work, but sometimes it's 0
|
|
527
582
|
// So we try using the imageRef width first and fallback to clientWidth.
|
|
528
583
|
const fallbackClientWidth = imageRef.current?.width || clientWidth;
|
|
@@ -546,13 +601,17 @@ export default function Image( {
|
|
|
546
601
|
borderProps={ isRounded ? undefined : borderProps }
|
|
547
602
|
/>
|
|
548
603
|
);
|
|
549
|
-
} else if ( ! isResizable
|
|
550
|
-
img = <div style={ { width, height } }>{ img }</div>;
|
|
604
|
+
} else if ( ! isResizable ) {
|
|
605
|
+
img = <div style={ { width, height, aspectRatio } }>{ img }</div>;
|
|
551
606
|
} else {
|
|
552
|
-
const
|
|
553
|
-
|
|
607
|
+
const ratio =
|
|
608
|
+
( aspectRatio && evalAspectRatio( aspectRatio ) ) ||
|
|
609
|
+
( width && height && width / height ) ||
|
|
610
|
+
naturalWidth / naturalHeight;
|
|
611
|
+
|
|
612
|
+
const currentWidth = ! width && height ? height * ratio : width;
|
|
613
|
+
const currentHeight = ! height && width ? width / ratio : height;
|
|
554
614
|
|
|
555
|
-
const ratio = naturalWidth / naturalHeight;
|
|
556
615
|
const minWidth =
|
|
557
616
|
naturalWidth < naturalHeight ? MIN_SIZE : MIN_SIZE * ratio;
|
|
558
617
|
const minHeight =
|
|
@@ -600,16 +659,24 @@ export default function Image( {
|
|
|
600
659
|
|
|
601
660
|
img = (
|
|
602
661
|
<ResizableBox
|
|
662
|
+
style={ {
|
|
663
|
+
display: 'block',
|
|
664
|
+
objectFit: scale,
|
|
665
|
+
aspectRatio:
|
|
666
|
+
! width && ! height && aspectRatio
|
|
667
|
+
? aspectRatio
|
|
668
|
+
: undefined,
|
|
669
|
+
} }
|
|
603
670
|
size={ {
|
|
604
|
-
width:
|
|
605
|
-
height:
|
|
671
|
+
width: currentWidth ?? 'auto',
|
|
672
|
+
height: currentHeight ?? 'auto',
|
|
606
673
|
} }
|
|
607
674
|
showHandle={ isSelected }
|
|
608
675
|
minWidth={ minWidth }
|
|
609
676
|
maxWidth={ maxWidthBuffer }
|
|
610
677
|
minHeight={ minHeight }
|
|
611
678
|
maxHeight={ maxWidthBuffer / ratio }
|
|
612
|
-
lockAspectRatio
|
|
679
|
+
lockAspectRatio={ ratio }
|
|
613
680
|
enable={ {
|
|
614
681
|
top: false,
|
|
615
682
|
right: showRightHandle,
|
|
@@ -617,11 +684,12 @@ export default function Image( {
|
|
|
617
684
|
left: showLeftHandle,
|
|
618
685
|
} }
|
|
619
686
|
onResizeStart={ onResizeStart }
|
|
620
|
-
onResizeStop={ ( event, direction, elt
|
|
687
|
+
onResizeStop={ ( event, direction, elt ) => {
|
|
621
688
|
onResizeStop();
|
|
622
689
|
setAttributes( {
|
|
623
|
-
width:
|
|
624
|
-
height:
|
|
690
|
+
width: elt.offsetWidth,
|
|
691
|
+
height: elt.offsetHeight,
|
|
692
|
+
aspectRatio: undefined,
|
|
625
693
|
} );
|
|
626
694
|
} }
|
|
627
695
|
resizeRatio={ align === 'center' ? 2 : 1 }
|
package/src/image/save.js
CHANGED
|
@@ -24,6 +24,8 @@ export default function save( { attributes } ) {
|
|
|
24
24
|
linkClass,
|
|
25
25
|
width,
|
|
26
26
|
height,
|
|
27
|
+
aspectRatio,
|
|
28
|
+
scale,
|
|
27
29
|
id,
|
|
28
30
|
linkTarget,
|
|
29
31
|
sizeSlug,
|
|
@@ -52,7 +54,11 @@ export default function save( { attributes } ) {
|
|
|
52
54
|
src={ url }
|
|
53
55
|
alt={ alt }
|
|
54
56
|
className={ imageClasses || undefined }
|
|
55
|
-
style={
|
|
57
|
+
style={ {
|
|
58
|
+
...borderProps.style,
|
|
59
|
+
aspectRatio,
|
|
60
|
+
objectFit: scale,
|
|
61
|
+
} }
|
|
56
62
|
width={ width }
|
|
57
63
|
height={ height }
|
|
58
64
|
title={ title }
|
package/src/image/utils.js
CHANGED
|
@@ -3,6 +3,22 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { NEW_TAB_REL } from './constants';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Evaluates a CSS aspect-ratio property value as a number.
|
|
8
|
+
*
|
|
9
|
+
* Degenerate or invalid ratios behave as 'auto'. And 'auto' ratios return NaN.
|
|
10
|
+
*
|
|
11
|
+
* @see https://drafts.csswg.org/css-sizing-4/#aspect-ratio
|
|
12
|
+
*
|
|
13
|
+
* @param {string} value CSS aspect-ratio property value.
|
|
14
|
+
* @return {number} Numerical aspect ratio or NaN if invalid.
|
|
15
|
+
*/
|
|
16
|
+
export function evalAspectRatio( value ) {
|
|
17
|
+
const [ width, height = 1 ] = value.split( '/' ).map( Number );
|
|
18
|
+
const aspectRatio = width / height;
|
|
19
|
+
return aspectRatio === Infinity || aspectRatio === 0 ? NaN : aspectRatio;
|
|
20
|
+
}
|
|
21
|
+
|
|
6
22
|
export function removeNewTabRel( currentRel ) {
|
|
7
23
|
let newRel = currentRel;
|
|
8
24
|
|
package/src/site-tagline/icon.js
CHANGED