block background image settings
This commit is contained in:
@@ -103,6 +103,51 @@ add_action('init', function () {
|
|||||||
'style' => "{$slug}-style",
|
'style' => "{$slug}-style",
|
||||||
'script' => "{$slug}-script",
|
'script' => "{$slug}-script",
|
||||||
'view_script' => "{$slug}-view-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")) {
|
if(!property_exists($json, 'acf') && \Roots\view()->exists("blocks.{$slug}.render")) {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
@use "sections/footer";
|
@use "sections/footer";
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
|
@use "components/block";
|
||||||
@use "components/forms";
|
@use "components/forms";
|
||||||
@use "components/button";
|
@use "components/button";
|
||||||
@use "components/card";
|
@use "components/card";
|
||||||
|
|||||||
15
resources/css/components/_block.scss
Normal file
15
resources/css/components/_block.scss
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
|
||||||
|
.has-bg-image {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
>.container {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badegg-block-background {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
@use "app";
|
@use "app";
|
||||||
@use "global/variables/colours";
|
@use "global/variables/colours";
|
||||||
|
|
||||||
|
html :where(.wp-block) {
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
.block-editor-block-list__layout .block-editor-block-list__block:not([contenteditable=true]) {
|
.block-editor-block-list__layout .block-editor-block-list__block:not([contenteditable=true]) {
|
||||||
&:hover:after {
|
&:hover:after {
|
||||||
content: '';
|
content: '';
|
||||||
|
|||||||
46
resources/js/lib/blocks/AttachmentImage.jsx
Normal file
46
resources/js/lib/blocks/AttachmentImage.jsx
Normal file
@@ -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 && (
|
||||||
|
<img {...imageAttributes()} />
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
43
resources/js/lib/blocks/BlockSettings.jsx
Normal file
43
resources/js/lib/blocks/BlockSettings.jsx
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { useSelect } from '@wordpress/data';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BlockSettings
|
||||||
|
*
|
||||||
|
* Bundles the <InspectorControls> 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 && (
|
||||||
|
<img {...imageAttributes()} />
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -42,6 +42,9 @@ export function sectionClassNames(attributes, defaultClasses, extraClasses = [])
|
|||||||
classNames.push(bg);
|
classNames.push(bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if('background_image'in attributes && attributes.background_image != '0')
|
||||||
|
classNames.push('has-bg-image');
|
||||||
|
|
||||||
// combine arrays
|
// combine arrays
|
||||||
classNames = classNames.concat(defaultClasses).concat(extraClasses);
|
classNames = classNames.concat(defaultClasses).concat(extraClasses);
|
||||||
|
|
||||||
|
|||||||
@@ -8,35 +8,6 @@
|
|||||||
"foreground": "#f58762"
|
"foreground": "#f58762"
|
||||||
},
|
},
|
||||||
"description": "A wrapper to contain core blocks",
|
"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": {
|
"supports": {
|
||||||
"html": true,
|
"html": true,
|
||||||
"color": {
|
"color": {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { registerBlockType } from '@wordpress/blocks';
|
import { registerBlockType } from '@wordpress/blocks';
|
||||||
|
import { useSelect } from '@wordpress/data';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
useBlockProps,
|
useBlockProps,
|
||||||
@@ -9,6 +10,8 @@ import {
|
|||||||
InspectorControls,
|
InspectorControls,
|
||||||
BlockControls,
|
BlockControls,
|
||||||
AlignmentToolbar,
|
AlignmentToolbar,
|
||||||
|
MediaUpload,
|
||||||
|
MediaUploadCheck,
|
||||||
} from '@wordpress/block-editor';
|
} from '@wordpress/block-editor';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -17,15 +20,20 @@ import {
|
|||||||
PanelRow,
|
PanelRow,
|
||||||
SelectControl,
|
SelectControl,
|
||||||
ToggleControl,
|
ToggleControl,
|
||||||
ColorIndicator,
|
RangeControl,
|
||||||
ColorPalette,
|
ColorPalette,
|
||||||
|
Button,
|
||||||
} from '@wordpress/components';
|
} from '@wordpress/components';
|
||||||
|
|
||||||
|
// import { Image } from '@10up/block-components';
|
||||||
|
|
||||||
import { useState, useEffect } from '@wordpress/element';
|
import { useState, useEffect } from '@wordpress/element';
|
||||||
import apiFetch from '@wordpress/api-fetch';
|
|
||||||
import metadata from './block.json';
|
import metadata from './block.json';
|
||||||
import allowedBlocks from '../../../json/core-block-whitelist.json';
|
import allowedBlocks from '../../../json/core-block-whitelist.json';
|
||||||
import { containerClassNames, sectionClassNames } from '../../../js/lib/blocks/classNames';
|
import { containerClassNames, sectionClassNames } from '../../../js/lib/blocks/classNames';
|
||||||
|
import AttachmentImage from '../../../js/lib/blocks/AttachmentImage';
|
||||||
|
|
||||||
|
import apiFetch from '@wordpress/api-fetch';
|
||||||
|
|
||||||
registerBlockType(metadata.name, {
|
registerBlockType(metadata.name, {
|
||||||
edit({ attributes, setAttributes }) {
|
edit({ attributes, setAttributes }) {
|
||||||
@@ -40,6 +48,10 @@ registerBlockType(metadata.name, {
|
|||||||
background_colour,
|
background_colour,
|
||||||
background_hex,
|
background_hex,
|
||||||
background_tint,
|
background_tint,
|
||||||
|
background_image,
|
||||||
|
background_url,
|
||||||
|
background_position,
|
||||||
|
background_opacity,
|
||||||
} = attributes;
|
} = attributes;
|
||||||
|
|
||||||
const [
|
const [
|
||||||
@@ -76,7 +88,7 @@ registerBlockType(metadata.name, {
|
|||||||
/>
|
/>
|
||||||
</BlockControls>
|
</BlockControls>
|
||||||
<InspectorControls>
|
<InspectorControls>
|
||||||
<Panel>
|
<Panel className="badegg-components-panel">
|
||||||
<PanelBody title={ __("Settings", "badegg") }>
|
<PanelBody title={ __("Settings", "badegg") }>
|
||||||
<SelectControl
|
<SelectControl
|
||||||
label={ __("Container Width", "badegg") }
|
label={ __("Container Width", "badegg") }
|
||||||
@@ -87,23 +99,31 @@ registerBlockType(metadata.name, {
|
|||||||
__nextHasNoMarginBottom={ true }
|
__nextHasNoMarginBottom={ true }
|
||||||
/>
|
/>
|
||||||
<ToggleControl
|
<ToggleControl
|
||||||
label={ __('Top Padding', 'badegg') }
|
label={ __('Top padding', 'badegg') }
|
||||||
checked={ padding_top }
|
checked={ padding_top }
|
||||||
onChange={(value) => setAttributes({ padding_top: value }) }
|
onChange={(value) => setAttributes({ padding_top: value }) }
|
||||||
__nextHasNoMarginBottom
|
__nextHasNoMarginBottom
|
||||||
/>
|
/>
|
||||||
<ToggleControl
|
<ToggleControl
|
||||||
label={ __('Bottom Padding', 'badegg') }
|
label={ __('Bottom padding', 'badegg') }
|
||||||
checked={ padding_bottom }
|
checked={ padding_bottom }
|
||||||
onChange={(value) => setAttributes({ padding_bottom: value }) }
|
onChange={(value) => setAttributes({ padding_bottom: value }) }
|
||||||
__nextHasNoMarginBottom
|
__nextHasNoMarginBottom
|
||||||
/>
|
/>
|
||||||
</PanelBody>
|
</PanelBody>
|
||||||
<PanelBody title={ __("Background Colour", "badegg") }>
|
<PanelBody
|
||||||
|
title={ __("Background", "badegg") }
|
||||||
|
initialOpen={ false }
|
||||||
|
>
|
||||||
|
<p style={{ textTransform: 'uppercase', fontSize: '11px' }} className="components-truncate components-text components-input-control__label">
|
||||||
|
{ __('Colour', 'badegg') }
|
||||||
|
</p>
|
||||||
<ColorPalette
|
<ColorPalette
|
||||||
colors={ configOptions.colours }
|
colors={ configOptions.colours }
|
||||||
value={ background_hex }
|
value={ background_hex }
|
||||||
|
clearable={ false }
|
||||||
disableCustomColors={ true }
|
disableCustomColors={ true }
|
||||||
|
style={{ marginBottom: '16px' }}
|
||||||
onChange={ ( value ) => {
|
onChange={ ( value ) => {
|
||||||
let slug, hex, selected = '';
|
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) ? (
|
||||||
<SelectControl
|
<SelectControl
|
||||||
label={ __("Tint", "badegg") }
|
label={ __("Background Tint", "badegg") }
|
||||||
value={ background_tint }
|
value={ background_tint }
|
||||||
options={ configOptions.tints }
|
options={ configOptions.tints }
|
||||||
onChange={ (value) => setAttributes({ background_tint: value }) }
|
onChange={ (value) => setAttributes({ background_tint: value }) }
|
||||||
@@ -138,6 +158,57 @@ registerBlockType(metadata.name, {
|
|||||||
/>
|
/>
|
||||||
) : null }
|
) : null }
|
||||||
|
|
||||||
|
{ background_image != 0 && (
|
||||||
|
<>
|
||||||
|
<AttachmentImage
|
||||||
|
imageId={ background_image }
|
||||||
|
size="thumbnail"
|
||||||
|
/>
|
||||||
|
<RangeControl
|
||||||
|
__next40pxDefaultSize
|
||||||
|
__nextHasNoMarginBottom
|
||||||
|
label={ __("Opacity", "badegg") }
|
||||||
|
value={ background_opacity }
|
||||||
|
onChange={ ( value ) => setAttributes({ background_opacity: value }) }
|
||||||
|
min={ 5 }
|
||||||
|
max={ 100 }
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<PanelRow>
|
||||||
|
<MediaUploadCheck>
|
||||||
|
<MediaUpload
|
||||||
|
onSelect={ (media) => {
|
||||||
|
setAttributes({
|
||||||
|
background_image: media.id,
|
||||||
|
background_url: media.url,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
allowedTypes={ ['image'] }
|
||||||
|
value={ background_image }
|
||||||
|
render={ ({ open }) => (
|
||||||
|
<Button
|
||||||
|
onClick={ open }
|
||||||
|
variant="primary"
|
||||||
|
>
|
||||||
|
{ background_image ? __("Replace image", "badegg") : __("Choose image", "badegg") }
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</MediaUploadCheck>
|
||||||
|
|
||||||
|
{ background_image != 0 && (
|
||||||
|
<Button
|
||||||
|
onClick={ () => setAttributes({ background_image: 0 }) }
|
||||||
|
isDestructive
|
||||||
|
variant="secondary"
|
||||||
|
>
|
||||||
|
{ __("Remove image", "badegg") }
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</PanelRow>
|
||||||
|
|
||||||
</PanelBody>
|
</PanelBody>
|
||||||
</Panel>
|
</Panel>
|
||||||
</InspectorControls>
|
</InspectorControls>
|
||||||
@@ -154,6 +225,18 @@ registerBlockType(metadata.name, {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{ attributes.background_image != 0 && (
|
||||||
|
<div
|
||||||
|
className="badegg-block-background"
|
||||||
|
style={{
|
||||||
|
backgroundImage: `url(${background_url})`,
|
||||||
|
backgroundPosition: background_position,
|
||||||
|
opacity: Number(background_opacity) * 0.01,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) }
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user