From 6c9bbce95728203215a81ee34b70c7a1a2490917 Mon Sep 17 00:00:00 2001
From: Andrew Serong <14988353+andrewserong@users.noreply.github.com>
Date: Fri, 2 Feb 2024 16:06:15 +1100
Subject: [PATCH 1/3] Background image support: Try adding background position
controls
---
packages/block-editor/src/hooks/background.js | 81 +++++++++++++++++++
.../src/styles/background/index.ts | 19 ++++-
2 files changed, 99 insertions(+), 1 deletion(-)
diff --git a/packages/block-editor/src/hooks/background.js b/packages/block-editor/src/hooks/background.js
index d093d3da55c8d..5843526ef47e6 100644
--- a/packages/block-editor/src/hooks/background.js
+++ b/packages/block-editor/src/hooks/background.js
@@ -18,6 +18,7 @@ import {
__experimentalVStack as VStack,
DropZone,
FlexItem,
+ FocalPointPicker,
MenuItem,
VisuallyHidden,
__experimentalItemGroup as ItemGroup,
@@ -367,6 +368,64 @@ function backgroundSizeHelpText( value ) {
return __( 'Set a fixed width.' );
}
+const coordsToBackgroundPosition = ( value ) => {
+ if ( ! value ) {
+ return undefined;
+ }
+
+ if ( value.x === 0 && value.y === 0 ) {
+ return 'left top';
+ }
+
+ if ( value.x === 0 && value.y === 1 ) {
+ return 'left bottom';
+ }
+
+ if ( value.x === 1 && value.y === 0 ) {
+ return 'right top';
+ }
+
+ if ( value.x === 1 && value.y === 1 ) {
+ return 'right bottom';
+ }
+
+ if ( value.x === 0.5 && value.y === 0.5 ) {
+ return 'center';
+ }
+
+ return `${ value.x * 100 }% ${ value.y * 100 }%`;
+};
+
+const backgroundPositionToCoords = ( value ) => {
+ if ( ! value ) {
+ return { x: 0.5, y: 0.5 };
+ }
+
+ if ( value === 'left top' ) {
+ return { x: 0, y: 0 };
+ }
+
+ if ( value === 'left bottom' ) {
+ return { x: 0, y: 1 };
+ }
+
+ if ( value === 'right top' ) {
+ return { x: 1, y: 0 };
+ }
+
+ if ( value === 'right bottom' ) {
+ return { x: 1, y: 1 };
+ }
+
+ if ( value === 'center' ) {
+ return { x: 0.5, y: 0.5 };
+ }
+
+ const [ x, y ] = value.split( ' ' ).map( ( v ) => parseFloat( v ) / 100 );
+
+ return { x, y };
+};
+
function BackgroundSizePanelItem( {
clientId,
isShownByDefault,
@@ -446,6 +505,18 @@ function BackgroundSizePanelItem( {
} );
};
+ const updateBackgroundPosition = ( next ) => {
+ setAttributes( {
+ style: cleanEmptyObject( {
+ ...style,
+ background: {
+ ...style?.background,
+ backgroundPosition: coordsToBackgroundPosition( next ),
+ },
+ } ),
+ } );
+ };
+
const toggleIsRepeated = () => {
setAttributes( {
style: cleanEmptyObject( {
@@ -471,6 +542,16 @@ function BackgroundSizePanelItem( {
resetAllFilter={ resetAllFilter }
panelId={ clientId }
>
+
{
+ return generateRule(
+ style,
+ options,
+ [ 'background', 'backgroundPosition' ],
+ 'backgroundPosition'
+ );
+ },
+};
+
const backgroundSize = {
name: 'backgroundSize',
generate: ( style: Style, options: StyleOptions ) => {
@@ -89,4 +101,9 @@ const backgroundSize = {
},
};
-export default [ backgroundImage, backgroundRepeat, backgroundSize ];
+export default [
+ backgroundImage,
+ backgroundRepeat,
+ backgroundPosition,
+ backgroundSize,
+];
From d9d87ba23f4604f1e7520ddc6e50f1fbce36f395 Mon Sep 17 00:00:00 2001
From: Andrew Serong <14988353+andrewserong@users.noreply.github.com>
Date: Mon, 5 Feb 2024 14:44:40 +1100
Subject: [PATCH 2/3] Fix reset and hasValue logic, add tests, update label
---
packages/block-editor/src/hooks/background.js | 63 +++++--------------
.../block-editor/src/hooks/test/background.js | 50 +++++++++++++++
.../src/styles/background/index.ts | 14 ++---
packages/style-engine/src/test/index.js | 6 ++
4 files changed, 78 insertions(+), 55 deletions(-)
create mode 100644 packages/block-editor/src/hooks/test/background.js
diff --git a/packages/block-editor/src/hooks/background.js b/packages/block-editor/src/hooks/background.js
index 5843526ef47e6..9524564b487ec 100644
--- a/packages/block-editor/src/hooks/background.js
+++ b/packages/block-editor/src/hooks/background.js
@@ -60,13 +60,17 @@ export function hasBackgroundImageValue( style ) {
/**
* Checks if there is a current value in the background size block support
- * attributes.
+ * attributes. Background size values include background size as well
+ * as background position.
*
* @param {Object} style Style attribute.
* @return {boolean} Whether or not the block has a background size value set.
*/
export function hasBackgroundSizeValue( style ) {
- return style?.background?.backgroundSize !== undefined;
+ return (
+ style?.background?.backgroundPosition !== undefined ||
+ style?.background?.backgroundSize !== undefined
+ );
}
/**
@@ -131,6 +135,7 @@ function resetBackgroundSize( style = {}, setAttributes ) {
...style,
background: {
...style?.background,
+ backgroundPosition: undefined,
backgroundRepeat: undefined,
backgroundSize: undefined,
},
@@ -368,60 +373,22 @@ function backgroundSizeHelpText( value ) {
return __( 'Set a fixed width.' );
}
-const coordsToBackgroundPosition = ( value ) => {
- if ( ! value ) {
+export const coordsToBackgroundPosition = ( value ) => {
+ if ( ! value || isNaN( value.x ) || isNaN( value.y ) ) {
return undefined;
}
- if ( value.x === 0 && value.y === 0 ) {
- return 'left top';
- }
-
- if ( value.x === 0 && value.y === 1 ) {
- return 'left bottom';
- }
-
- if ( value.x === 1 && value.y === 0 ) {
- return 'right top';
- }
-
- if ( value.x === 1 && value.y === 1 ) {
- return 'right bottom';
- }
-
- if ( value.x === 0.5 && value.y === 0.5 ) {
- return 'center';
- }
-
return `${ value.x * 100 }% ${ value.y * 100 }%`;
};
-const backgroundPositionToCoords = ( value ) => {
+export const backgroundPositionToCoords = ( value ) => {
if ( ! value ) {
- return { x: 0.5, y: 0.5 };
- }
-
- if ( value === 'left top' ) {
- return { x: 0, y: 0 };
- }
-
- if ( value === 'left bottom' ) {
- return { x: 0, y: 1 };
- }
-
- if ( value === 'right top' ) {
- return { x: 1, y: 0 };
- }
-
- if ( value === 'right bottom' ) {
- return { x: 1, y: 1 };
- }
-
- if ( value === 'center' ) {
- return { x: 0.5, y: 0.5 };
+ return { x: undefined, y: undefined };
}
- const [ x, y ] = value.split( ' ' ).map( ( v ) => parseFloat( v ) / 100 );
+ let [ x, y ] = value.split( ' ' ).map( ( v ) => parseFloat( v ) / 100 );
+ x = isNaN( x ) ? undefined : x;
+ y = isNaN( y ) ? x : y;
return { x, y };
};
@@ -545,7 +512,7 @@ function BackgroundSizePanelItem( {
{
+ it( 'should return the correct coordinates for a percentage value using 2-value syntax', () => {
+ expect( backgroundPositionToCoords( '25% 75%' ) ).toEqual( {
+ x: 0.25,
+ y: 0.75,
+ } );
+ } );
+
+ it( 'should return the correct coordinates for a percentage using 1-value syntax', () => {
+ expect( backgroundPositionToCoords( '50%' ) ).toEqual( {
+ x: 0.5,
+ y: 0.5,
+ } );
+ } );
+
+ it( 'should return undefined coords in given an empty value', () => {
+ expect( backgroundPositionToCoords( '' ) ).toEqual( {
+ x: undefined,
+ y: undefined,
+ } );
+ } );
+
+ it( 'should return undefined coords in given a string that cannot be converted', () => {
+ expect( backgroundPositionToCoords( 'apples' ) ).toEqual( {
+ x: undefined,
+ y: undefined,
+ } );
+ } );
+} );
+
+describe( 'coordsToBackgroundPosition', () => {
+ it( 'should return the correct background position for a set of coordinates', () => {
+ expect( coordsToBackgroundPosition( { x: 0.25, y: 0.75 } ) ).toBe(
+ '25% 75%'
+ );
+ } );
+
+ it( 'should return undefined if no coordinates are provided', () => {
+ expect( coordsToBackgroundPosition( {} ) ).toBeUndefined();
+ } );
+} );
diff --git a/packages/style-engine/src/styles/background/index.ts b/packages/style-engine/src/styles/background/index.ts
index 1cb36fbf0dcad..8ce8c7d577fb2 100644
--- a/packages/style-engine/src/styles/background/index.ts
+++ b/packages/style-engine/src/styles/background/index.ts
@@ -40,26 +40,26 @@ const backgroundImage = {
},
};
-const backgroundRepeat = {
+const backgroundPosition = {
name: 'backgroundRepeat',
generate: ( style: Style, options: StyleOptions ) => {
return generateRule(
style,
options,
- [ 'background', 'backgroundRepeat' ],
- 'backgroundRepeat'
+ [ 'background', 'backgroundPosition' ],
+ 'backgroundPosition'
);
},
};
-const backgroundPosition = {
+const backgroundRepeat = {
name: 'backgroundRepeat',
generate: ( style: Style, options: StyleOptions ) => {
return generateRule(
style,
options,
- [ 'background', 'backgroundPosition' ],
- 'backgroundPosition'
+ [ 'background', 'backgroundRepeat' ],
+ 'backgroundRepeat'
);
},
};
@@ -103,7 +103,7 @@ const backgroundSize = {
export default [
backgroundImage,
- backgroundRepeat,
backgroundPosition,
+ backgroundRepeat,
backgroundSize,
];
diff --git a/packages/style-engine/src/test/index.js b/packages/style-engine/src/test/index.js
index 1727ed535897b..b679775d3f37f 100644
--- a/packages/style-engine/src/test/index.js
+++ b/packages/style-engine/src/test/index.js
@@ -229,6 +229,7 @@ describe( 'getCSSRules', () => {
source: 'file',
url: 'https://example.com/image.jpg',
},
+ backgroundPosition: '50% 50%',
backgroundRepeat: 'no-repeat',
backgroundSize: '300px',
},
@@ -384,6 +385,11 @@ describe( 'getCSSRules', () => {
key: 'backgroundImage',
value: "url( 'https://example.com/image.jpg' )",
},
+ {
+ selector: '.some-selector',
+ key: 'backgroundPosition',
+ value: '50% 50%',
+ },
{
selector: '.some-selector',
key: 'backgroundRepeat',
From 5af7895c8a21ed9842364bf56874d735f685c165 Mon Sep 17 00:00:00 2001
From: Andrew Serong <14988353+andrewserong@users.noreply.github.com>
Date: Tue, 6 Feb 2024 13:48:15 +1100
Subject: [PATCH 3/3] Ensure default position of focal point picker control is
centered
---
packages/components/CHANGELOG.md | 1 +
packages/components/src/focal-point-picker/index.tsx | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md
index 94f69636b3e05..3c4dd1e29476c 100644
--- a/packages/components/CHANGELOG.md
+++ b/packages/components/CHANGELOG.md
@@ -9,6 +9,7 @@
### Bug Fix
+- `FocalPointPicker`: Allow `PointerCircle` to render in a default centered position when x and y coordinates are undefined ([#58592](https://github.com/WordPress/gutenberg/pull/58592)).
- `DateTime`: Add a timezone offset value for display purposes. ([#56682](https://github.com/WordPress/gutenberg/pull/56682)).
- `Placeholder`: Fix Placeholder component padding when body text font size is changed ([#58323](https://github.com/WordPress/gutenberg/pull/58323)).
- `Placeholder`: Fix Global Styles typography settings bleeding into placeholder component ([#58303](https://github.com/WordPress/gutenberg/pull/58303)).
diff --git a/packages/components/src/focal-point-picker/index.tsx b/packages/components/src/focal-point-picker/index.tsx
index 1b4c4d9dff966..33fd505f67fe1 100644
--- a/packages/components/src/focal-point-picker/index.tsx
+++ b/packages/components/src/focal-point-picker/index.tsx
@@ -217,8 +217,8 @@ export function FocalPointPicker( {
};
const focalPointPosition = {
- left: x * bounds.width,
- top: y * bounds.height,
+ left: x !== undefined ? x * bounds.width : 0.5 * bounds.width,
+ top: y !== undefined ? y * bounds.height : 0.5 * bounds.height,
};
const classes = classnames(