@wordpress/block-library 9.46.0 → 9.48.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 +8 -0
- package/build/button/edit.cjs +7 -4
- package/build/button/edit.cjs.map +3 -3
- package/build/columns/edit.cjs +4 -10
- package/build/columns/edit.cjs.map +2 -2
- package/build/cover/edit/inspector-controls.cjs +20 -6
- package/build/cover/edit/inspector-controls.cjs.map +2 -2
- package/build/freeform/migration-notice.cjs +1 -1
- package/build/freeform/migration-notice.cjs.map +1 -1
- package/build/home-link/block.json +7 -0
- package/build/home-link/edit.cjs +167 -24
- package/build/home-link/edit.cjs.map +3 -3
- package/build/html/edit.cjs +2 -4
- package/build/html/edit.cjs.map +2 -2
- package/build/html/modal.cjs +0 -4
- package/build/html/modal.cjs.map +2 -2
- package/build/image/block.json +4 -0
- package/build/image/deprecated.cjs +202 -4
- package/build/image/deprecated.cjs.map +3 -3
- package/build/image/image.cjs +94 -30
- package/build/image/image.cjs.map +2 -2
- package/build/image/index.cjs +23 -4
- package/build/image/index.cjs.map +2 -2
- package/build/image/save.cjs +25 -10
- package/build/image/save.cjs.map +2 -2
- package/build/image/transforms.cjs +15 -3
- package/build/image/transforms.cjs.map +2 -2
- package/build/image/use-open-image-media-editor-modal.cjs +37 -14
- package/build/image/use-open-image-media-editor-modal.cjs.map +2 -2
- package/build/list-item/hooks/use-enter.cjs +8 -4
- package/build/list-item/hooks/use-enter.cjs.map +3 -3
- package/build/list-item/hooks/use-space.cjs +8 -4
- package/build/list-item/hooks/use-space.cjs.map +3 -3
- package/build/navigation-link/edit.cjs +2 -1
- package/build/navigation-link/edit.cjs.map +2 -2
- package/build/navigation-link/shared/use-handle-link-change.cjs +19 -3
- package/build/navigation-link/shared/use-handle-link-change.cjs.map +3 -3
- package/build/navigation-submenu/edit.cjs +8 -22
- package/build/navigation-submenu/edit.cjs.map +2 -2
- package/build/paragraph/use-enter.cjs +8 -4
- package/build/paragraph/use-enter.cjs.map +3 -3
- package/build/post-date/edit.cjs +9 -1
- package/build/post-date/edit.cjs.map +2 -2
- package/build/post-featured-image/edit.cjs +6 -5
- package/build/post-featured-image/edit.cjs.map +2 -2
- package/build/site-logo/edit.cjs +5 -2
- package/build/site-logo/edit.cjs.map +2 -2
- package/build/social-link/edit.cjs.map +3 -3
- package/build/tab-list/edit.cjs +2 -0
- package/build/tab-list/edit.cjs.map +2 -2
- package/build/tab-panels/edit.cjs +5 -1
- package/build/tab-panels/edit.cjs.map +2 -2
- package/build/table/edit.cjs +1 -0
- package/build/table/edit.cjs.map +2 -2
- package/build/tabs/edit.cjs +1 -36
- package/build/tabs/edit.cjs.map +2 -2
- package/build-module/button/edit.mjs +12 -5
- package/build-module/button/edit.mjs.map +2 -2
- package/build-module/columns/edit.mjs +4 -10
- package/build-module/columns/edit.mjs.map +2 -2
- package/build-module/cover/edit/inspector-controls.mjs +20 -7
- package/build-module/cover/edit/inspector-controls.mjs.map +2 -2
- package/build-module/freeform/migration-notice.mjs +1 -1
- package/build-module/freeform/migration-notice.mjs.map +1 -1
- package/build-module/home-link/block.json +7 -0
- package/build-module/home-link/edit.mjs +181 -26
- package/build-module/home-link/edit.mjs.map +2 -2
- package/build-module/html/edit.mjs +2 -4
- package/build-module/html/edit.mjs.map +2 -2
- package/build-module/html/modal.mjs +0 -4
- package/build-module/html/modal.mjs.map +2 -2
- package/build-module/image/block.json +4 -0
- package/build-module/image/deprecated.mjs +204 -5
- package/build-module/image/deprecated.mjs.map +2 -2
- package/build-module/image/image.mjs +96 -30
- package/build-module/image/image.mjs.map +2 -2
- package/build-module/image/index.mjs +23 -4
- package/build-module/image/index.mjs.map +2 -2
- package/build-module/image/save.mjs +25 -10
- package/build-module/image/save.mjs.map +2 -2
- package/build-module/image/transforms.mjs +15 -3
- package/build-module/image/transforms.mjs.map +2 -2
- package/build-module/image/use-open-image-media-editor-modal.mjs +37 -14
- package/build-module/image/use-open-image-media-editor-modal.mjs.map +2 -2
- package/build-module/list-item/hooks/use-enter.mjs +12 -5
- package/build-module/list-item/hooks/use-enter.mjs.map +2 -2
- package/build-module/list-item/hooks/use-space.mjs +12 -5
- package/build-module/list-item/hooks/use-space.mjs.map +2 -2
- package/build-module/navigation-link/edit.mjs +2 -1
- package/build-module/navigation-link/edit.mjs.map +2 -2
- package/build-module/navigation-link/shared/use-handle-link-change.mjs +19 -3
- package/build-module/navigation-link/shared/use-handle-link-change.mjs.map +2 -2
- package/build-module/navigation-submenu/edit.mjs +9 -23
- package/build-module/navigation-submenu/edit.mjs.map +2 -2
- package/build-module/paragraph/use-enter.mjs +12 -5
- package/build-module/paragraph/use-enter.mjs.map +2 -2
- package/build-module/post-date/edit.mjs +9 -1
- package/build-module/post-date/edit.mjs.map +2 -2
- package/build-module/post-featured-image/edit.mjs +6 -5
- package/build-module/post-featured-image/edit.mjs.map +2 -2
- package/build-module/site-logo/edit.mjs +6 -2
- package/build-module/site-logo/edit.mjs.map +2 -2
- package/build-module/social-link/edit.mjs +2 -2
- package/build-module/social-link/edit.mjs.map +2 -2
- package/build-module/tab-list/edit.mjs +2 -0
- package/build-module/tab-list/edit.mjs.map +2 -2
- package/build-module/tab-panels/edit.mjs +5 -1
- package/build-module/tab-panels/edit.mjs.map +2 -2
- package/build-module/table/edit.mjs +1 -0
- package/build-module/table/edit.mjs.map +2 -2
- package/build-module/tabs/edit.mjs +2 -37
- package/build-module/tabs/edit.mjs.map +2 -2
- package/build-style/breadcrumbs/style-rtl.css +1 -1
- package/build-style/breadcrumbs/style.css +1 -1
- package/build-style/editor-rtl.css +0 -11
- package/build-style/editor.css +0 -11
- package/build-style/gallery/editor-rtl.css +0 -11
- package/build-style/gallery/editor.css +0 -11
- package/build-style/style-rtl.css +1 -1
- package/build-style/style.css +1 -1
- package/package.json +40 -40
- package/src/block/edit-title.native.js +3 -3
- package/src/block/edit.native.js +2 -2
- package/src/breadcrumbs/style.scss +1 -1
- package/src/button/edit.js +14 -5
- package/src/columns/edit.js +3 -9
- package/src/cover/controls.native.js +2 -2
- package/src/cover/edit/inspector-controls.js +69 -52
- package/src/cover/edit.native.js +6 -4
- package/src/cover/focal-point-settings-button.native.js +2 -2
- package/src/cover/test/edit.js +70 -31
- package/src/embed/embed-no-preview.native.js +7 -3
- package/src/embed/embed-placeholder.native.js +2 -2
- package/src/file/edit.native.js +2 -2
- package/src/freeform/migration-notice.js +1 -1
- package/src/gallery/editor.scss +0 -14
- package/src/home-link/block.json +7 -0
- package/src/home-link/edit.js +185 -22
- package/src/home-link/index.php +14 -2
- package/src/html/edit.js +14 -12
- package/src/html/modal.js +0 -5
- package/src/image/block.json +4 -0
- package/src/image/deprecated.js +236 -4
- package/src/image/edit.native.js +2 -2
- package/src/image/image.js +166 -76
- package/src/image/index.js +20 -1
- package/src/image/index.php +1 -1
- package/src/image/save.js +39 -12
- package/src/image/test/use-open-image-media-editor-modal.js +101 -0
- package/src/image/transforms.js +21 -5
- package/src/image/use-open-image-media-editor-modal.js +41 -17
- package/src/latest-posts/edit.native.js +2 -2
- package/src/list-item/hooks/use-enter.js +15 -5
- package/src/list-item/hooks/use-space.js +15 -5
- package/src/list-item/list-style-type.native.js +2 -2
- package/src/media-text/media-container.native.js +7 -3
- package/src/missing/edit.native.js +4 -4
- package/src/missing/test/edit.native.js +3 -3
- package/src/navigation/test/use-navigation-menu.js +8 -2
- package/src/navigation-link/edit.js +1 -0
- package/src/navigation-link/shared/test/use-handle-link-change.test.js +212 -0
- package/src/navigation-link/shared/use-handle-link-change.js +36 -9
- package/src/navigation-submenu/edit.js +11 -28
- package/src/navigation-submenu/index.php +13 -0
- package/src/paragraph/use-enter.js +19 -5
- package/src/post-date/edit.js +7 -3
- package/src/post-featured-image/edit.js +15 -11
- package/src/search/edit.native.js +2 -2
- package/src/search/test/edit.native.js +2 -2
- package/src/site-logo/edit.js +7 -1
- package/src/social-link/edit.js +2 -2
- package/src/tab-list/edit.js +3 -0
- package/src/tab-panels/edit.js +10 -1
- package/src/table/edit.js +1 -0
- package/src/tabs/edit.js +14 -42
- package/src/video/edit.native.js +3 -3
|
@@ -423,6 +423,51 @@ describe( 'useHandleLinkChange', () => {
|
|
|
423
423
|
} )
|
|
424
424
|
);
|
|
425
425
|
} );
|
|
426
|
+
|
|
427
|
+
it( 'should update text when editing text and changing a bound entity link to a custom URL in the link editing UI', () => {
|
|
428
|
+
useEntityBinding.mockReturnValue( {
|
|
429
|
+
hasUrlBinding: true,
|
|
430
|
+
createBinding: mockCreateBinding,
|
|
431
|
+
clearBinding: mockClearBinding,
|
|
432
|
+
} );
|
|
433
|
+
|
|
434
|
+
const attributes = {
|
|
435
|
+
id: 456,
|
|
436
|
+
url: 'https://example.com/my-page',
|
|
437
|
+
label: 'My Page',
|
|
438
|
+
kind: 'post-type',
|
|
439
|
+
type: 'page',
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
const { result } = renderHook( () =>
|
|
443
|
+
useHandleLinkChange( {
|
|
444
|
+
clientId,
|
|
445
|
+
attributes,
|
|
446
|
+
setAttributes: mockSetAttributes,
|
|
447
|
+
allowTextUpdate: true,
|
|
448
|
+
} )
|
|
449
|
+
);
|
|
450
|
+
|
|
451
|
+
const updatedLink = {
|
|
452
|
+
url: 'https://external-site.com',
|
|
453
|
+
title: 'Updated Navigation Text',
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
result.current( updatedLink );
|
|
457
|
+
|
|
458
|
+
expect( mockClearBinding ).toHaveBeenCalled();
|
|
459
|
+
expect( mockUpdateBlockAttributes ).toHaveBeenCalledWith(
|
|
460
|
+
clientId,
|
|
461
|
+
expect.objectContaining( {
|
|
462
|
+
url: 'https://external-site.com',
|
|
463
|
+
kind: 'custom',
|
|
464
|
+
type: 'custom',
|
|
465
|
+
id: undefined,
|
|
466
|
+
label: 'Updated Navigation Text',
|
|
467
|
+
} )
|
|
468
|
+
);
|
|
469
|
+
expect( updateAttributes ).not.toHaveBeenCalled();
|
|
470
|
+
} );
|
|
426
471
|
} );
|
|
427
472
|
|
|
428
473
|
describe( 'updating existing links', () => {
|
|
@@ -503,6 +548,87 @@ describe( 'useHandleLinkChange', () => {
|
|
|
503
548
|
);
|
|
504
549
|
} );
|
|
505
550
|
|
|
551
|
+
it( 'should preserve label when changing the link without editing text in the link editing UI', () => {
|
|
552
|
+
const attributes = {
|
|
553
|
+
id: 123,
|
|
554
|
+
url: 'https://example.com/page',
|
|
555
|
+
label: 'Custom Label',
|
|
556
|
+
kind: 'post-type',
|
|
557
|
+
type: 'page',
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
const { result } = renderHook( () =>
|
|
561
|
+
useHandleLinkChange( {
|
|
562
|
+
clientId,
|
|
563
|
+
attributes,
|
|
564
|
+
setAttributes: mockSetAttributes,
|
|
565
|
+
allowTextUpdate: true,
|
|
566
|
+
} )
|
|
567
|
+
);
|
|
568
|
+
|
|
569
|
+
const updatedLink = {
|
|
570
|
+
id: 456,
|
|
571
|
+
url: 'https://example.com/new-page',
|
|
572
|
+
title: 'Custom Label',
|
|
573
|
+
kind: 'post-type',
|
|
574
|
+
type: 'page',
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
result.current( updatedLink );
|
|
578
|
+
|
|
579
|
+
expect( updateAttributes ).toHaveBeenCalledWith(
|
|
580
|
+
expect.not.objectContaining( {
|
|
581
|
+
title: 'Custom Label',
|
|
582
|
+
} ),
|
|
583
|
+
mockSetAttributes,
|
|
584
|
+
attributes
|
|
585
|
+
);
|
|
586
|
+
expect( mockUpdateBlockAttributes ).not.toHaveBeenCalled();
|
|
587
|
+
} );
|
|
588
|
+
|
|
589
|
+
it( 'should include title when editing text and changing the entity link in the link editing UI', () => {
|
|
590
|
+
const attributes = {
|
|
591
|
+
id: 123,
|
|
592
|
+
url: 'https://example.com/page',
|
|
593
|
+
label: 'Sample Page',
|
|
594
|
+
kind: 'post-type',
|
|
595
|
+
type: 'page',
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
const { result } = renderHook( () =>
|
|
599
|
+
useHandleLinkChange( {
|
|
600
|
+
clientId,
|
|
601
|
+
attributes,
|
|
602
|
+
setAttributes: mockSetAttributes,
|
|
603
|
+
allowTextUpdate: true,
|
|
604
|
+
} )
|
|
605
|
+
);
|
|
606
|
+
|
|
607
|
+
const updatedLink = {
|
|
608
|
+
id: 456,
|
|
609
|
+
url: 'https://example.com/new-page',
|
|
610
|
+
title: 'Updated Navigation Text',
|
|
611
|
+
kind: 'post-type',
|
|
612
|
+
type: 'page',
|
|
613
|
+
};
|
|
614
|
+
|
|
615
|
+
result.current( updatedLink );
|
|
616
|
+
|
|
617
|
+
expect( updateAttributes ).toHaveBeenCalledWith(
|
|
618
|
+
expect.objectContaining( {
|
|
619
|
+
title: 'Updated Navigation Text',
|
|
620
|
+
} ),
|
|
621
|
+
mockSetAttributes,
|
|
622
|
+
attributes
|
|
623
|
+
);
|
|
624
|
+
expect( mockUpdateBlockAttributes ).toHaveBeenCalledWith(
|
|
625
|
+
clientId,
|
|
626
|
+
{
|
|
627
|
+
label: 'Updated Navigation Text',
|
|
628
|
+
}
|
|
629
|
+
);
|
|
630
|
+
} );
|
|
631
|
+
|
|
506
632
|
it( 'should include title when creating link without existing label', () => {
|
|
507
633
|
const attributes = {};
|
|
508
634
|
|
|
@@ -606,6 +732,92 @@ describe( 'useHandleLinkChange', () => {
|
|
|
606
732
|
);
|
|
607
733
|
} );
|
|
608
734
|
|
|
735
|
+
it( 'should include title when editing text for the same existing entity link', () => {
|
|
736
|
+
const attributes = {
|
|
737
|
+
id: 123,
|
|
738
|
+
url: 'https://example.com/page',
|
|
739
|
+
label: 'Sample Page',
|
|
740
|
+
kind: 'post-type',
|
|
741
|
+
type: 'page',
|
|
742
|
+
};
|
|
743
|
+
|
|
744
|
+
const { result } = renderHook( () =>
|
|
745
|
+
useHandleLinkChange( {
|
|
746
|
+
clientId,
|
|
747
|
+
attributes,
|
|
748
|
+
setAttributes: mockSetAttributes,
|
|
749
|
+
allowTextUpdate: true,
|
|
750
|
+
} )
|
|
751
|
+
);
|
|
752
|
+
|
|
753
|
+
const updatedLink = {
|
|
754
|
+
id: 123,
|
|
755
|
+
url: 'https://example.com/page',
|
|
756
|
+
title: 'Updated Sample Page',
|
|
757
|
+
kind: 'post-type',
|
|
758
|
+
type: 'page',
|
|
759
|
+
};
|
|
760
|
+
|
|
761
|
+
result.current( updatedLink );
|
|
762
|
+
|
|
763
|
+
expect( updateAttributes ).toHaveBeenCalledWith(
|
|
764
|
+
expect.objectContaining( {
|
|
765
|
+
title: 'Updated Sample Page',
|
|
766
|
+
} ),
|
|
767
|
+
mockSetAttributes,
|
|
768
|
+
attributes
|
|
769
|
+
);
|
|
770
|
+
expect( mockUpdateBlockAttributes ).toHaveBeenCalledWith(
|
|
771
|
+
clientId,
|
|
772
|
+
{
|
|
773
|
+
label: 'Updated Sample Page',
|
|
774
|
+
}
|
|
775
|
+
);
|
|
776
|
+
} );
|
|
777
|
+
|
|
778
|
+
it( 'should clear text when the inline link editing UI title is emptied', () => {
|
|
779
|
+
const attributes = {
|
|
780
|
+
id: 123,
|
|
781
|
+
url: 'https://example.com/page',
|
|
782
|
+
label: 'Sample Page',
|
|
783
|
+
kind: 'post-type',
|
|
784
|
+
type: 'page',
|
|
785
|
+
};
|
|
786
|
+
|
|
787
|
+
const { result } = renderHook( () =>
|
|
788
|
+
useHandleLinkChange( {
|
|
789
|
+
clientId,
|
|
790
|
+
attributes,
|
|
791
|
+
setAttributes: mockSetAttributes,
|
|
792
|
+
allowTextUpdate: true,
|
|
793
|
+
} )
|
|
794
|
+
);
|
|
795
|
+
|
|
796
|
+
const updatedLink = {
|
|
797
|
+
id: 123,
|
|
798
|
+
url: 'https://example.com/page',
|
|
799
|
+
title: '',
|
|
800
|
+
kind: 'post-type',
|
|
801
|
+
type: 'page',
|
|
802
|
+
};
|
|
803
|
+
|
|
804
|
+
result.current( updatedLink );
|
|
805
|
+
|
|
806
|
+
expect( updateAttributes ).toHaveBeenCalledWith(
|
|
807
|
+
expect.objectContaining( {
|
|
808
|
+
title: '',
|
|
809
|
+
} ),
|
|
810
|
+
mockSetAttributes,
|
|
811
|
+
attributes
|
|
812
|
+
);
|
|
813
|
+
expect( mockUpdateBlockAttributes ).toHaveBeenCalledWith(
|
|
814
|
+
clientId,
|
|
815
|
+
{
|
|
816
|
+
label: '',
|
|
817
|
+
}
|
|
818
|
+
);
|
|
819
|
+
} );
|
|
820
|
+
|
|
609
821
|
it( 'should update custom link to another custom link', () => {
|
|
610
822
|
updateAttributes.mockImplementation( ( attrs ) => ( {
|
|
611
823
|
isEntityLink: false,
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
import { useCallback } from '@wordpress/element';
|
|
5
5
|
import { useDispatch } from '@wordpress/data';
|
|
6
6
|
import { store as blockEditorStore } from '@wordpress/block-editor';
|
|
7
|
+
import { __unstableStripHTML as stripHTML } from '@wordpress/dom';
|
|
8
|
+
import { escapeHTML } from '@wordpress/escape-html';
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Internal dependencies
|
|
@@ -16,13 +18,19 @@ import { useEntityBinding } from './use-entity-binding';
|
|
|
16
18
|
* Manages the transition between entity links and custom links,
|
|
17
19
|
* including proper binding creation and cleanup.
|
|
18
20
|
*
|
|
19
|
-
* @param {Object} options
|
|
20
|
-
* @param {string} options.clientId
|
|
21
|
-
* @param {Object} options.attributes
|
|
22
|
-
* @param {Function} options.setAttributes
|
|
21
|
+
* @param {Object} options - Configuration options
|
|
22
|
+
* @param {string} options.clientId - Block client ID
|
|
23
|
+
* @param {Object} options.attributes - Current block attributes
|
|
24
|
+
* @param {Function} options.setAttributes - Standard setAttribute function
|
|
25
|
+
* @param {boolean} options.allowTextUpdate - Whether this control can update the link text
|
|
23
26
|
* @return {Function} Callback function to handle link changes
|
|
24
27
|
*/
|
|
25
|
-
export function useHandleLinkChange( {
|
|
28
|
+
export function useHandleLinkChange( {
|
|
29
|
+
clientId,
|
|
30
|
+
attributes,
|
|
31
|
+
setAttributes,
|
|
32
|
+
allowTextUpdate = false,
|
|
33
|
+
} ) {
|
|
26
34
|
const { updateBlockAttributes } = useDispatch( blockEditorStore );
|
|
27
35
|
const { hasUrlBinding, createBinding, clearBinding } = useEntityBinding( {
|
|
28
36
|
clientId,
|
|
@@ -42,12 +50,25 @@ export function useHandleLinkChange( { clientId, attributes, setAttributes } ) {
|
|
|
42
50
|
id: updatedLink.id,
|
|
43
51
|
};
|
|
44
52
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
53
|
+
const currentText = attributes.label
|
|
54
|
+
? stripHTML( attributes.label )
|
|
55
|
+
: '';
|
|
56
|
+
const updatedText = updatedLink.title ?? '';
|
|
57
|
+
const hasTextUpdate =
|
|
58
|
+
allowTextUpdate &&
|
|
59
|
+
updatedLink.title !== undefined &&
|
|
60
|
+
updatedText !== currentText;
|
|
61
|
+
const textUpdateAttributes = hasTextUpdate
|
|
62
|
+
? { label: escapeHTML( updatedText ) }
|
|
63
|
+
: {};
|
|
64
|
+
|
|
65
|
+
if (
|
|
66
|
+
! attributes.label ||
|
|
67
|
+
attributes.label === '' ||
|
|
68
|
+
hasTextUpdate
|
|
69
|
+
) {
|
|
48
70
|
attrs.title = updatedLink.title;
|
|
49
71
|
}
|
|
50
|
-
|
|
51
72
|
// Check if transitioning from entity to custom link
|
|
52
73
|
const willBeCustomLink = ! updatedLink.id && hasUrlBinding;
|
|
53
74
|
|
|
@@ -62,6 +83,7 @@ export function useHandleLinkChange( { clientId, attributes, setAttributes } ) {
|
|
|
62
83
|
kind: 'custom',
|
|
63
84
|
type: 'custom',
|
|
64
85
|
id: undefined,
|
|
86
|
+
...textUpdateAttributes,
|
|
65
87
|
} );
|
|
66
88
|
} else {
|
|
67
89
|
// Normal flow for entity links or unbound custom links
|
|
@@ -76,10 +98,15 @@ export function useHandleLinkChange( { clientId, attributes, setAttributes } ) {
|
|
|
76
98
|
} else {
|
|
77
99
|
clearBinding();
|
|
78
100
|
}
|
|
101
|
+
|
|
102
|
+
if ( Object.keys( textUpdateAttributes ).length ) {
|
|
103
|
+
updateBlockAttributes( clientId, textUpdateAttributes );
|
|
104
|
+
}
|
|
79
105
|
}
|
|
80
106
|
},
|
|
81
107
|
[
|
|
82
108
|
attributes,
|
|
109
|
+
allowTextUpdate,
|
|
83
110
|
clientId,
|
|
84
111
|
hasUrlBinding,
|
|
85
112
|
createBinding,
|
|
@@ -35,8 +35,8 @@ import { ItemSubmenuIcon } from './icons';
|
|
|
35
35
|
import {
|
|
36
36
|
Controls,
|
|
37
37
|
LinkUI,
|
|
38
|
-
updateAttributes,
|
|
39
38
|
useEntityBinding,
|
|
39
|
+
useHandleLinkChange,
|
|
40
40
|
useIsInvalidLink,
|
|
41
41
|
InvalidDraftDisplay,
|
|
42
42
|
useEnableLinkStatusValidation,
|
|
@@ -92,15 +92,17 @@ export default function NavigationSubmenuEdit( {
|
|
|
92
92
|
blockEditingMode !== 'default' ? true : submenuVisibility === 'click';
|
|
93
93
|
|
|
94
94
|
// URL binding logic
|
|
95
|
-
const {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
95
|
+
const { hasUrlBinding, isBoundEntityAvailable, entityRecord } =
|
|
96
|
+
useEntityBinding( {
|
|
97
|
+
clientId,
|
|
98
|
+
attributes,
|
|
99
|
+
} );
|
|
100
|
+
|
|
101
|
+
const handleLinkChange = useHandleLinkChange( {
|
|
102
102
|
clientId,
|
|
103
103
|
attributes,
|
|
104
|
+
setAttributes,
|
|
105
|
+
allowTextUpdate: true,
|
|
104
106
|
} );
|
|
105
107
|
|
|
106
108
|
const { __unstableMarkNextChangeAsNotPersistent, replaceBlock } =
|
|
@@ -398,26 +400,7 @@ export default function NavigationSubmenuEdit( {
|
|
|
398
400
|
setAttributes( { url: '' } );
|
|
399
401
|
speak( __( 'Link removed.' ), 'assertive' );
|
|
400
402
|
} }
|
|
401
|
-
onChange={
|
|
402
|
-
// updateAttributes determines the final state and returns metadata
|
|
403
|
-
const {
|
|
404
|
-
isEntityLink,
|
|
405
|
-
attributes: updatedAttributes,
|
|
406
|
-
} = updateAttributes(
|
|
407
|
-
updatedValue,
|
|
408
|
-
setAttributes,
|
|
409
|
-
attributes
|
|
410
|
-
);
|
|
411
|
-
|
|
412
|
-
// Handle URL binding based on the final computed state
|
|
413
|
-
// Only create bindings for entity links (posts, pages, taxonomies)
|
|
414
|
-
// Never create bindings for custom links (manual URLs)
|
|
415
|
-
if ( isEntityLink ) {
|
|
416
|
-
createBinding( updatedAttributes );
|
|
417
|
-
} else {
|
|
418
|
-
clearBinding();
|
|
419
|
-
}
|
|
420
|
-
} }
|
|
403
|
+
onChange={ handleLinkChange }
|
|
421
404
|
/>
|
|
422
405
|
) }
|
|
423
406
|
</ParentElement>
|
|
@@ -9,6 +9,19 @@ require_once __DIR__ . '/navigation-link/shared/item-should-render.php';
|
|
|
9
9
|
require_once __DIR__ . '/navigation-link/shared/render-submenu-icon.php';
|
|
10
10
|
require_once __DIR__ . '/navigation-link/shared/build-css-font-sizes.php';
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Renders the submenu icon SVG for the Navigation Submenu block.
|
|
14
|
+
*
|
|
15
|
+
* @since 5.9.0
|
|
16
|
+
* @deprecated 7.0.0 Use block_core_shared_navigation_render_submenu_icon() instead.
|
|
17
|
+
*
|
|
18
|
+
* @return string SVG markup for the submenu icon.
|
|
19
|
+
*/
|
|
20
|
+
function block_core_navigation_submenu_render_submenu_icon() {
|
|
21
|
+
_deprecated_function( __FUNCTION__, '7.0.0', 'block_core_shared_navigation_render_submenu_icon()' );
|
|
22
|
+
return block_core_shared_navigation_render_submenu_icon();
|
|
23
|
+
}
|
|
24
|
+
|
|
12
25
|
/**
|
|
13
26
|
* Returns the submenu visibility value with backward compatibility
|
|
14
27
|
* for the deprecated openSubmenusOnClick attribute.
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { useRef } from '@wordpress/element';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
useRefEffect,
|
|
7
|
+
privateApis as composePrivateApis,
|
|
8
|
+
} from '@wordpress/compose';
|
|
6
9
|
import { ENTER } from '@wordpress/keycodes';
|
|
7
10
|
import { useSelect, useDispatch, useRegistry } from '@wordpress/data';
|
|
8
11
|
import { store as blockEditorStore } from '@wordpress/block-editor';
|
|
@@ -13,6 +16,13 @@ import {
|
|
|
13
16
|
getDefaultBlockName,
|
|
14
17
|
} from '@wordpress/blocks';
|
|
15
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Internal dependencies
|
|
21
|
+
*/
|
|
22
|
+
import { unlock } from '../lock-unlock';
|
|
23
|
+
|
|
24
|
+
const { subscribeDelegatedListener } = unlock( composePrivateApis );
|
|
25
|
+
|
|
16
26
|
export function useOnEnter( props ) {
|
|
17
27
|
const { batch } = useRegistry();
|
|
18
28
|
const { moveBlocksToPosition, replaceBlocks, selectionChange } =
|
|
@@ -119,9 +129,13 @@ export function useOnEnter( props ) {
|
|
|
119
129
|
} );
|
|
120
130
|
}
|
|
121
131
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
132
|
+
// Capture phase so we run before writing-flow's ancestor-bubble
|
|
133
|
+
// keydown handlers that gate on `event.defaultPrevented`.
|
|
134
|
+
return subscribeDelegatedListener(
|
|
135
|
+
element,
|
|
136
|
+
'keydown',
|
|
137
|
+
onKeyDown,
|
|
138
|
+
true
|
|
139
|
+
);
|
|
126
140
|
}, [] );
|
|
127
141
|
}
|
package/src/post-date/edit.js
CHANGED
|
@@ -99,11 +99,15 @@ export default function PostDateEdit( props ) {
|
|
|
99
99
|
|
|
100
100
|
const blockEditingMode = useBlockEditingMode();
|
|
101
101
|
|
|
102
|
+
const validDatetime = datetime || new Date();
|
|
102
103
|
let postDate = (
|
|
103
|
-
<time
|
|
104
|
+
<time
|
|
105
|
+
dateTime={ dateI18n( 'c', validDatetime ) }
|
|
106
|
+
ref={ setPopoverAnchor }
|
|
107
|
+
>
|
|
104
108
|
{ format === 'human-diff'
|
|
105
|
-
? humanTimeDiff(
|
|
106
|
-
: dateI18n( format || siteFormat,
|
|
109
|
+
? humanTimeDiff( validDatetime )
|
|
110
|
+
: dateI18n( format || siteFormat, validDatetime ) }
|
|
107
111
|
</time>
|
|
108
112
|
);
|
|
109
113
|
|
|
@@ -137,10 +137,12 @@ export default function PostFeaturedImageEdit( {
|
|
|
137
137
|
return imageId;
|
|
138
138
|
}, [ storedFeaturedImage, useFirstImageFromPost, postContent ] );
|
|
139
139
|
|
|
140
|
-
const { media, postType, postPermalink } = useSelect(
|
|
140
|
+
const { media, postType, postPermalink, hasSelectedStyleState } = useSelect(
|
|
141
141
|
( select ) => {
|
|
142
142
|
const { getEntityRecord, getPostType, getEditedEntityRecord } =
|
|
143
143
|
select( coreStore );
|
|
144
|
+
const { hasSelectedStyleState: hasSelectedBlockStyleState } =
|
|
145
|
+
unlock( select( blockEditorStore ) );
|
|
144
146
|
return {
|
|
145
147
|
media:
|
|
146
148
|
featuredImage &&
|
|
@@ -153,9 +155,10 @@ export default function PostFeaturedImageEdit( {
|
|
|
153
155
|
postTypeSlug,
|
|
154
156
|
postId
|
|
155
157
|
)?.link,
|
|
158
|
+
hasSelectedStyleState: hasSelectedBlockStyleState( clientId ),
|
|
156
159
|
};
|
|
157
160
|
},
|
|
158
|
-
[ featuredImage, postTypeSlug, postId ]
|
|
161
|
+
[ clientId, featuredImage, postTypeSlug, postId ]
|
|
159
162
|
);
|
|
160
163
|
|
|
161
164
|
const mediaUrl =
|
|
@@ -237,14 +240,16 @@ export default function PostFeaturedImageEdit( {
|
|
|
237
240
|
clientId={ clientId }
|
|
238
241
|
/>
|
|
239
242
|
</InspectorControls>
|
|
240
|
-
|
|
241
|
-
<
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
243
|
+
{ ! hasSelectedStyleState && (
|
|
244
|
+
<InspectorControls group="dimensions">
|
|
245
|
+
<DimensionControls
|
|
246
|
+
clientId={ clientId }
|
|
247
|
+
attributes={ attributes }
|
|
248
|
+
setAttributes={ setAttributes }
|
|
249
|
+
media={ media }
|
|
250
|
+
/>
|
|
251
|
+
</InspectorControls>
|
|
252
|
+
) }
|
|
248
253
|
{ ( featuredImage || isDescendentOfQueryLoop || ! postId ) && (
|
|
249
254
|
<InspectorControls>
|
|
250
255
|
<ToolsPanel
|
|
@@ -278,7 +283,6 @@ export default function PostFeaturedImageEdit( {
|
|
|
278
283
|
}
|
|
279
284
|
>
|
|
280
285
|
<ToggleControl
|
|
281
|
-
__nextHasNoMarginBottom
|
|
282
286
|
label={ __( 'Make image a link' ) }
|
|
283
287
|
onChange={ () =>
|
|
284
288
|
setAttributes( { isLink: ! isLink } )
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
PanelBody,
|
|
18
18
|
SelectControl,
|
|
19
19
|
ToggleControl,
|
|
20
|
-
Icon,
|
|
20
|
+
Icon as WCIcon,
|
|
21
21
|
} from '@wordpress/components';
|
|
22
22
|
import { __ } from '@wordpress/i18n';
|
|
23
23
|
import { search } from '@wordpress/icons';
|
|
@@ -374,7 +374,7 @@ export default function SearchEdit( {
|
|
|
374
374
|
return (
|
|
375
375
|
<View style={ richTextButtonContainerStyle }>
|
|
376
376
|
{ buttonUseIcon && (
|
|
377
|
-
<
|
|
377
|
+
<WCIcon
|
|
378
378
|
icon={ search }
|
|
379
379
|
{ ...iconStyles }
|
|
380
380
|
onLayout={ onLayoutButton }
|
|
@@ -6,7 +6,7 @@ import { render } from 'test/helpers';
|
|
|
6
6
|
/**
|
|
7
7
|
* WordPress dependencies
|
|
8
8
|
*/
|
|
9
|
-
import { Icon } from '@wordpress/components';
|
|
9
|
+
import { Icon as WCIcon } from '@wordpress/components';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Internal dependencies
|
|
@@ -129,7 +129,7 @@ describe( 'Search Block', () => {
|
|
|
129
129
|
} );
|
|
130
130
|
|
|
131
131
|
it( 'search button uses icon', () => {
|
|
132
|
-
const button = instance.UNSAFE_getByType(
|
|
132
|
+
const button = instance.UNSAFE_getByType( WCIcon );
|
|
133
133
|
expect( button ).toBeTruthy();
|
|
134
134
|
} );
|
|
135
135
|
|
package/src/site-logo/edit.js
CHANGED
|
@@ -10,6 +10,7 @@ import { isBlobURL } from '@wordpress/blob';
|
|
|
10
10
|
import {
|
|
11
11
|
createInterpolateElement,
|
|
12
12
|
useEffect,
|
|
13
|
+
useRef,
|
|
13
14
|
useState,
|
|
14
15
|
} from '@wordpress/element';
|
|
15
16
|
import { __, isRTL } from '@wordpress/i18n';
|
|
@@ -73,6 +74,7 @@ const SiteLogo = ( {
|
|
|
73
74
|
const isResizable = ! isWideAligned && isLargeViewport;
|
|
74
75
|
const [ { naturalWidth, naturalHeight }, setNaturalSize ] = useState( {} );
|
|
75
76
|
const [ isEditingImage, setIsEditingImage ] = useState( false );
|
|
77
|
+
const cropButtonRef = useRef();
|
|
76
78
|
const { toggleSelection } = useDispatch( blockEditorStore );
|
|
77
79
|
const dropdownMenuProps = useToolsPanelDropdownMenuProps();
|
|
78
80
|
|
|
@@ -116,8 +118,9 @@ const SiteLogo = ( {
|
|
|
116
118
|
}
|
|
117
119
|
}, [ isSelected ] );
|
|
118
120
|
|
|
121
|
+
// Always apply modal updates as snackbar Undo may restore the original id.
|
|
119
122
|
const handleMediaUpdate = ( { id: newId } ) => {
|
|
120
|
-
if ( typeof newId === 'number'
|
|
123
|
+
if ( typeof newId === 'number' ) {
|
|
121
124
|
setLogo( newId );
|
|
122
125
|
}
|
|
123
126
|
};
|
|
@@ -400,12 +403,15 @@ const SiteLogo = ( {
|
|
|
400
403
|
shouldShowCropAndDimensions && (
|
|
401
404
|
<BlockControls group="block">
|
|
402
405
|
<ToolbarButton
|
|
406
|
+
ref={ cropButtonRef }
|
|
403
407
|
onClick={
|
|
404
408
|
openMediaEditorModal && logoId
|
|
405
409
|
? () =>
|
|
406
410
|
openMediaEditorModal( {
|
|
407
411
|
id: logoId,
|
|
408
412
|
onUpdate: handleMediaUpdate,
|
|
413
|
+
onClose: () =>
|
|
414
|
+
cropButtonRef.current?.focus(),
|
|
409
415
|
} )
|
|
410
416
|
: () => setIsEditingImage( true )
|
|
411
417
|
}
|
package/src/social-link/edit.js
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
} from '@wordpress/block-editor';
|
|
20
20
|
import { useState, useRef, createInterpolateElement } from '@wordpress/element';
|
|
21
21
|
import {
|
|
22
|
-
Icon,
|
|
22
|
+
Icon as WCIcon,
|
|
23
23
|
Button,
|
|
24
24
|
Dropdown,
|
|
25
25
|
TextControl,
|
|
@@ -277,7 +277,7 @@ const SocialLinkEdit = ( {
|
|
|
277
277
|
*/
|
|
278
278
|
/* eslint-disable jsx-a11y/no-redundant-roles */ }
|
|
279
279
|
<button aria-haspopup="dialog" { ...blockProps } role="button">
|
|
280
|
-
<
|
|
280
|
+
<WCIcon icon={ icon } />
|
|
281
281
|
<span
|
|
282
282
|
className={ clsx( 'wp-block-social-link-label', {
|
|
283
283
|
'screen-reader-text': ! showLabels,
|
package/src/tab-list/edit.js
CHANGED
|
@@ -14,6 +14,8 @@ import { useSelect } from '@wordpress/data';
|
|
|
14
14
|
import AddTabToolbarControl from '../tab-panel/add-tab-toolbar-control';
|
|
15
15
|
import RemoveTabToolbarControl from '../tab-panel/remove-tab-toolbar-control';
|
|
16
16
|
|
|
17
|
+
const TAB_LIST_TEMPLATE = [ [ 'core/tab' ], [ 'core/tab' ] ];
|
|
18
|
+
|
|
17
19
|
function Edit( { clientId } ) {
|
|
18
20
|
const tabsClientId = useSelect(
|
|
19
21
|
( select ) =>
|
|
@@ -26,6 +28,7 @@ function Edit( { clientId } ) {
|
|
|
26
28
|
const innerBlocksProps = useInnerBlocksProps( blockProps, {
|
|
27
29
|
allowedBlocks: [ 'core/tab' ],
|
|
28
30
|
orientation: 'horizontal',
|
|
31
|
+
template: TAB_LIST_TEMPLATE,
|
|
29
32
|
templateLock: false,
|
|
30
33
|
renderAppender: false,
|
|
31
34
|
} );
|
package/src/tab-panels/edit.js
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
store as blockEditorStore,
|
|
8
8
|
} from '@wordpress/block-editor';
|
|
9
9
|
import { useSelect } from '@wordpress/data';
|
|
10
|
+
import { __ } from '@wordpress/i18n';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Internal dependencies
|
|
@@ -14,7 +15,15 @@ import { useSelect } from '@wordpress/data';
|
|
|
14
15
|
import AddTabToolbarControl from '../tab-panel/add-tab-toolbar-control';
|
|
15
16
|
import RemoveTabToolbarControl from '../tab-panel/remove-tab-toolbar-control';
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Initial template applied only when the block is first inserted (i.e. when
|
|
20
|
+
* inner blocks are empty). templateLock is false, so this is never applied to
|
|
21
|
+
* existing blocks that already have tab panels saved.
|
|
22
|
+
*/
|
|
23
|
+
const TAB_PANELS_TEMPLATE = [
|
|
24
|
+
[ 'core/tab-panel', { label: __( 'Tab' ) } ],
|
|
25
|
+
[ 'core/tab-panel', { label: __( 'Tab' ) } ],
|
|
26
|
+
];
|
|
18
27
|
|
|
19
28
|
export default function Edit( { clientId } ) {
|
|
20
29
|
const blockProps = useBlockProps();
|