diff --git a/packages/block-library/src/legacy-widget/edit/form.js b/packages/block-library/src/legacy-widget/edit/form.js
index cae1bab7010758..eb8abefb6dc586 100644
--- a/packages/block-library/src/legacy-widget/edit/form.js
+++ b/packages/block-library/src/legacy-widget/edit/form.js
@@ -1,3 +1,7 @@
+/**
+ * External dependencies
+ */
+import classnames from 'classnames';
/**
* WordPress dependencies
*/
@@ -5,7 +9,8 @@ import { useRef, useEffect } from '@wordpress/element';
import { useDispatch } from '@wordpress/data';
import { store as noticesStore } from '@wordpress/notices';
import { __ } from '@wordpress/i18n';
-
+import { Popover } from '@wordpress/components';
+import { useViewportMatch } from '@wordpress/compose';
/**
* Internal dependencies
*/
@@ -17,11 +22,14 @@ export default function Form( {
id,
idBase,
instance,
+ isWide,
onChangeInstance,
onChangeHasPreview,
} ) {
const ref = useRef();
+ const isMediumLargeViewport = useViewportMatch( 'small' );
+
// We only want to remount the control when the instance changes
// *externally*. For example, if the user performs an undo. To do this, we
// keep track of changes made to instance by the control itself and then
@@ -68,7 +76,41 @@ export default function Form( {
control.destroy();
};
- }, [ id, idBase, instance, onChangeInstance, onChangeHasPreview ] );
+ }, [
+ id,
+ idBase,
+ instance,
+ onChangeInstance,
+ onChangeHasPreview,
+ isMediumLargeViewport,
+ ] );
+
+ if ( isWide && isMediumLargeViewport ) {
+ return (
+
+ { isVisible && (
+
+ { title }
+
+ ) }
+
+
+
+
+ );
+ }
return (
+
{ ! id && ! idBase ? (
) : (
@@ -77,6 +90,7 @@ function NotEmpty( {
setAttributes,
clientId,
isSelected,
+ isWide = false,
} ) {
const [ hasPreview, setHasPreview ] = useState( null );
@@ -168,6 +182,7 @@ function NotEmpty( {
id={ id }
idBase={ idBase }
instance={ instance }
+ isWide={ isWide }
onChangeInstance={ setInstance }
onChangeHasPreview={ setHasPreview }
/>
diff --git a/packages/block-library/src/legacy-widget/editor.scss b/packages/block-library/src/legacy-widget/editor.scss
index 1282f2a528be1d..710e4d905879cf 100644
--- a/packages/block-library/src/legacy-widget/editor.scss
+++ b/packages/block-library/src/legacy-widget/editor.scss
@@ -86,3 +86,11 @@
margin: 0 0 5px;
font-weight: 500;
}
+
+// When wide widget is selected it opens in a popover but its container should still have a bit of height.
+.is-selected {
+ .wp-block-legacy-widget__container {
+ padding: $grid-unit-10 $grid-unit-15;
+ min-height: 50px;
+ }
+}
diff --git a/packages/components/src/popover/index.js b/packages/components/src/popover/index.js
index fa29974e28cf86..3d2d3e650c4e84 100644
--- a/packages/components/src/popover/index.js
+++ b/packages/components/src/popover/index.js
@@ -261,6 +261,7 @@ const Popover = (
__unstableObserveElement,
__unstableBoundaryParent,
__unstableForcePosition,
+ __unstableForceXAlignment,
/* eslint-enable no-unused-vars */
...contentProps
},
@@ -354,7 +355,8 @@ const Popover = (
containerRef.current,
relativeOffsetTop,
boundaryElement,
- __unstableForcePosition
+ __unstableForcePosition,
+ __unstableForceXAlignment
);
if (
diff --git a/packages/components/src/popover/utils.js b/packages/components/src/popover/utils.js
index 3d23ae71fb211c..f7021198085a21 100644
--- a/packages/components/src/popover/utils.js
+++ b/packages/components/src/popover/utils.js
@@ -21,6 +21,7 @@ const HEIGHT_OFFSET = 10; // used by the arrow and a bit of empty space
* @param {string} chosenYAxis yAxis to be used.
* @param {Element} boundaryElement Boundary element.
* @param {boolean} forcePosition Don't adjust position based on anchor.
+ * @param {boolean} forceXAlignment Don't adjust alignment based on YAxis
*
* @return {Object} Popover xAxis position and constraints.
*/
@@ -32,7 +33,8 @@ export function computePopoverXAxisPosition(
stickyBoundaryElement,
chosenYAxis,
boundaryElement,
- forcePosition
+ forcePosition,
+ forceXAlignment
) {
const { width } = contentSize;
@@ -64,7 +66,7 @@ export function computePopoverXAxisPosition(
if ( corner === 'right' ) {
leftAlignmentX = anchorRect.right;
- } else if ( chosenYAxis !== 'middle' ) {
+ } else if ( chosenYAxis !== 'middle' && ! forceXAlignment ) {
leftAlignmentX = anchorMidPoint;
}
@@ -72,7 +74,7 @@ export function computePopoverXAxisPosition(
if ( corner === 'left' ) {
rightAlignmentX = anchorRect.left;
- } else if ( chosenYAxis !== 'middle' ) {
+ } else if ( chosenYAxis !== 'middle' && ! forceXAlignment ) {
rightAlignmentX = anchorMidPoint;
}
@@ -285,6 +287,7 @@ export function computePopoverYAxisPosition(
* relative positioned parent container.
* @param {Element} boundaryElement Boundary element.
* @param {boolean} forcePosition Don't adjust position based on anchor.
+ * @param {boolean} forceXAlignment Don't adjust alignment based on YAxis
*
* @return {Object} Popover position and constraints.
*/
@@ -296,7 +299,8 @@ export function computePopoverPosition(
anchorRef,
relativeOffsetTop,
boundaryElement,
- forcePosition
+ forcePosition,
+ forceXAlignment
) {
const [ yAxis, xAxis = 'center', corner ] = position.split( ' ' );
@@ -318,7 +322,8 @@ export function computePopoverPosition(
stickyBoundaryElement,
yAxisPosition.yAxis,
boundaryElement,
- forcePosition
+ forcePosition,
+ forceXAlignment
);
return {
diff --git a/packages/customize-widgets/src/filters/index.js b/packages/customize-widgets/src/filters/index.js
index fdae4d488b83d2..07b68a610103ab 100644
--- a/packages/customize-widgets/src/filters/index.js
+++ b/packages/customize-widgets/src/filters/index.js
@@ -3,3 +3,4 @@
*/
import './move-to-sidebar';
import './replace-media-upload';
+import './wide-widget-display';
diff --git a/packages/customize-widgets/src/filters/wide-widget-display.js b/packages/customize-widgets/src/filters/wide-widget-display.js
new file mode 100644
index 00000000000000..abcaa3514b640e
--- /dev/null
+++ b/packages/customize-widgets/src/filters/wide-widget-display.js
@@ -0,0 +1,26 @@
+/**
+ * WordPress dependencies
+ */
+import { createHigherOrderComponent } from '@wordpress/compose';
+import { addFilter } from '@wordpress/hooks';
+
+const { wp } = window;
+
+const withWideWidgetDisplay = createHigherOrderComponent(
+ ( BlockEdit ) => ( props ) => {
+ const { idBase } = props.attributes;
+ const isWide =
+ wp.customize.Widgets.data.availableWidgets.find(
+ ( widget ) => widget.id_base === idBase
+ )?.is_wide ?? false;
+
+ return ;
+ },
+ 'withWideWidgetDisplay'
+);
+
+addFilter(
+ 'editor.BlockEdit',
+ 'core/customize-widgets/wide-widget-display',
+ withWideWidgetDisplay
+);