@wordpress/block-library 8.12.15 → 8.12.17

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.
@@ -46,7 +46,19 @@ export default function FootnotesEdit( { context: { postType, postId } } ) {
46
46
  return (
47
47
  <ol { ...blockProps }>
48
48
  { footnotes.map( ( { id, content } ) => (
49
- <li key={ id }>
49
+ /* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */
50
+ <li
51
+ key={ id }
52
+ onMouseDown={ ( event ) => {
53
+ // When clicking on the list item (not on descendants),
54
+ // focus the rich text element since it's only 1px wide when
55
+ // empty.
56
+ if ( event.target === event.currentTarget ) {
57
+ event.target.firstElementChild.focus();
58
+ event.preventDefault();
59
+ }
60
+ } }
61
+ >
50
62
  <RichText
51
63
  id={ id }
52
64
  tagName="span"
@@ -37,6 +37,7 @@ export const format = {
37
37
  attributes: {
38
38
  'data-fn': 'data-fn',
39
39
  },
40
+ interactive: true,
40
41
  contentEditable: false,
41
42
  [ usesContextKey ]: [ 'postType' ],
42
43
  edit: function Edit( {
@@ -64,10 +64,10 @@
64
64
  "__experimentalRole": "content"
65
65
  },
66
66
  "width": {
67
- "type": "number"
67
+ "type": "string"
68
68
  },
69
69
  "height": {
70
- "type": "number"
70
+ "type": "string"
71
71
  },
72
72
  "aspectRatio": {
73
73
  "type": "string"
@@ -740,4 +740,211 @@ const v6 = {
740
740
  },
741
741
  };
742
742
 
743
- export default [ v6, v5, v4, v3, v2, v1 ];
743
+ /**
744
+ * Deprecation for converting to string width and height block attributes and
745
+ * removing the width and height img element attributes which are not needed
746
+ * as they get added by the TODO hook.
747
+ *
748
+ * @see https://github.com/WordPress/gutenberg/pull/53274
749
+ */
750
+ const v7 = {
751
+ attributes: {
752
+ align: {
753
+ type: 'string',
754
+ },
755
+ url: {
756
+ type: 'string',
757
+ source: 'attribute',
758
+ selector: 'img',
759
+ attribute: 'src',
760
+ __experimentalRole: 'content',
761
+ },
762
+ alt: {
763
+ type: 'string',
764
+ source: 'attribute',
765
+ selector: 'img',
766
+ attribute: 'alt',
767
+ default: '',
768
+ __experimentalRole: 'content',
769
+ },
770
+ caption: {
771
+ type: 'string',
772
+ source: 'html',
773
+ selector: 'figcaption',
774
+ __experimentalRole: 'content',
775
+ },
776
+ title: {
777
+ type: 'string',
778
+ source: 'attribute',
779
+ selector: 'img',
780
+ attribute: 'title',
781
+ __experimentalRole: 'content',
782
+ },
783
+ href: {
784
+ type: 'string',
785
+ source: 'attribute',
786
+ selector: 'figure > a',
787
+ attribute: 'href',
788
+ __experimentalRole: 'content',
789
+ },
790
+ rel: {
791
+ type: 'string',
792
+ source: 'attribute',
793
+ selector: 'figure > a',
794
+ attribute: 'rel',
795
+ },
796
+ linkClass: {
797
+ type: 'string',
798
+ source: 'attribute',
799
+ selector: 'figure > a',
800
+ attribute: 'class',
801
+ },
802
+ id: {
803
+ type: 'number',
804
+ __experimentalRole: 'content',
805
+ },
806
+ width: {
807
+ type: 'number',
808
+ },
809
+ height: {
810
+ type: 'number',
811
+ },
812
+ aspectRatio: {
813
+ type: 'string',
814
+ },
815
+ scale: {
816
+ type: 'string',
817
+ },
818
+ sizeSlug: {
819
+ type: 'string',
820
+ },
821
+ linkDestination: {
822
+ type: 'string',
823
+ },
824
+ linkTarget: {
825
+ type: 'string',
826
+ source: 'attribute',
827
+ selector: 'figure > a',
828
+ attribute: 'target',
829
+ },
830
+ },
831
+ supports: {
832
+ anchor: true,
833
+ behaviors: {
834
+ lightbox: true,
835
+ },
836
+ color: {
837
+ text: false,
838
+ background: false,
839
+ },
840
+ filter: {
841
+ duotone: true,
842
+ },
843
+ __experimentalBorder: {
844
+ color: true,
845
+ radius: true,
846
+ width: true,
847
+ __experimentalSkipSerialization: true,
848
+ __experimentalDefaultControls: {
849
+ color: true,
850
+ radius: true,
851
+ width: true,
852
+ },
853
+ },
854
+ },
855
+ migrate( { width, height, ...attributes } ) {
856
+ return {
857
+ ...attributes,
858
+ width: `${ width }px`,
859
+ height: `${ height }px`,
860
+ };
861
+ },
862
+ save( { attributes } ) {
863
+ const {
864
+ url,
865
+ alt,
866
+ caption,
867
+ align,
868
+ href,
869
+ rel,
870
+ linkClass,
871
+ width,
872
+ height,
873
+ aspectRatio,
874
+ scale,
875
+ id,
876
+ linkTarget,
877
+ sizeSlug,
878
+ title,
879
+ } = attributes;
880
+
881
+ const newRel = ! rel ? undefined : rel;
882
+ const borderProps = getBorderClassesAndStyles( attributes );
883
+
884
+ const classes = classnames( {
885
+ [ `align${ align }` ]: align,
886
+ [ `size-${ sizeSlug }` ]: sizeSlug,
887
+ 'is-resized': width || height,
888
+ 'has-custom-border':
889
+ !! borderProps.className ||
890
+ ( borderProps.style &&
891
+ Object.keys( borderProps.style ).length > 0 ),
892
+ } );
893
+
894
+ const imageClasses = classnames( borderProps.className, {
895
+ [ `wp-image-${ id }` ]: !! id,
896
+ } );
897
+
898
+ const image = (
899
+ <img
900
+ src={ url }
901
+ alt={ alt }
902
+ className={ imageClasses || undefined }
903
+ style={ {
904
+ ...borderProps.style,
905
+ aspectRatio,
906
+ objectFit: scale,
907
+ width,
908
+ height,
909
+ } }
910
+ width={ width }
911
+ height={ height }
912
+ title={ title }
913
+ />
914
+ );
915
+
916
+ const figure = (
917
+ <>
918
+ { href ? (
919
+ <a
920
+ className={ linkClass }
921
+ href={ href }
922
+ target={ linkTarget }
923
+ rel={ newRel }
924
+ >
925
+ { image }
926
+ </a>
927
+ ) : (
928
+ image
929
+ ) }
930
+ { ! RichText.isEmpty( caption ) && (
931
+ <RichText.Content
932
+ className={ __experimentalGetElementClassName(
933
+ 'caption'
934
+ ) }
935
+ tagName="figcaption"
936
+ value={ caption }
937
+ />
938
+ ) }
939
+ </>
940
+ );
941
+
942
+ return (
943
+ <figure { ...useBlockProps.save( { className: classes } ) }>
944
+ { figure }
945
+ </figure>
946
+ );
947
+ },
948
+ };
949
+
950
+ export default [ v7, v6, v5, v4, v3, v2, v1 ];
@@ -114,6 +114,11 @@ export default function Image( {
114
114
  linkTarget,
115
115
  sizeSlug,
116
116
  } = attributes;
117
+
118
+ // The only supported unit is px, so we can parseInt to strip the px here.
119
+ const numericWidth = width ? parseInt( width, 10 ) : undefined;
120
+ const numericHeight = height ? parseInt( height, 10 ) : undefined;
121
+
117
122
  const imageRef = useRef();
118
123
  const prevCaption = usePrevious( caption );
119
124
  const [ showCaption, setShowCaption ] = useState( !! caption );
@@ -321,7 +326,12 @@ export default function Image( {
321
326
 
322
327
  function updateAlignment( nextAlign ) {
323
328
  const extraUpdatedAttributes = [ 'wide', 'full' ].includes( nextAlign )
324
- ? { width: undefined, height: undefined }
329
+ ? {
330
+ width: undefined,
331
+ height: undefined,
332
+ aspectRatio: undefined,
333
+ scale: undefined,
334
+ }
325
335
  : {};
326
336
  setAttributes( {
327
337
  ...extraUpdatedAttributes,
@@ -472,33 +482,26 @@ export default function Image( {
472
482
  />
473
483
  </ToolsPanelItem>
474
484
  ) }
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
- />
485
+ { isResizable && (
486
+ <DimensionsTool
487
+ value={ { width, height, scale, aspectRatio } }
488
+ onChange={ ( newValue ) => {
489
+ // Rebuilding the object forces setting `undefined`
490
+ // for values that are removed since setAttributes
491
+ // doesn't do anything with keys that aren't set.
492
+ setAttributes( {
493
+ width: newValue.width,
494
+ height: newValue.height,
495
+ scale: newValue.scale,
496
+ aspectRatio: newValue.aspectRatio,
497
+ } );
498
+ } }
499
+ defaultScale="cover"
500
+ defaultAspectRatio="auto"
501
+ scaleOptions={ scaleOptions }
502
+ unitsOptions={ dimensionsUnitsOptions }
503
+ />
504
+ ) }
502
505
  <ResolutionTool
503
506
  value={ sizeSlug }
504
507
  onChange={ updateImage }
@@ -587,8 +590,8 @@ export default function Image( {
587
590
  <ImageEditor
588
591
  id={ id }
589
592
  url={ url }
590
- width={ width }
591
- height={ height }
593
+ width={ numericWidth }
594
+ height={ numericHeight }
592
595
  clientWidth={ fallbackClientWidth }
593
596
  naturalHeight={ naturalHeight }
594
597
  naturalWidth={ naturalWidth }
@@ -604,14 +607,18 @@ export default function Image( {
604
607
  } else if ( ! isResizable ) {
605
608
  img = <div style={ { width, height, aspectRatio } }>{ img }</div>;
606
609
  } else {
610
+ const numericRatio = aspectRatio && evalAspectRatio( aspectRatio );
611
+ const customRatio = numericWidth / numericHeight;
607
612
  const ratio =
608
- ( aspectRatio && evalAspectRatio( aspectRatio ) ) ||
609
- ( width && height && width / height ) ||
610
- naturalWidth / naturalHeight ||
611
- 1;
612
-
613
- const currentWidth = ! width && height ? height * ratio : width;
614
- const currentHeight = ! height && width ? width / ratio : height;
613
+ numericRatio || customRatio || naturalWidth / naturalHeight || 1;
614
+ const currentWidth =
615
+ ! numericWidth && numericHeight
616
+ ? numericHeight * ratio
617
+ : numericWidth;
618
+ const currentHeight =
619
+ ! numericHeight && numericWidth
620
+ ? numericWidth / ratio
621
+ : numericHeight;
615
622
 
616
623
  const minWidth =
617
624
  naturalWidth < naturalHeight ? MIN_SIZE : MIN_SIZE * ratio;
@@ -687,10 +694,14 @@ export default function Image( {
687
694
  onResizeStart={ onResizeStart }
688
695
  onResizeStop={ ( event, direction, elt ) => {
689
696
  onResizeStop();
697
+ // Since the aspect ratio is locked when resizing, we can
698
+ // use the width of the resized element to calculate the
699
+ // height in CSS to prevent stretching when the max-width
700
+ // is reached.
690
701
  setAttributes( {
691
- width: elt.offsetWidth,
692
- height: elt.offsetHeight,
693
- aspectRatio: undefined,
702
+ width: `${ elt.offsetWidth }px`,
703
+ height: 'auto',
704
+ aspectRatio: `${ ratio }`,
694
705
  } );
695
706
  } }
696
707
  resizeRatio={ align === 'center' ? 2 : 1 }
package/src/image/save.js CHANGED
@@ -61,8 +61,6 @@ export default function save( { attributes } ) {
61
61
  width,
62
62
  height,
63
63
  } }
64
- width={ width }
65
- height={ height }
66
64
  title={ title }
67
65
  />
68
66
  );