@wordpress/block-editor 8.5.0 → 8.5.1

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.
Files changed (71) hide show
  1. package/build/components/block-content-overlay/index.js +13 -4
  2. package/build/components/block-content-overlay/index.js.map +1 -1
  3. package/build/components/block-lock/index.js +8 -0
  4. package/build/components/block-lock/index.js.map +1 -1
  5. package/build/components/block-lock/menu-item.js +5 -20
  6. package/build/components/block-lock/menu-item.js.map +1 -1
  7. package/build/components/block-lock/modal.js +33 -12
  8. package/build/components/block-lock/modal.js.map +1 -1
  9. package/build/components/block-lock/toolbar.js +7 -20
  10. package/build/components/block-lock/toolbar.js.map +1 -1
  11. package/build/components/block-lock/use-block-lock.js +53 -0
  12. package/build/components/block-lock/use-block-lock.js.map +1 -0
  13. package/build/components/block-pattern-setup/index.js +37 -22
  14. package/build/components/block-pattern-setup/index.js.map +1 -1
  15. package/build/components/block-pattern-setup/setup-toolbar.js +1 -1
  16. package/build/components/block-pattern-setup/setup-toolbar.js.map +1 -1
  17. package/build/components/block-preview/auto.js +6 -3
  18. package/build/components/block-preview/auto.js.map +1 -1
  19. package/build/components/block-preview/index.js +4 -2
  20. package/build/components/block-preview/index.js.map +1 -1
  21. package/build/components/block-switcher/index.js +7 -2
  22. package/build/components/block-switcher/index.js.map +1 -1
  23. package/build/components/list-view/block-select-button.js +4 -10
  24. package/build/components/list-view/block-select-button.js.map +1 -1
  25. package/build/store/selectors.js +26 -2
  26. package/build/store/selectors.js.map +1 -1
  27. package/build-module/components/block-content-overlay/index.js +13 -4
  28. package/build-module/components/block-content-overlay/index.js.map +1 -1
  29. package/build-module/components/block-lock/index.js +1 -0
  30. package/build-module/components/block-lock/index.js.map +1 -1
  31. package/build-module/components/block-lock/menu-item.js +4 -18
  32. package/build-module/components/block-lock/menu-item.js.map +1 -1
  33. package/build-module/components/block-lock/modal.js +31 -12
  34. package/build-module/components/block-lock/modal.js.map +1 -1
  35. package/build-module/components/block-lock/toolbar.js +6 -18
  36. package/build-module/components/block-lock/toolbar.js.map +1 -1
  37. package/build-module/components/block-lock/use-block-lock.js +44 -0
  38. package/build-module/components/block-lock/use-block-lock.js.map +1 -0
  39. package/build-module/components/block-pattern-setup/index.js +39 -24
  40. package/build-module/components/block-pattern-setup/index.js.map +1 -1
  41. package/build-module/components/block-pattern-setup/setup-toolbar.js +1 -1
  42. package/build-module/components/block-pattern-setup/setup-toolbar.js.map +1 -1
  43. package/build-module/components/block-preview/auto.js +6 -3
  44. package/build-module/components/block-preview/auto.js.map +1 -1
  45. package/build-module/components/block-preview/index.js +4 -2
  46. package/build-module/components/block-preview/index.js.map +1 -1
  47. package/build-module/components/block-switcher/index.js +7 -2
  48. package/build-module/components/block-switcher/index.js.map +1 -1
  49. package/build-module/components/list-view/block-select-button.js +4 -9
  50. package/build-module/components/list-view/block-select-button.js.map +1 -1
  51. package/build-module/store/selectors.js +24 -2
  52. package/build-module/store/selectors.js.map +1 -1
  53. package/build-style/style-rtl.css +34 -25
  54. package/build-style/style.css +34 -25
  55. package/package.json +3 -3
  56. package/src/components/block-content-overlay/index.js +19 -2
  57. package/src/components/block-lock/index.js +1 -0
  58. package/src/components/block-lock/menu-item.js +3 -23
  59. package/src/components/block-lock/modal.js +37 -13
  60. package/src/components/block-lock/toolbar.js +4 -21
  61. package/src/components/block-lock/use-block-lock.js +49 -0
  62. package/src/components/block-pattern-setup/index.js +84 -59
  63. package/src/components/block-pattern-setup/setup-toolbar.js +3 -1
  64. package/src/components/block-pattern-setup/style.scss +32 -26
  65. package/src/components/block-preview/auto.js +10 -1
  66. package/src/components/block-preview/index.js +2 -0
  67. package/src/components/block-switcher/index.js +13 -1
  68. package/src/components/block-switcher/style.scss +7 -3
  69. package/src/components/block-switcher/test/__snapshots__/index.js.snap +15 -13
  70. package/src/components/list-view/block-select-button.js +2 -10
  71. package/src/store/selectors.js +22 -2
@@ -1423,11 +1423,13 @@
1423
1423
  }
1424
1424
 
1425
1425
  .components-button.block-editor-block-switcher__no-switcher-icon {
1426
- width: 48px;
1426
+ display: flex;
1427
+ padding: 6px 12px !important;
1427
1428
  }
1428
- .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-blocks-icon {
1429
+ .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-icon {
1429
1430
  margin-left: auto;
1430
1431
  margin-right: auto;
1432
+ min-width: 24px !important;
1431
1433
  }
1432
1434
 
1433
1435
  .components-button.block-editor-block-switcher__no-switcher-icon:disabled {
@@ -1525,7 +1527,7 @@
1525
1527
  }
1526
1528
 
1527
1529
  .block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon {
1528
- width: 48px;
1530
+ min-width: 36px;
1529
1531
  }
1530
1532
  .block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon,
1531
1533
  .block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__toggle {
@@ -1652,39 +1654,41 @@
1652
1654
  align-items: flex-start;
1653
1655
  width: 100%;
1654
1656
  border-radius: 2px;
1655
- box-shadow: inset 0 0 0 1px #1e1e1e;
1656
- outline: 1px solid transparent;
1657
1657
  }
1658
1658
  .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__toolbar {
1659
1659
  justify-content: center;
1660
1660
  }
1661
1661
  .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container {
1662
- display: grid;
1663
- grid-template-columns: 1fr 1fr;
1664
- grid-gap: 16px;
1665
- padding: 16px;
1666
- max-height: 550px;
1667
- overflow: auto;
1668
- margin: 0 1px 1px 1px;
1669
- width: calc(100% - 2px);
1670
- background: #fff;
1662
+ column-gap: 24px;
1663
+ display: block;
1664
+ width: 100%;
1665
+ padding: 32px;
1666
+ column-count: 2;
1667
+ }
1668
+ @media (min-width: 1440px) {
1669
+ .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container {
1670
+ column-count: 3;
1671
+ }
1671
1672
  }
1672
1673
  .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-preview__container,
1673
1674
  .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container div[role=button] {
1674
1675
  cursor: pointer;
1675
1676
  }
1676
- .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item-title {
1677
- padding: 4px;
1678
- font-size: 12px;
1679
- text-align: center;
1677
+ .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item {
1678
+ break-inside: avoid-column;
1679
+ margin-bottom: 24px;
1680
1680
  }
1681
- .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-preview__container {
1681
+ .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item .block-editor-block-preview__container {
1682
+ min-height: 100px;
1682
1683
  border-radius: 2px;
1683
1684
  border: 1px solid #ddd;
1684
1685
  }
1686
+ .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item .block-editor-block-preview__content {
1687
+ width: 100%;
1688
+ }
1685
1689
  .block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar {
1690
+ height: 60px;
1686
1691
  box-sizing: border-box;
1687
- position: relative;
1688
1692
  padding: 16px;
1689
1693
  width: 100%;
1690
1694
  text-align: right;
@@ -1692,12 +1696,12 @@
1692
1696
  color: #1e1e1e;
1693
1697
  border-radius: 2px 2px 0 0;
1694
1698
  background-color: #fff;
1695
- box-shadow: inset 0 0 0 1px #1e1e1e;
1696
- outline: 1px solid transparent;
1697
1699
  display: flex;
1698
1700
  flex-direction: row;
1699
1701
  align-items: center;
1700
1702
  justify-content: space-between;
1703
+ border-top: 1px solid #ddd;
1704
+ align-self: flex-end;
1701
1705
  }
1702
1706
  .block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar .block-editor-block-pattern-setup__display-controls {
1703
1707
  display: flex;
@@ -1728,13 +1732,12 @@
1728
1732
  box-sizing: border-box;
1729
1733
  }
1730
1734
  .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide {
1731
- opacity: 0;
1732
1735
  position: absolute;
1733
1736
  top: 0;
1734
1737
  width: 100%;
1735
1738
  margin: auto;
1736
- padding: 16px;
1737
- transition: transform 0.5s, opacity 0.5s, z-index 0.5s;
1739
+ padding: 0;
1740
+ transition: transform 0.5s, z-index 0.5s;
1738
1741
  z-index: 100;
1739
1742
  }
1740
1743
  .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide.active-slide {
@@ -1754,6 +1757,12 @@
1754
1757
  display: none;
1755
1758
  }
1756
1759
 
1760
+ .block-editor-block-pattern-setup__carousel,
1761
+ .block-editor-block-pattern-setup__grid {
1762
+ width: 100%;
1763
+ overflow-y: auto;
1764
+ }
1765
+
1757
1766
  .block-editor-block-variation-transforms {
1758
1767
  padding: 0 52px 16px 16px;
1759
1768
  width: 100%;
@@ -1423,11 +1423,13 @@
1423
1423
  }
1424
1424
 
1425
1425
  .components-button.block-editor-block-switcher__no-switcher-icon {
1426
- width: 48px;
1426
+ display: flex;
1427
+ padding: 6px 12px !important;
1427
1428
  }
1428
- .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-blocks-icon {
1429
+ .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-icon {
1429
1430
  margin-right: auto;
1430
1431
  margin-left: auto;
1432
+ min-width: 24px !important;
1431
1433
  }
1432
1434
 
1433
1435
  .components-button.block-editor-block-switcher__no-switcher-icon:disabled {
@@ -1525,7 +1527,7 @@
1525
1527
  }
1526
1528
 
1527
1529
  .block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon {
1528
- width: 48px;
1530
+ min-width: 36px;
1529
1531
  }
1530
1532
  .block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon,
1531
1533
  .block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__toggle {
@@ -1652,39 +1654,41 @@
1652
1654
  align-items: flex-start;
1653
1655
  width: 100%;
1654
1656
  border-radius: 2px;
1655
- box-shadow: inset 0 0 0 1px #1e1e1e;
1656
- outline: 1px solid transparent;
1657
1657
  }
1658
1658
  .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__toolbar {
1659
1659
  justify-content: center;
1660
1660
  }
1661
1661
  .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container {
1662
- display: grid;
1663
- grid-template-columns: 1fr 1fr;
1664
- grid-gap: 16px;
1665
- padding: 16px;
1666
- max-height: 550px;
1667
- overflow: auto;
1668
- margin: 0 1px 1px 1px;
1669
- width: calc(100% - 2px);
1670
- background: #fff;
1662
+ column-gap: 24px;
1663
+ display: block;
1664
+ width: 100%;
1665
+ padding: 32px;
1666
+ column-count: 2;
1667
+ }
1668
+ @media (min-width: 1440px) {
1669
+ .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container {
1670
+ column-count: 3;
1671
+ }
1671
1672
  }
1672
1673
  .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-preview__container,
1673
1674
  .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container div[role=button] {
1674
1675
  cursor: pointer;
1675
1676
  }
1676
- .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item-title {
1677
- padding: 4px;
1678
- font-size: 12px;
1679
- text-align: center;
1677
+ .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item {
1678
+ break-inside: avoid-column;
1679
+ margin-bottom: 24px;
1680
1680
  }
1681
- .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-preview__container {
1681
+ .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item .block-editor-block-preview__container {
1682
+ min-height: 100px;
1682
1683
  border-radius: 2px;
1683
1684
  border: 1px solid #ddd;
1684
1685
  }
1686
+ .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item .block-editor-block-preview__content {
1687
+ width: 100%;
1688
+ }
1685
1689
  .block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar {
1690
+ height: 60px;
1686
1691
  box-sizing: border-box;
1687
- position: relative;
1688
1692
  padding: 16px;
1689
1693
  width: 100%;
1690
1694
  text-align: left;
@@ -1692,12 +1696,12 @@
1692
1696
  color: #1e1e1e;
1693
1697
  border-radius: 2px 2px 0 0;
1694
1698
  background-color: #fff;
1695
- box-shadow: inset 0 0 0 1px #1e1e1e;
1696
- outline: 1px solid transparent;
1697
1699
  display: flex;
1698
1700
  flex-direction: row;
1699
1701
  align-items: center;
1700
1702
  justify-content: space-between;
1703
+ border-top: 1px solid #ddd;
1704
+ align-self: flex-end;
1701
1705
  }
1702
1706
  .block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar .block-editor-block-pattern-setup__display-controls {
1703
1707
  display: flex;
@@ -1728,13 +1732,12 @@
1728
1732
  box-sizing: border-box;
1729
1733
  }
1730
1734
  .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide {
1731
- opacity: 0;
1732
1735
  position: absolute;
1733
1736
  top: 0;
1734
1737
  width: 100%;
1735
1738
  margin: auto;
1736
- padding: 16px;
1737
- transition: transform 0.5s, opacity 0.5s, z-index 0.5s;
1739
+ padding: 0;
1740
+ transition: transform 0.5s, z-index 0.5s;
1738
1741
  z-index: 100;
1739
1742
  }
1740
1743
  .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide.active-slide {
@@ -1754,6 +1757,12 @@
1754
1757
  display: none;
1755
1758
  }
1756
1759
 
1760
+ .block-editor-block-pattern-setup__carousel,
1761
+ .block-editor-block-pattern-setup__grid {
1762
+ width: 100%;
1763
+ overflow-y: auto;
1764
+ }
1765
+
1757
1766
  .block-editor-block-variation-transforms {
1758
1767
  padding: 0 16px 16px 52px;
1759
1768
  width: 100%;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/block-editor",
3
- "version": "8.5.0",
3
+ "version": "8.5.1",
4
4
  "description": "Generic block editor.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -36,7 +36,7 @@
36
36
  "@wordpress/a11y": "^3.6.0",
37
37
  "@wordpress/api-fetch": "^6.3.0",
38
38
  "@wordpress/blob": "^3.6.0",
39
- "@wordpress/blocks": "^11.5.0",
39
+ "@wordpress/blocks": "^11.5.1",
40
40
  "@wordpress/components": "^19.8.0",
41
41
  "@wordpress/compose": "^5.4.0",
42
42
  "@wordpress/data": "^6.6.0",
@@ -77,5 +77,5 @@
77
77
  "publishConfig": {
78
78
  "access": "public"
79
79
  },
80
- "gitHead": "11eb1241e63c9240018323551c6753f8a5fa96f9"
80
+ "gitHead": "9c15c669843d53c5ca6024a4c486d01d819d123f"
81
81
  }
@@ -25,6 +25,7 @@ export default function BlockContentOverlay( {
25
25
  const [ isHovered, setIsHovered ] = useState( false );
26
26
 
27
27
  const {
28
+ canEdit,
28
29
  isParentSelected,
29
30
  hasChildSelected,
30
31
  isDraggingBlocks,
@@ -36,8 +37,10 @@ export default function BlockContentOverlay( {
36
37
  hasSelectedInnerBlock,
37
38
  isDraggingBlocks: _isDraggingBlocks,
38
39
  isBlockHighlighted,
40
+ canEditBlock,
39
41
  } = select( blockEditorStore );
40
42
  return {
43
+ canEdit: canEditBlock( clientId ),
41
44
  isParentSelected: isBlockSelected( clientId ),
42
45
  hasChildSelected: hasSelectedInnerBlock( clientId, true ),
43
46
  isDraggingBlocks: _isDraggingBlocks(),
@@ -59,6 +62,12 @@ export default function BlockContentOverlay( {
59
62
  );
60
63
 
61
64
  useEffect( () => {
65
+ // The overlay is always active when editing is locked.
66
+ if ( ! canEdit ) {
67
+ setIsOverlayActive( true );
68
+ return;
69
+ }
70
+
62
71
  // Reenable when blocks are not in use.
63
72
  if ( ! isParentSelected && ! hasChildSelected && ! isOverlayActive ) {
64
73
  setIsOverlayActive( true );
@@ -75,7 +84,13 @@ export default function BlockContentOverlay( {
75
84
  if ( hasChildSelected && isOverlayActive ) {
76
85
  setIsOverlayActive( false );
77
86
  }
78
- }, [ isParentSelected, hasChildSelected, isOverlayActive, isHovered ] );
87
+ }, [
88
+ isParentSelected,
89
+ hasChildSelected,
90
+ isOverlayActive,
91
+ isHovered,
92
+ canEdit,
93
+ ] );
79
94
 
80
95
  // Disabled because the overlay div doesn't actually have a role or functionality
81
96
  // as far as the a11y is concerned. We're just catching the first click so that
@@ -88,7 +103,9 @@ export default function BlockContentOverlay( {
88
103
  onMouseEnter={ () => setIsHovered( true ) }
89
104
  onMouseLeave={ () => setIsHovered( false ) }
90
105
  onMouseUp={
91
- isOverlayActive ? () => setIsOverlayActive( false ) : undefined
106
+ isOverlayActive && canEdit
107
+ ? () => setIsOverlayActive( false )
108
+ : undefined
92
109
  }
93
110
  >
94
111
  { wrapperProps?.children }
@@ -1,3 +1,4 @@
1
1
  export { default as BlockLockMenuItem } from './menu-item';
2
2
  export { default as BlockLockModal } from './modal';
3
3
  export { default as BlockLockToolbar } from './toolbar';
4
+ export { default as useBlockLock } from './use-block-lock';
@@ -4,43 +4,23 @@
4
4
  import { __ } from '@wordpress/i18n';
5
5
  import { useReducer } from '@wordpress/element';
6
6
  import { MenuItem } from '@wordpress/components';
7
- import { useSelect } from '@wordpress/data';
8
7
  import { lock, unlock } from '@wordpress/icons';
9
8
 
10
9
  /**
11
10
  * Internal dependencies
12
11
  */
12
+ import useBlockLock from './use-block-lock';
13
13
  import BlockLockModal from './modal';
14
- import { store as blockEditorStore } from '../../store';
15
14
 
16
15
  export default function BlockLockMenuItem( { clientId } ) {
17
- const { canLockBlock, isLocked } = useSelect(
18
- ( select ) => {
19
- const {
20
- canMoveBlock,
21
- canRemoveBlock,
22
- canLockBlockType,
23
- getBlockName,
24
- getBlockRootClientId,
25
- } = select( blockEditorStore );
26
- const rootClientId = getBlockRootClientId( clientId );
27
-
28
- return {
29
- canLockBlock: canLockBlockType( getBlockName( clientId ) ),
30
- isLocked:
31
- ! canMoveBlock( clientId, rootClientId ) ||
32
- ! canRemoveBlock( clientId, rootClientId ),
33
- };
34
- },
35
- [ clientId ]
36
- );
16
+ const { canLock, isLocked } = useBlockLock( clientId, true );
37
17
 
38
18
  const [ isModalOpen, toggleModal ] = useReducer(
39
19
  ( isActive ) => ! isActive,
40
20
  false
41
21
  );
42
22
 
43
- if ( ! canLockBlock ) {
23
+ if ( ! canLock ) {
44
24
  return null;
45
25
  }
46
26
 
@@ -14,27 +14,25 @@ import {
14
14
  import { lock as lockIcon, unlock as unlockIcon } from '@wordpress/icons';
15
15
  import { useInstanceId } from '@wordpress/compose';
16
16
  import { useDispatch, useSelect } from '@wordpress/data';
17
+ import { isReusableBlock, getBlockType } from '@wordpress/blocks';
17
18
 
18
19
  /**
19
20
  * Internal dependencies
20
21
  */
22
+ import useBlockLock from './use-block-lock';
21
23
  import useBlockDisplayInformation from '../use-block-display-information';
22
24
  import { store as blockEditorStore } from '../../store';
23
25
 
24
26
  export default function BlockLockModal( { clientId, onClose } ) {
25
27
  const [ lock, setLock ] = useState( { move: false, remove: false } );
26
- const { canMove, canRemove } = useSelect(
28
+ const { canEdit, canMove, canRemove } = useBlockLock( clientId, true );
29
+ const { isReusable } = useSelect(
27
30
  ( select ) => {
28
- const {
29
- canMoveBlock,
30
- canRemoveBlock,
31
- getBlockRootClientId,
32
- } = select( blockEditorStore );
33
- const rootClientId = getBlockRootClientId( clientId );
31
+ const { getBlockName } = select( blockEditorStore );
32
+ const blockName = getBlockName( clientId );
34
33
 
35
34
  return {
36
- canMove: canMoveBlock( clientId, rootClientId ),
37
- canRemove: canRemoveBlock( clientId, rootClientId ),
35
+ isReusable: isReusableBlock( getBlockType( blockName ) ),
38
36
  };
39
37
  },
40
38
  [ clientId ]
@@ -50,12 +48,12 @@ export default function BlockLockModal( { clientId, onClose } ) {
50
48
  setLock( {
51
49
  move: ! canMove,
52
50
  remove: ! canRemove,
51
+ ...( isReusable ? { edit: ! canEdit } : {} ),
53
52
  } );
54
- }, [ canMove, canRemove ] );
53
+ }, [ canEdit, canMove, canRemove, isReusable ] );
55
54
 
56
55
  const isAllChecked = Object.values( lock ).every( Boolean );
57
- const isIndeterminate =
58
- Object.values( lock ).some( Boolean ) && ! isAllChecked;
56
+ const isMixed = Object.values( lock ).some( Boolean ) && ! isAllChecked;
59
57
 
60
58
  return (
61
59
  <Modal
@@ -91,15 +89,41 @@ export default function BlockLockModal( { clientId, onClose } ) {
91
89
  <span id={ instanceId }>{ __( 'Lock all' ) }</span>
92
90
  }
93
91
  checked={ isAllChecked }
94
- indeterminate={ isIndeterminate }
92
+ indeterminate={ isMixed }
95
93
  onChange={ ( newValue ) =>
96
94
  setLock( {
97
95
  move: newValue,
98
96
  remove: newValue,
97
+ ...( isReusable ? { edit: newValue } : {} ),
99
98
  } )
100
99
  }
101
100
  />
102
101
  <ul className="block-editor-block-lock-modal__checklist">
102
+ { isReusable && (
103
+ <li className="block-editor-block-lock-modal__checklist-item">
104
+ <CheckboxControl
105
+ label={
106
+ <>
107
+ { __( 'Restrict editing' ) }
108
+ <Icon
109
+ icon={
110
+ lock.edit
111
+ ? lockIcon
112
+ : unlockIcon
113
+ }
114
+ />
115
+ </>
116
+ }
117
+ checked={ !! lock.edit }
118
+ onChange={ ( edit ) =>
119
+ setLock( ( prevLock ) => ( {
120
+ ...prevLock,
121
+ edit,
122
+ } ) )
123
+ }
124
+ />
125
+ </li>
126
+ ) }
103
127
  <li className="block-editor-block-lock-modal__checklist-item">
104
128
  <CheckboxControl
105
129
  label={
@@ -5,45 +5,28 @@ import { __, sprintf } from '@wordpress/i18n';
5
5
  import { ToolbarButton, ToolbarGroup } from '@wordpress/components';
6
6
  import { useReducer } from '@wordpress/element';
7
7
  import { lock } from '@wordpress/icons';
8
- import { useSelect } from '@wordpress/data';
9
8
 
10
9
  /**
11
10
  * Internal dependencies
12
11
  */
13
12
  import BlockLockModal from './modal';
13
+ import useBlockLock from './use-block-lock';
14
14
  import useBlockDisplayInformation from '../use-block-display-information';
15
- import { store as blockEditorStore } from '../../store';
16
15
 
17
16
  export default function BlockLockToolbar( { clientId } ) {
18
17
  const blockInformation = useBlockDisplayInformation( clientId );
19
- const { canMove, canRemove, canLockBlock } = useSelect(
20
- ( select ) => {
21
- const {
22
- canMoveBlock,
23
- canRemoveBlock,
24
- canLockBlockType,
25
- getBlockName,
26
- } = select( blockEditorStore );
27
-
28
- return {
29
- canMove: canMoveBlock( clientId ),
30
- canRemove: canRemoveBlock( clientId ),
31
- canLockBlock: canLockBlockType( getBlockName( clientId ) ),
32
- };
33
- },
34
- [ clientId ]
35
- );
18
+ const { canEdit, canMove, canRemove, canLock } = useBlockLock( clientId );
36
19
 
37
20
  const [ isModalOpen, toggleModal ] = useReducer(
38
21
  ( isActive ) => ! isActive,
39
22
  false
40
23
  );
41
24
 
42
- if ( ! canLockBlock ) {
25
+ if ( ! canLock ) {
43
26
  return null;
44
27
  }
45
28
 
46
- if ( canMove && canRemove ) {
29
+ if ( canEdit && canMove && canRemove ) {
47
30
  return null;
48
31
  }
49
32
 
@@ -0,0 +1,49 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect } from '@wordpress/data';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { store as blockEditorStore } from '../../store';
10
+
11
+ /**
12
+ * Return details about the block lock status.
13
+ *
14
+ * @param {string} clientId The block client Id.
15
+ * @param {boolean} checkParent Optional. The status is derived from the parent `templateLock`
16
+ * when the current block's lock state isn't defined.
17
+ *
18
+ * @return {Object} Block lock status
19
+ */
20
+ export default function useBlockLock( clientId, checkParent = false ) {
21
+ return useSelect(
22
+ ( select ) => {
23
+ const {
24
+ canEditBlock,
25
+ canMoveBlock,
26
+ canRemoveBlock,
27
+ canLockBlockType,
28
+ getBlockName,
29
+ getBlockRootClientId,
30
+ } = select( blockEditorStore );
31
+ const rootClientId = checkParent
32
+ ? getBlockRootClientId( clientId )
33
+ : null;
34
+
35
+ const canEdit = canEditBlock( clientId );
36
+ const canMove = canMoveBlock( clientId, rootClientId );
37
+ const canRemove = canRemoveBlock( clientId, rootClientId );
38
+
39
+ return {
40
+ canEdit,
41
+ canMove,
42
+ canRemove,
43
+ canLock: canLockBlockType( getBlockName( clientId ) ),
44
+ isLocked: ! canEdit || ! canMove || ! canRemove,
45
+ };
46
+ },
47
+ [ clientId, checkParent ]
48
+ );
49
+ }