From 17a8807a87bb5b372d1142a42f80522f32c9cf0d Mon Sep 17 00:00:00 2001 From: Steve Ross Date: Fri, 2 Jan 2026 20:21:33 +0000 Subject: [PATCH] block background image settings --- web/app/themes/badegg/app/blocks.php | 45 +++++++++ web/app/themes/badegg/resources/css/app.scss | 1 + .../resources/css/components/_block.scss | 15 +++ .../themes/badegg/resources/css/editor.scss | 4 + .../js/lib/blocks/AttachmentImage.jsx | 46 +++++++++ .../resources/js/lib/blocks/BlockSettings.jsx | 43 ++++++++ .../resources/js/lib/blocks/classNames.js | 3 + .../resources/views/blocks/article/block.json | 29 ------ .../resources/views/blocks/article/index.jsx | 99 +++++++++++++++++-- 9 files changed, 248 insertions(+), 37 deletions(-) create mode 100644 web/app/themes/badegg/resources/css/components/_block.scss create mode 100644 web/app/themes/badegg/resources/js/lib/blocks/AttachmentImage.jsx create mode 100644 web/app/themes/badegg/resources/js/lib/blocks/BlockSettings.jsx diff --git a/web/app/themes/badegg/app/blocks.php b/web/app/themes/badegg/app/blocks.php index 4607d8e..5f1e190 100644 --- a/web/app/themes/badegg/app/blocks.php +++ b/web/app/themes/badegg/app/blocks.php @@ -103,6 +103,51 @@ add_action('init', function () { 'style' => "{$slug}-style", 'script' => "{$slug}-script", 'view_script' => "{$slug}-view-script", + 'attributes' => [ + 'container_width' => [ + 'type' => 'string', + 'default' => '', + ], + 'alignment' => [ + 'type' => 'string', + ], + 'padding_top' => [ + 'type' => 'boolean', + 'default' => true + ], + 'padding_bottom' => [ + 'type' => 'boolean', + 'default' => true + ], + 'background_colour' => [ + 'type' => 'string', + 'default' => '', + ], + 'background_hex' => [ + 'type' => 'string', + 'default' => '', + ], + 'background_tint' => [ + 'type' => 'string', + 'default' => '0', + ], + 'background_image' => [ + 'type' => 'integer', + 'default' => 0, + ], + 'background_url' => [ + 'type' => 'string', + 'default' => '', + ], + 'background_opacity' => [ + 'type' => 'integer', + 'default' => 30 + ], + 'background_position' => [ + 'type' => 'string', + 'default' => '', + ], + ], ]; if(!property_exists($json, 'acf') && \Roots\view()->exists("blocks.{$slug}.render")) { diff --git a/web/app/themes/badegg/resources/css/app.scss b/web/app/themes/badegg/resources/css/app.scss index 8268514..5227b5e 100644 --- a/web/app/themes/badegg/resources/css/app.scss +++ b/web/app/themes/badegg/resources/css/app.scss @@ -14,6 +14,7 @@ @use "sections/footer"; // Components +@use "components/block"; @use "components/forms"; @use "components/button"; @use "components/card"; diff --git a/web/app/themes/badegg/resources/css/components/_block.scss b/web/app/themes/badegg/resources/css/components/_block.scss new file mode 100644 index 0000000..6714c50 --- /dev/null +++ b/web/app/themes/badegg/resources/css/components/_block.scss @@ -0,0 +1,15 @@ + + +.has-bg-image { + position: relative; + + >.container { + position: relative; + z-index: 1; + } + + .badegg-block-background { + position: absolute; + inset: 0; + } +} diff --git a/web/app/themes/badegg/resources/css/editor.scss b/web/app/themes/badegg/resources/css/editor.scss index f225c36..6ab781c 100644 --- a/web/app/themes/badegg/resources/css/editor.scss +++ b/web/app/themes/badegg/resources/css/editor.scss @@ -1,6 +1,10 @@ @use "app"; @use "global/variables/colours"; +html :where(.wp-block) { + max-width: none; +} + .block-editor-block-list__layout .block-editor-block-list__block:not([contenteditable=true]) { &:hover:after { content: ''; diff --git a/web/app/themes/badegg/resources/js/lib/blocks/AttachmentImage.jsx b/web/app/themes/badegg/resources/js/lib/blocks/AttachmentImage.jsx new file mode 100644 index 0000000..3e5f1f3 --- /dev/null +++ b/web/app/themes/badegg/resources/js/lib/blocks/AttachmentImage.jsx @@ -0,0 +1,46 @@ +import { useSelect } from '@wordpress/data'; + +/** + * AttachmentImage + * + * This component is used to display an image from the media library. + * It's meant as a JS companion to the PHP function `wp_get_attachment_image()`. + * + * @link https://www.briancoords.com/getting-wordpress-media-library-images-in-javascript/ + * + * @param {object} props + * @param {number} props.imageId The ID of the image to display. + * @param {string} props.size The size of the image to display. Defaults to 'full'. + * @returns {*} React JSX + */ +export default function AttachmentImage({ imageId, size = 'full' }) { + + const { image } = useSelect((select) => ({ + image: select('core').getEntityRecord('postType', 'attachment', imageId), + })); + + const imageAttributes = () =>{ + let attributes = { + src: image.source_url, + alt: image.alt_text, + className: `attachment-${size} size-${size}`, + width: image.media_details.width, + height: image.media_details.height, + }; + if (image.media_details && image.media_details.sizes && image.media_details.sizes[size]) { + attributes.src = image.media_details.sizes[size].source_url; + attributes.width = image.media_details.sizes[size].width; + attributes.height = image.media_details.sizes[size].height; + } + + return attributes; + }; + + return ( + <> + {image && ( + + )} + + ) +} diff --git a/web/app/themes/badegg/resources/js/lib/blocks/BlockSettings.jsx b/web/app/themes/badegg/resources/js/lib/blocks/BlockSettings.jsx new file mode 100644 index 0000000..4cbbfd2 --- /dev/null +++ b/web/app/themes/badegg/resources/js/lib/blocks/BlockSettings.jsx @@ -0,0 +1,43 @@ +import { useSelect } from '@wordpress/data'; + +/** + * BlockSettings + * + * Bundles the used for several blocks + * * + * @param {object} props + * @param {number} props.imageId The ID of the image to display. + * @param {string} props.size The size of the image to display. Defaults to 'full'. + * @returns {*} React JSX + */ +export default function BlockSettings({ imageId, size = 'full' }) { + + const { image } = useSelect((select) => ({ + image: select('core').getEntityRecord('postType', 'attachment', imageId), + })); + + const imageAttributes = () =>{ + let attributes = { + src: image.source_url, + alt: image.alt_text, + className: `attachment-${size} size-${size}`, + width: image.media_details.width, + height: image.media_details.height, + }; + if (image.media_details && image.media_details.sizes && image.media_details.sizes[size]) { + attributes.src = image.media_details.sizes[size].source_url; + attributes.width = image.media_details.sizes[size].width; + attributes.height = image.media_details.sizes[size].height; + } + + return attributes; + }; + + return ( + <> + {image && ( + + )} + + ) +} diff --git a/web/app/themes/badegg/resources/js/lib/blocks/classNames.js b/web/app/themes/badegg/resources/js/lib/blocks/classNames.js index 2f07a8d..dd73d16 100644 --- a/web/app/themes/badegg/resources/js/lib/blocks/classNames.js +++ b/web/app/themes/badegg/resources/js/lib/blocks/classNames.js @@ -42,6 +42,9 @@ export function sectionClassNames(attributes, defaultClasses, extraClasses = []) classNames.push(bg); } + if('background_image'in attributes && attributes.background_image != '0') + classNames.push('has-bg-image'); + // combine arrays classNames = classNames.concat(defaultClasses).concat(extraClasses); diff --git a/web/app/themes/badegg/resources/views/blocks/article/block.json b/web/app/themes/badegg/resources/views/blocks/article/block.json index 30c1840..2f60303 100644 --- a/web/app/themes/badegg/resources/views/blocks/article/block.json +++ b/web/app/themes/badegg/resources/views/blocks/article/block.json @@ -8,35 +8,6 @@ "foreground": "#f58762" }, "description": "A wrapper to contain core blocks", - "attributes": { - "container_width": { - "type": "string", - "default": "" - }, - "alignment": { - "type": "string" - }, - "padding_top": { - "type": "boolean", - "default": true - }, - "padding_bottom": { - "type": "boolean", - "default": true - }, - "background_colour": { - "type": "string", - "default": "" - }, - "background_hex": { - "type": "string", - "default": "" - }, - "background_tint": { - "type": "string", - "default": "0" - } - }, "supports": { "html": true, "color": { diff --git a/web/app/themes/badegg/resources/views/blocks/article/index.jsx b/web/app/themes/badegg/resources/views/blocks/article/index.jsx index 4b9a1d6..3c9bf8f 100644 --- a/web/app/themes/badegg/resources/views/blocks/article/index.jsx +++ b/web/app/themes/badegg/resources/views/blocks/article/index.jsx @@ -2,6 +2,7 @@ import { __ } from '@wordpress/i18n'; import { registerBlockType } from '@wordpress/blocks'; +import { useSelect } from '@wordpress/data'; import { useBlockProps, @@ -9,6 +10,8 @@ import { InspectorControls, BlockControls, AlignmentToolbar, + MediaUpload, + MediaUploadCheck, } from '@wordpress/block-editor'; import { @@ -17,15 +20,20 @@ import { PanelRow, SelectControl, ToggleControl, - ColorIndicator, + RangeControl, ColorPalette, + Button, } from '@wordpress/components'; +// import { Image } from '@10up/block-components'; + import { useState, useEffect } from '@wordpress/element'; -import apiFetch from '@wordpress/api-fetch'; import metadata from './block.json'; import allowedBlocks from '../../../json/core-block-whitelist.json'; import { containerClassNames, sectionClassNames } from '../../../js/lib/blocks/classNames'; +import AttachmentImage from '../../../js/lib/blocks/AttachmentImage'; + +import apiFetch from '@wordpress/api-fetch'; registerBlockType(metadata.name, { edit({ attributes, setAttributes }) { @@ -40,6 +48,10 @@ registerBlockType(metadata.name, { background_colour, background_hex, background_tint, + background_image, + background_url, + background_position, + background_opacity, } = attributes; const [ @@ -76,7 +88,7 @@ registerBlockType(metadata.name, { /> - + setAttributes({ padding_top: value }) } __nextHasNoMarginBottom /> setAttributes({ padding_bottom: value }) } __nextHasNoMarginBottom /> - + +

+ { __('Colour', 'badegg') } +

{ let slug, hex, selected = ''; @@ -127,9 +147,9 @@ registerBlockType(metadata.name, { } } /> - { 'background_colour' in attributes && attributes.background_colour ? ( + { 'background_colour' in attributes && attributes.background_colour && ![0, '0', 'white', 'black'].includes(attributes.background_colour) ? ( setAttributes({ background_tint: value }) } @@ -138,6 +158,57 @@ registerBlockType(metadata.name, { /> ) : null } + { background_image != 0 && ( + <> + + setAttributes({ background_opacity: value }) } + min={ 5 } + max={ 100 } + /> + + )} + + + + { + setAttributes({ + background_image: media.id, + background_url: media.url, + }); + }} + allowedTypes={ ['image'] } + value={ background_image } + render={ ({ open }) => ( + + )} + /> + + + { background_image != 0 && ( + + )} + +
@@ -154,6 +225,18 @@ registerBlockType(metadata.name, { } /> + + { attributes.background_image != 0 && ( +
+ ) } +
); },