@wordpress/block-editor 12.19.3 → 12.19.4

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 (98) hide show
  1. package/build/components/block-edit/context.js +2 -1
  2. package/build/components/block-edit/context.js.map +1 -1
  3. package/build/components/block-edit/index.js +8 -3
  4. package/build/components/block-edit/index.js.map +1 -1
  5. package/build/components/block-inspector/index.js +5 -4
  6. package/build/components/block-inspector/index.js.map +1 -1
  7. package/build/components/block-preview/index.js +4 -0
  8. package/build/components/block-preview/index.js.map +1 -1
  9. package/build/components/global-styles/border-panel.js +21 -8
  10. package/build/components/global-styles/border-panel.js.map +1 -1
  11. package/build/components/global-styles/index.js +6 -0
  12. package/build/components/global-styles/index.js.map +1 -1
  13. package/build/components/global-styles/shadow-panel-components.js +80 -23
  14. package/build/components/global-styles/shadow-panel-components.js.map +1 -1
  15. package/build/components/inspector-controls-tabs/styles-tab.js +1 -1
  16. package/build/components/inspector-controls-tabs/styles-tab.js.map +1 -1
  17. package/build/components/link-control/link-preview.js +4 -1
  18. package/build/components/link-control/link-preview.js.map +1 -1
  19. package/build/components/rich-text/index.js +45 -25
  20. package/build/components/rich-text/index.js.map +1 -1
  21. package/build/components/rich-text/use-enter.js +3 -0
  22. package/build/components/rich-text/use-enter.js.map +1 -1
  23. package/build/hooks/block-hooks.js +8 -6
  24. package/build/hooks/block-hooks.js.map +1 -1
  25. package/build/hooks/border.js +6 -4
  26. package/build/hooks/border.js.map +1 -1
  27. package/build/hooks/use-bindings-attributes.js +2 -4
  28. package/build/hooks/use-bindings-attributes.js.map +1 -1
  29. package/build/private-apis.js +3 -1
  30. package/build/private-apis.js.map +1 -1
  31. package/build/store/private-actions.js +0 -10
  32. package/build/store/private-actions.js.map +1 -1
  33. package/build/store/private-selectors.js +0 -8
  34. package/build/store/private-selectors.js.map +1 -1
  35. package/build/store/reducer.js +1 -16
  36. package/build/store/reducer.js.map +1 -1
  37. package/build-module/components/block-edit/context.js +1 -0
  38. package/build-module/components/block-edit/context.js.map +1 -1
  39. package/build-module/components/block-edit/index.js +9 -4
  40. package/build-module/components/block-edit/index.js.map +1 -1
  41. package/build-module/components/block-inspector/index.js +6 -5
  42. package/build-module/components/block-inspector/index.js.map +1 -1
  43. package/build-module/components/block-preview/index.js +4 -0
  44. package/build-module/components/block-preview/index.js.map +1 -1
  45. package/build-module/components/global-styles/border-panel.js +22 -10
  46. package/build-module/components/global-styles/border-panel.js.map +1 -1
  47. package/build-module/components/global-styles/index.js +1 -1
  48. package/build-module/components/global-styles/index.js.map +1 -1
  49. package/build-module/components/global-styles/shadow-panel-components.js +82 -24
  50. package/build-module/components/global-styles/shadow-panel-components.js.map +1 -1
  51. package/build-module/components/inspector-controls-tabs/styles-tab.js +2 -2
  52. package/build-module/components/inspector-controls-tabs/styles-tab.js.map +1 -1
  53. package/build-module/components/link-control/link-preview.js +5 -2
  54. package/build-module/components/link-control/link-preview.js.map +1 -1
  55. package/build-module/components/rich-text/index.js +45 -26
  56. package/build-module/components/rich-text/index.js.map +1 -1
  57. package/build-module/components/rich-text/use-enter.js +3 -0
  58. package/build-module/components/rich-text/use-enter.js.map +1 -1
  59. package/build-module/hooks/block-hooks.js +8 -6
  60. package/build-module/hooks/block-hooks.js.map +1 -1
  61. package/build-module/hooks/border.js +7 -5
  62. package/build-module/hooks/border.js.map +1 -1
  63. package/build-module/hooks/use-bindings-attributes.js +3 -5
  64. package/build-module/hooks/use-bindings-attributes.js.map +1 -1
  65. package/build-module/private-apis.js +3 -1
  66. package/build-module/private-apis.js.map +1 -1
  67. package/build-module/store/private-actions.js +0 -9
  68. package/build-module/store/private-actions.js.map +1 -1
  69. package/build-module/store/private-selectors.js +0 -6
  70. package/build-module/store/private-selectors.js.map +1 -1
  71. package/build-module/store/reducer.js +1 -16
  72. package/build-module/store/reducer.js.map +1 -1
  73. package/build-style/style-rtl.css +47 -14
  74. package/build-style/style.css +47 -14
  75. package/package.json +7 -7
  76. package/src/components/block-edit/context.js +1 -0
  77. package/src/components/block-edit/index.js +5 -1
  78. package/src/components/block-inspector/index.js +7 -5
  79. package/src/components/block-preview/index.js +6 -1
  80. package/src/components/block-toolbar/style.scss +11 -6
  81. package/src/components/global-styles/border-panel.js +33 -22
  82. package/src/components/global-styles/index.js +5 -1
  83. package/src/components/global-styles/shadow-panel-components.js +92 -23
  84. package/src/components/global-styles/style.scss +33 -10
  85. package/src/components/inspector-controls-tabs/styles-tab.js +2 -2
  86. package/src/components/link-control/link-preview.js +9 -2
  87. package/src/components/link-control/style.scss +9 -0
  88. package/src/components/rich-text/index.js +74 -51
  89. package/src/components/rich-text/use-enter.js +4 -0
  90. package/src/components/url-popover/style.scss +1 -0
  91. package/src/hooks/block-hooks.js +10 -5
  92. package/src/hooks/block-hooks.scss +6 -0
  93. package/src/hooks/border.js +16 -4
  94. package/src/hooks/use-bindings-attributes.js +5 -7
  95. package/src/private-apis.js +2 -0
  96. package/src/store/private-actions.js +0 -10
  97. package/src/store/private-selectors.js +0 -8
  98. package/src/store/reducer.js +0 -15
@@ -1550,6 +1550,17 @@ iframe[name=editor-canvas].has-editor-padding {
1550
1550
  width: 230px;
1551
1551
  }
1552
1552
 
1553
+ .block-editor-global-styles__shadow__list {
1554
+ display: flex;
1555
+ gap: 12px;
1556
+ flex-wrap: wrap;
1557
+ padding-bottom: 8px;
1558
+ }
1559
+
1560
+ .block-editor-global-styles__clear-shadow {
1561
+ text-align: left;
1562
+ }
1563
+
1553
1564
  .block-editor-global-styles-filters-panel__dropdown,
1554
1565
  .block-editor-global-styles__shadow-dropdown {
1555
1566
  display: block;
@@ -1565,21 +1576,27 @@ iframe[name=editor-canvas].has-editor-padding {
1565
1576
  background-color: #f0f0f0;
1566
1577
  }
1567
1578
 
1568
- .block-editor-global-styles__shadow-indicator-wrapper {
1569
- padding: 6px;
1570
- display: flex;
1571
- align-items: center;
1572
- justify-content: center;
1573
- }
1574
-
1575
1579
  .block-editor-global-styles__shadow-indicator {
1576
1580
  color: #2f2f2f;
1577
1581
  border: #e0e0e0 1px solid;
1578
1582
  border-radius: 2px;
1579
1583
  cursor: pointer;
1580
1584
  padding: 0;
1581
- height: 24px;
1582
- width: 24px;
1585
+ height: 26px;
1586
+ width: 26px;
1587
+ box-sizing: border-box;
1588
+ transform: scale(1);
1589
+ transition: transform 0.1s ease;
1590
+ will-change: transform;
1591
+ }
1592
+ .block-editor-global-styles__shadow-indicator:focus {
1593
+ border: 2px solid #757575;
1594
+ }
1595
+ .block-editor-global-styles__shadow-indicator:hover {
1596
+ transform: scale(1.2);
1597
+ }
1598
+ .block-editor-global-styles__shadow-indicator.unset {
1599
+ background: linear-gradient(45deg, transparent 48%, #ddd 48%, #ddd 52%, transparent 52%);
1583
1600
  }
1584
1601
 
1585
1602
  .block-editor-global-styles-advanced-panel__custom-css-input textarea {
@@ -1794,6 +1811,13 @@ iframe[name=editor-canvas].has-editor-padding {
1794
1811
  .show-icon-labels .block-editor-link-control .components-button.has-icon::before {
1795
1812
  content: attr(aria-label);
1796
1813
  }
1814
+ .show-icon-labels .block-editor-link-control .block-editor-link-control__search-item-top {
1815
+ gap: 8px;
1816
+ }
1817
+ .show-icon-labels .block-editor-link-control .block-editor-link-control__search-item-top .components-button.has-icon {
1818
+ min-width: inherit;
1819
+ width: min-content;
1820
+ }
1797
1821
 
1798
1822
  .block-editor-link-control__search-input-wrapper {
1799
1823
  margin-bottom: 8px;
@@ -3125,6 +3149,7 @@ iframe[name=editor-canvas].has-editor-padding {
3125
3149
  text-overflow: ellipsis;
3126
3150
  white-space: nowrap;
3127
3151
  margin-left: 8px;
3152
+ min-width: 150px;
3128
3153
  max-width: 350px;
3129
3154
  }
3130
3155
  .block-editor-url-popover__link-viewer-url.has-invalid-link {
@@ -3169,6 +3194,11 @@ iframe[name=editor-canvas].has-editor-padding {
3169
3194
  .block-editor-hooks__block-hooks .components-toggle-control .components-h-stack .components-h-stack {
3170
3195
  flex-direction: row;
3171
3196
  }
3197
+ .block-editor-hooks__block-hooks .block-editor-hooks__block-hooks-helptext {
3198
+ color: #757575;
3199
+ font-size: 12px;
3200
+ margin-bottom: 16px;
3201
+ }
3172
3202
 
3173
3203
  .block-editor-hooks__background__inspector-media-replace-container {
3174
3204
  position: relative;
@@ -3521,16 +3551,14 @@ iframe[name=editor-canvas].has-editor-padding {
3521
3551
  }
3522
3552
  .show-icon-labels .block-editor-block-mover .block-editor-block-mover__move-button-container {
3523
3553
  width: auto;
3554
+ position: relative;
3524
3555
  }
3525
3556
  @media (min-width: 600px) {
3526
- .show-icon-labels .block-editor-block-mover .block-editor-block-mover__move-button-container {
3527
- position: relative;
3528
- }
3529
- .show-icon-labels .block-editor-block-mover .block-editor-block-mover__move-button-container::before {
3557
+ .show-icon-labels .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container::before {
3530
3558
  content: "";
3531
3559
  height: 1px;
3532
3560
  width: 100%;
3533
- background: #1e1e1e;
3561
+ background: #e0e0e0;
3534
3562
  position: absolute;
3535
3563
  top: 50%;
3536
3564
  right: 50%;
@@ -3538,6 +3566,11 @@ iframe[name=editor-canvas].has-editor-padding {
3538
3566
  margin-top: -0.5px;
3539
3567
  }
3540
3568
  }
3569
+ @media (min-width: 782px) {
3570
+ .show-icon-labels .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container::before {
3571
+ background: #1e1e1e;
3572
+ }
3573
+ }
3541
3574
  .show-icon-labels .block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container,
3542
3575
  .show-icon-labels .block-editor-block-mover.is-horizontal .block-editor-block-mover-button {
3543
3576
  padding-right: 6px;
@@ -1550,6 +1550,17 @@ iframe[name=editor-canvas].has-editor-padding {
1550
1550
  width: 230px;
1551
1551
  }
1552
1552
 
1553
+ .block-editor-global-styles__shadow__list {
1554
+ display: flex;
1555
+ gap: 12px;
1556
+ flex-wrap: wrap;
1557
+ padding-bottom: 8px;
1558
+ }
1559
+
1560
+ .block-editor-global-styles__clear-shadow {
1561
+ text-align: right;
1562
+ }
1563
+
1553
1564
  .block-editor-global-styles-filters-panel__dropdown,
1554
1565
  .block-editor-global-styles__shadow-dropdown {
1555
1566
  display: block;
@@ -1565,21 +1576,27 @@ iframe[name=editor-canvas].has-editor-padding {
1565
1576
  background-color: #f0f0f0;
1566
1577
  }
1567
1578
 
1568
- .block-editor-global-styles__shadow-indicator-wrapper {
1569
- padding: 6px;
1570
- display: flex;
1571
- align-items: center;
1572
- justify-content: center;
1573
- }
1574
-
1575
1579
  .block-editor-global-styles__shadow-indicator {
1576
1580
  color: #2f2f2f;
1577
1581
  border: #e0e0e0 1px solid;
1578
1582
  border-radius: 2px;
1579
1583
  cursor: pointer;
1580
1584
  padding: 0;
1581
- height: 24px;
1582
- width: 24px;
1585
+ height: 26px;
1586
+ width: 26px;
1587
+ box-sizing: border-box;
1588
+ transform: scale(1);
1589
+ transition: transform 0.1s ease;
1590
+ will-change: transform;
1591
+ }
1592
+ .block-editor-global-styles__shadow-indicator:focus {
1593
+ border: 2px solid #757575;
1594
+ }
1595
+ .block-editor-global-styles__shadow-indicator:hover {
1596
+ transform: scale(1.2);
1597
+ }
1598
+ .block-editor-global-styles__shadow-indicator.unset {
1599
+ background: linear-gradient(-45deg, transparent 48%, #ddd 48%, #ddd 52%, transparent 52%);
1583
1600
  }
1584
1601
 
1585
1602
  .block-editor-global-styles-advanced-panel__custom-css-input textarea {
@@ -1795,6 +1812,13 @@ iframe[name=editor-canvas].has-editor-padding {
1795
1812
  .show-icon-labels .block-editor-link-control .components-button.has-icon::before {
1796
1813
  content: attr(aria-label);
1797
1814
  }
1815
+ .show-icon-labels .block-editor-link-control .block-editor-link-control__search-item-top {
1816
+ gap: 8px;
1817
+ }
1818
+ .show-icon-labels .block-editor-link-control .block-editor-link-control__search-item-top .components-button.has-icon {
1819
+ min-width: inherit;
1820
+ width: min-content;
1821
+ }
1798
1822
 
1799
1823
  .block-editor-link-control__search-input-wrapper {
1800
1824
  margin-bottom: 8px;
@@ -3126,6 +3150,7 @@ iframe[name=editor-canvas].has-editor-padding {
3126
3150
  text-overflow: ellipsis;
3127
3151
  white-space: nowrap;
3128
3152
  margin-right: 8px;
3153
+ min-width: 150px;
3129
3154
  max-width: 350px;
3130
3155
  }
3131
3156
  .block-editor-url-popover__link-viewer-url.has-invalid-link {
@@ -3170,6 +3195,11 @@ iframe[name=editor-canvas].has-editor-padding {
3170
3195
  .block-editor-hooks__block-hooks .components-toggle-control .components-h-stack .components-h-stack {
3171
3196
  flex-direction: row;
3172
3197
  }
3198
+ .block-editor-hooks__block-hooks .block-editor-hooks__block-hooks-helptext {
3199
+ color: #757575;
3200
+ font-size: 12px;
3201
+ margin-bottom: 16px;
3202
+ }
3173
3203
 
3174
3204
  .block-editor-hooks__background__inspector-media-replace-container {
3175
3205
  position: relative;
@@ -3522,16 +3552,14 @@ iframe[name=editor-canvas].has-editor-padding {
3522
3552
  }
3523
3553
  .show-icon-labels .block-editor-block-mover .block-editor-block-mover__move-button-container {
3524
3554
  width: auto;
3555
+ position: relative;
3525
3556
  }
3526
3557
  @media (min-width: 600px) {
3527
- .show-icon-labels .block-editor-block-mover .block-editor-block-mover__move-button-container {
3528
- position: relative;
3529
- }
3530
- .show-icon-labels .block-editor-block-mover .block-editor-block-mover__move-button-container::before {
3558
+ .show-icon-labels .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container::before {
3531
3559
  content: "";
3532
3560
  height: 1px;
3533
3561
  width: 100%;
3534
- background: #1e1e1e;
3562
+ background: #e0e0e0;
3535
3563
  position: absolute;
3536
3564
  top: 50%;
3537
3565
  left: 50%;
@@ -3539,6 +3567,11 @@ iframe[name=editor-canvas].has-editor-padding {
3539
3567
  margin-top: -0.5px;
3540
3568
  }
3541
3569
  }
3570
+ @media (min-width: 782px) {
3571
+ .show-icon-labels .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container::before {
3572
+ background: #1e1e1e;
3573
+ }
3574
+ }
3542
3575
  .show-icon-labels .block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container,
3543
3576
  .show-icon-labels .block-editor-block-mover.is-horizontal .block-editor-block-mover-button {
3544
3577
  padding-left: 6px;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/block-editor",
3
- "version": "12.19.3",
3
+ "version": "12.19.4",
4
4
  "description": "Generic block editor.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -38,9 +38,9 @@
38
38
  "@wordpress/a11y": "^3.51.1",
39
39
  "@wordpress/api-fetch": "^6.48.1",
40
40
  "@wordpress/blob": "^3.51.1",
41
- "@wordpress/blocks": "^12.28.3",
42
- "@wordpress/commands": "^0.22.2",
43
- "@wordpress/components": "^26.0.2",
41
+ "@wordpress/blocks": "^12.28.4",
42
+ "@wordpress/commands": "^0.22.3",
43
+ "@wordpress/components": "^26.0.3",
44
44
  "@wordpress/compose": "^6.28.1",
45
45
  "@wordpress/data": "^9.21.1",
46
46
  "@wordpress/date": "^4.51.1",
@@ -51,12 +51,12 @@
51
51
  "@wordpress/hooks": "^3.51.1",
52
52
  "@wordpress/html-entities": "^3.51.1",
53
53
  "@wordpress/i18n": "^4.51.1",
54
- "@wordpress/icons": "^9.42.1",
54
+ "@wordpress/icons": "^9.42.2",
55
55
  "@wordpress/is-shallow-equal": "^4.51.1",
56
56
  "@wordpress/keyboard-shortcuts": "^4.28.1",
57
57
  "@wordpress/keycodes": "^3.51.1",
58
58
  "@wordpress/notices": "^4.19.1",
59
- "@wordpress/preferences": "^3.28.2",
59
+ "@wordpress/preferences": "^3.28.3",
60
60
  "@wordpress/private-apis": "^0.33.1",
61
61
  "@wordpress/rich-text": "^6.28.2",
62
62
  "@wordpress/style-engine": "^1.34.1",
@@ -87,5 +87,5 @@
87
87
  "publishConfig": {
88
88
  "access": "public"
89
89
  },
90
- "gitHead": "b12d75c5c5256fda2a0509bb432e20ddd3354d5e"
90
+ "gitHead": "864c1c553cb284def3bd5c907998da45f5c143ea"
91
91
  }
@@ -6,6 +6,7 @@ import { createContext, useContext } from '@wordpress/element';
6
6
  export const mayDisplayControlsKey = Symbol( 'mayDisplayControls' );
7
7
  export const mayDisplayParentControlsKey = Symbol( 'mayDisplayParentControls' );
8
8
  export const blockEditingModeKey = Symbol( 'blockEditingMode' );
9
+ export const blockBindingsKey = Symbol( 'blockBindings' );
9
10
 
10
11
  export const DEFAULT_BLOCK_EDIT_CONTEXT = {
11
12
  name: '',
@@ -14,6 +14,7 @@ import {
14
14
  mayDisplayControlsKey,
15
15
  mayDisplayParentControlsKey,
16
16
  blockEditingModeKey,
17
+ blockBindingsKey,
17
18
  } from './context';
18
19
 
19
20
  /**
@@ -41,7 +42,8 @@ export default function BlockEdit( {
41
42
  attributes = {},
42
43
  __unstableLayoutClassNames,
43
44
  } = props;
44
- const { layout = null } = attributes;
45
+ const { layout = null, metadata = {} } = attributes;
46
+ const { bindings } = metadata;
45
47
  const layoutSupport =
46
48
  hasBlockSupport( name, 'layout', false ) ||
47
49
  hasBlockSupport( name, '__experimentalLayout', false );
@@ -62,6 +64,7 @@ export default function BlockEdit( {
62
64
  [ mayDisplayControlsKey ]: mayDisplayControls,
63
65
  [ mayDisplayParentControlsKey ]: mayDisplayParentControls,
64
66
  [ blockEditingModeKey ]: blockEditingMode,
67
+ [ blockBindingsKey ]: bindings,
65
68
  } ),
66
69
  [
67
70
  name,
@@ -73,6 +76,7 @@ export default function BlockEdit( {
73
76
  mayDisplayControls,
74
77
  mayDisplayParentControls,
75
78
  blockEditingMode,
79
+ bindings,
76
80
  ]
77
81
  ) }
78
82
  >
@@ -30,7 +30,7 @@ import PositionControls from '../inspector-controls-tabs/position-controls-panel
30
30
  import useBlockInspectorAnimationSettings from './useBlockInspectorAnimationSettings';
31
31
  import BlockInfo from '../block-info-slot-fill';
32
32
  import BlockQuickNavigation from '../block-quick-navigation';
33
- import { getBorderPanelLabel } from '../../hooks/border';
33
+ import { useBorderPanelLabel } from '../../hooks/border';
34
34
 
35
35
  function BlockInspectorLockedBlocks( { topLevelLockedBlock } ) {
36
36
  const contentClientIds = useSelect(
@@ -116,6 +116,10 @@ const BlockInspector = ( { showNoBlockSelectedMessage = true } ) => {
116
116
  selectedBlockClientId
117
117
  );
118
118
 
119
+ const borderPanelLabel = useBorderPanelLabel( {
120
+ blockName: selectedBlockName,
121
+ } );
122
+
119
123
  if ( count > 1 ) {
120
124
  return (
121
125
  <div className="block-editor-block-inspector">
@@ -140,9 +144,7 @@ const BlockInspector = ( { showNoBlockSelectedMessage = true } ) => {
140
144
  />
141
145
  <InspectorControls.Slot
142
146
  group="border"
143
- label={ getBorderPanelLabel( {
144
- blockName: selectedBlockName,
145
- } ) }
147
+ label={ borderPanelLabel }
146
148
  />
147
149
  <InspectorControls.Slot group="styles" />
148
150
  </>
@@ -251,7 +253,7 @@ const BlockInspectorSingleBlock = ( { clientId, blockName } ) => {
251
253
  [ blockName ]
252
254
  );
253
255
  const blockInformation = useBlockDisplayInformation( clientId );
254
- const borderPanelLabel = getBorderPanelLabel( { blockName } );
256
+ const borderPanelLabel = useBorderPanelLabel( { blockName } );
255
257
 
256
258
  return (
257
259
  <div className="block-editor-block-inspector">
@@ -54,7 +54,11 @@ export function BlockPreview( {
54
54
  []
55
55
  );
56
56
  const settings = useMemo(
57
- () => ( { ...originalSettings, __unstableIsPreviewMode: true } ),
57
+ () => ( {
58
+ ...originalSettings,
59
+ focusMode: false, // Disable "Spotlight mode".
60
+ __unstableIsPreviewMode: true,
61
+ } ),
58
62
  [ originalSettings ]
59
63
  );
60
64
  const renderedBlocks = useMemo(
@@ -117,6 +121,7 @@ export function useBlockPreview( { blocks, props = {}, layout } ) {
117
121
  () => ( {
118
122
  ...originalSettings,
119
123
  styles: undefined, // Clear styles included by the parent settings, as they are already output by the parent's EditorStyles.
124
+ focusMode: false, // Disable "Spotlight mode".
120
125
  __unstableIsPreviewMode: true,
121
126
  } ),
122
127
  [ originalSettings ]
@@ -207,17 +207,18 @@
207
207
  }
208
208
  }
209
209
 
210
- .block-editor-block-mover .block-editor-block-mover__move-button-container {
211
- width: auto;
212
-
213
- @include break-small() {
210
+ .block-editor-block-mover {
211
+ .block-editor-block-mover__move-button-container {
212
+ width: auto;
214
213
  position: relative;
214
+ }
215
215
 
216
- &::before {
216
+ &:not(.is-horizontal) .block-editor-block-mover__move-button-container::before {
217
+ @include break-small() {
217
218
  content: "";
218
219
  height: $border-width;
219
220
  width: 100%;
220
- background: $gray-900;
221
+ background: $gray-200;
221
222
  position: absolute;
222
223
  top: 50%;
223
224
  left: 50%;
@@ -226,6 +227,10 @@
226
227
  transform: translate(-50%, 0);
227
228
  margin-top: -$border-width * 0.5;
228
229
  }
230
+
231
+ @include break-medium {
232
+ background: $gray-900;
233
+ }
229
234
  }
230
235
  }
231
236
 
@@ -21,23 +21,24 @@ import { useColorsPerOrigin } from './hooks';
21
21
  import { getValueFromVariable, TOOLSPANEL_DROPDOWNMENU_PROPS } from './utils';
22
22
  import { overrideOrigins } from '../../store/get-block-settings';
23
23
  import { setImmutably } from '../../utils/object';
24
- import { getBorderPanelLabel } from '../../hooks/border';
25
- import { ShadowPopover } from './shadow-panel-components';
24
+ import { useBorderPanelLabel } from '../../hooks/border';
25
+ import { ShadowPopover, useShadowPresets } from './shadow-panel-components';
26
26
 
27
- function useHasShadowControl( settings ) {
28
- return !! settings?.shadow;
27
+ export function useHasBorderPanel( settings ) {
28
+ const controls = Object.values( useHasBorderPanelControls( settings ) );
29
+ return controls.some( Boolean );
29
30
  }
30
31
 
31
- export function useHasBorderPanel( settings ) {
32
- const controls = [
33
- useHasBorderColorControl( settings ),
34
- useHasBorderRadiusControl( settings ),
35
- useHasBorderStyleControl( settings ),
36
- useHasBorderWidthControl( settings ),
37
- useHasShadowControl( settings ),
38
- ];
32
+ export function useHasBorderPanelControls( settings ) {
33
+ const controls = {
34
+ hasBorderColor: useHasBorderColorControl( settings ),
35
+ hasBorderRadius: useHasBorderRadiusControl( settings ),
36
+ hasBorderStyle: useHasBorderStyleControl( settings ),
37
+ hasBorderWidth: useHasBorderWidthControl( settings ),
38
+ hasShadow: useHasShadowControl( settings ),
39
+ };
39
40
 
40
- return controls.some( Boolean );
41
+ return controls;
41
42
  }
42
43
 
43
44
  function useHasBorderColorControl( settings ) {
@@ -56,6 +57,11 @@ function useHasBorderWidthControl( settings ) {
56
57
  return settings?.border?.width;
57
58
  }
58
59
 
60
+ function useHasShadowControl( settings ) {
61
+ const shadows = useShadowPresets( settings );
62
+ return !! settings?.shadow && shadows.length > 0;
63
+ }
64
+
59
65
  function BorderToolsPanel( {
60
66
  resetAllFilter,
61
67
  onChange,
@@ -215,14 +221,16 @@ export default function BorderPanel( {
215
221
  const showBorderByDefault =
216
222
  defaultControls?.color || defaultControls?.width;
217
223
 
218
- const label = getBorderPanelLabel( {
224
+ const hasBorderControl =
225
+ showBorderColor ||
226
+ showBorderStyle ||
227
+ showBorderWidth ||
228
+ showBorderRadius;
229
+
230
+ const label = useBorderPanelLabel( {
219
231
  blockName: name,
220
232
  hasShadowControl,
221
- hasBorderControl:
222
- showBorderColor ||
223
- showBorderStyle ||
224
- showBorderWidth ||
225
- showBorderRadius,
233
+ hasBorderControl,
226
234
  } );
227
235
 
228
236
  return (
@@ -280,9 +288,12 @@ export default function BorderPanel( {
280
288
  isShownByDefault={ defaultControls.shadow }
281
289
  panelId={ panelId }
282
290
  >
283
- <BaseControl.VisualLabel as="legend">
284
- { __( 'Shadow' ) }
285
- </BaseControl.VisualLabel>
291
+ { hasBorderControl ? (
292
+ <BaseControl.VisualLabel as="legend">
293
+ { __( 'Shadow' ) }
294
+ </BaseControl.VisualLabel>
295
+ ) : null }
296
+
286
297
  <ItemGroup isBordered isSeparated>
287
298
  <ShadowPopover
288
299
  shadow={ shadow }
@@ -19,7 +19,11 @@ export {
19
19
  default as DimensionsPanel,
20
20
  useHasDimensionsPanel,
21
21
  } from './dimensions-panel';
22
- export { default as BorderPanel, useHasBorderPanel } from './border-panel';
22
+ export {
23
+ default as BorderPanel,
24
+ useHasBorderPanel,
25
+ useHasBorderPanelControls,
26
+ } from './border-panel';
23
27
  export { default as ColorPanel, useHasColorPanel } from './color-panel';
24
28
  export { default as FiltersPanel, useHasFiltersPanel } from './filters-panel';
25
29
  export {
@@ -5,28 +5,36 @@ import { __ } from '@wordpress/i18n';
5
5
  import {
6
6
  __experimentalVStack as VStack,
7
7
  __experimentalHeading as Heading,
8
- __experimentalGrid as Grid,
9
8
  __experimentalHStack as HStack,
10
9
  __experimentalDropdownContentWrapper as DropdownContentWrapper,
11
10
  Button,
12
11
  FlexItem,
13
12
  Dropdown,
13
+ privateApis as componentsPrivateApis,
14
14
  } from '@wordpress/components';
15
+ import { useMemo } from '@wordpress/element';
15
16
  import { shadow as shadowIcon, Icon, check } from '@wordpress/icons';
17
+
16
18
  /**
17
19
  * External dependencies
18
20
  */
19
21
  import classNames from 'classnames';
20
22
 
21
- export function ShadowPopoverContainer( { shadow, onShadowChange, settings } ) {
22
- const defaultShadows = settings?.shadow?.presets?.default || [];
23
- const themeShadows = settings?.shadow?.presets?.theme || [];
24
- const defaultPresetsEnabled = settings?.shadow?.defaultPresets;
23
+ /**
24
+ * Internal dependencies
25
+ */
26
+ import { unlock } from '../../lock-unlock';
25
27
 
26
- const shadows = [
27
- ...( defaultPresetsEnabled ? defaultShadows : [] ),
28
- ...themeShadows,
29
- ];
28
+ /**
29
+ * Shared reference to an empty array for cases where it is important to avoid
30
+ * returning a new array reference on every invocation.
31
+ *
32
+ * @type {Array}
33
+ */
34
+ const EMPTY_ARRAY = [];
35
+
36
+ export function ShadowPopoverContainer( { shadow, onShadowChange, settings } ) {
37
+ const shadows = useShadowPresets( settings );
30
38
 
31
39
  return (
32
40
  <div className="block-editor-global-styles__shadow-popover-container">
@@ -37,42 +45,76 @@ export function ShadowPopoverContainer( { shadow, onShadowChange, settings } ) {
37
45
  activeShadow={ shadow }
38
46
  onSelect={ onShadowChange }
39
47
  />
48
+ <div className="block-editor-global-styles__clear-shadow">
49
+ <Button
50
+ variant="tertiary"
51
+ onClick={ () => onShadowChange( undefined ) }
52
+ >
53
+ { __( 'Clear' ) }
54
+ </Button>
55
+ </div>
40
56
  </VStack>
41
57
  </div>
42
58
  );
43
59
  }
44
60
 
45
61
  export function ShadowPresets( { presets, activeShadow, onSelect } ) {
62
+ const { CompositeV2: Composite, useCompositeStoreV2: useCompositeStore } =
63
+ unlock( componentsPrivateApis );
64
+ const compositeStore = useCompositeStore();
46
65
  return ! presets ? null : (
47
- <Grid columns={ 6 } gap={ 0 } align="center" justify="center">
66
+ <Composite
67
+ store={ compositeStore }
68
+ role="listbox"
69
+ className="block-editor-global-styles__shadow__list"
70
+ aria-label={ __( 'Drop shadows' ) }
71
+ >
48
72
  { presets.map( ( { name, slug, shadow } ) => (
49
73
  <ShadowIndicator
50
74
  key={ slug }
51
75
  label={ name }
52
76
  isActive={ shadow === activeShadow }
77
+ type={ slug === 'unset' ? 'unset' : 'preset' }
53
78
  onSelect={ () =>
54
79
  onSelect( shadow === activeShadow ? undefined : shadow )
55
80
  }
56
81
  shadow={ shadow }
57
82
  />
58
83
  ) ) }
59
- </Grid>
84
+ </Composite>
60
85
  );
61
86
  }
62
87
 
63
- export function ShadowIndicator( { label, isActive, onSelect, shadow } ) {
88
+ export function ShadowIndicator( { type, label, isActive, onSelect, shadow } ) {
89
+ const { CompositeItemV2: CompositeItem } = unlock( componentsPrivateApis );
64
90
  return (
65
- <div className="block-editor-global-styles__shadow-indicator-wrapper">
66
- <Button
67
- className="block-editor-global-styles__shadow-indicator"
68
- onClick={ onSelect }
69
- label={ label }
70
- style={ { boxShadow: shadow } }
71
- showTooltip
72
- >
73
- { isActive && <Icon icon={ check } /> }
74
- </Button>
75
- </div>
91
+ <CompositeItem
92
+ role="option"
93
+ aria-label={ label }
94
+ aria-selected={ isActive }
95
+ className={ classNames(
96
+ 'block-editor-global-styles__shadow__item',
97
+ {
98
+ 'is-active': isActive,
99
+ }
100
+ ) }
101
+ render={
102
+ <Button
103
+ className={ classNames(
104
+ 'block-editor-global-styles__shadow-indicator',
105
+ {
106
+ unset: type === 'unset',
107
+ }
108
+ ) }
109
+ onClick={ onSelect }
110
+ label={ label }
111
+ style={ { boxShadow: shadow } }
112
+ showTooltip
113
+ >
114
+ { isActive && <Icon icon={ check } /> }
115
+ </Button>
116
+ }
117
+ />
76
118
  );
77
119
  }
78
120
 
@@ -123,3 +165,30 @@ function renderShadowToggle() {
123
165
  );
124
166
  };
125
167
  }
168
+
169
+ export function useShadowPresets( settings ) {
170
+ return useMemo( () => {
171
+ if ( ! settings?.shadow ) {
172
+ return EMPTY_ARRAY;
173
+ }
174
+
175
+ const defaultPresetsEnabled = settings?.shadow?.defaultPresets;
176
+ const { default: defaultShadows, theme: themeShadows } =
177
+ settings?.shadow?.presets ?? {};
178
+ const unsetShadow = {
179
+ name: __( 'Unset' ),
180
+ slug: 'unset',
181
+ shadow: 'none',
182
+ };
183
+
184
+ const shadowPresets = [
185
+ ...( ( defaultPresetsEnabled && defaultShadows ) || EMPTY_ARRAY ),
186
+ ...( themeShadows || EMPTY_ARRAY ),
187
+ ];
188
+ if ( shadowPresets.length ) {
189
+ shadowPresets.unshift( unsetShadow );
190
+ }
191
+
192
+ return shadowPresets;
193
+ }, [ settings ] );
194
+ }