FEATURE Extending block features with border and background shape refactoring into dedicated components
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Antoine M 2025-11-25 15:08:14 +01:00
parent 77e3a3c62e
commit 05c48e2779
5 changed files with 254 additions and 153 deletions

View File

@ -9,7 +9,12 @@
"description": "Example block scaffolded with Create Block tool.", "description": "Example block scaffolded with Create Block tool.",
"example": {}, "example": {},
"supports": { "supports": {
"html": false "html": false,
"border": {
"color": true,
"style": true,
"width": true
}
}, },
"textdomain": "carhop-blocks", "textdomain": "carhop-blocks",
"editorScript": "file:./index.js", "editorScript": "file:./index.js",
@ -65,10 +70,23 @@
"right" "right"
] ]
}, },
"hasBackgroundColor": { "hasBorder": {
"type": "boolean", "type": "boolean",
"default": false "default": false
}, },
"blockVariant": {
"type": "string",
"default": "framed",
"enum": [
"framed",
"backgrounded",
"nude"
]
},
"borderColor": {
"type": "string",
"default": "#136f63"
},
"backgroundColor": { "backgroundColor": {
"type": "string", "type": "string",
"default": "#ffffff" "default": "#ffffff"
@ -88,14 +106,6 @@
"variationA", "variationA",
"variationB" "variationB"
] ]
},
"backgroundOrientation": {
"type": "string",
"default": "left",
"enum": [
"left",
"right"
]
} }
}, },
"usesContext": [ "usesContext": [

View File

@ -7,6 +7,8 @@ import {
MediaPlaceholder, MediaPlaceholder,
useSetting, useSetting,
} from "@wordpress/block-editor"; } from "@wordpress/block-editor";
import shapeA from "./shapeA.jsx";
import shapeB from "./shapeB.jsx";
import { lock, trash } from "@wordpress/icons"; import { lock, trash } from "@wordpress/icons";
import { ColorPalette } from "@wordpress/components"; import { ColorPalette } from "@wordpress/components";
import { import {
@ -19,6 +21,8 @@ import {
import "./editor.scss"; import "./editor.scss";
import { isColorLight } from "../../_utilities/utilities"; import { isColorLight } from "../../_utilities/utilities";
import ShapeA from "./shapeA.jsx";
import ShapeB from "./shapeB.jsx";
export default function Edit({ attributes, setAttributes, ...props }) { export default function Edit({ attributes, setAttributes, ...props }) {
const colors = useSetting("color.palette.theme"); const colors = useSetting("color.palette.theme");
@ -30,12 +34,13 @@ export default function Edit({ attributes, setAttributes, ...props }) {
coverAlt, coverAlt,
coverId, coverId,
coverSize, coverSize,
hasBackgroundColor,
backgroundColor, backgroundColor,
backgroundOrientation,
blockWidth, blockWidth,
textColor, textColor,
shapeType, shapeType,
blockVariant,
borderColor,
} = attributes; } = attributes;
function onDispositionChange(disposition) { function onDispositionChange(disposition) {
@ -61,34 +66,37 @@ export default function Edit({ attributes, setAttributes, ...props }) {
setAttributes({ backgroundColor: value }); setAttributes({ backgroundColor: value });
setHasLightBackground(value); setHasLightBackground(value);
} }
function onHasBackgroundColorChange(value) {
setAttributes({ hasBackgroundColor: value });
if (!value) {
setAttributes({ backgroundColor: null });
}
}
function onCoverTypeChange(value) { function onCoverTypeChange(value) {
setAttributes({ coverType: value }); setAttributes({ coverType: value });
} }
function onBackgroundOrientationChange(value) { function onBlockVariantChange(value) {
setAttributes({ backgroundOrientation: value }); setAttributes({ blockVariant: value });
if (value === "framed" || value === "nude") {
setAttributes({ backgroundColor: "#fff" });
setAttributes({ hasLightBackground: true });
}
} }
function setHasLightBackground(backgroundColor) { function setHasLightBackground(backgroundColor) {
if (!backgroundColor) return; if (!backgroundColor) return;
const isLightBackgroundColor = isColorLight(backgroundColor); const isLightBackgroundColor = isColorLight(backgroundColor);
console.log(isLightBackgroundColor);
setAttributes({ hasLightBackground: isLightBackgroundColor }); setAttributes({ hasLightBackground: isLightBackgroundColor });
} }
console.log(backgroundColor);
console.log(isColorLight(backgroundColor));
return ( return (
<> <>
<InspectorControls> <InspectorControls>
<PanelBody <PanelBody
className="deligraph-blocks-components-image__panel-body" className="deligraph-blocks-components-image__panel-body"
title={__("Largeur", "deligraph-blocks")} title={__("Aspect & Variante de bloc", "deligraph-blocks")}
> >
{/* Largeur du bloc */}
<ToggleGroupControl <ToggleGroupControl
className="deligraph-blocks__variant" className="deligraph-blocks__variant"
isBlock isBlock
@ -99,10 +107,95 @@ export default function Edit({ attributes, setAttributes, ...props }) {
<ToggleGroupControlOption label="Contenue" value="contained" /> <ToggleGroupControlOption label="Contenue" value="contained" />
<ToggleGroupControlOption label="Pleine largeur" value="full" /> <ToggleGroupControlOption label="Pleine largeur" value="full" />
</ToggleGroupControl> </ToggleGroupControl>
{/* Modèle de bloc */}
<ToggleGroupControl
className="deligraph-blocks__variant"
isBlock
label="Modèle de bloc"
onChange={onBlockVariantChange}
value={blockVariant}
>
<ToggleGroupControlOption label="Nu" value="nude" />
<ToggleGroupControlOption label="Encadré" value="framed" />
<ToggleGroupControlOption
label="Fond Coloré"
value="backgrounded"
/>
</ToggleGroupControl>
{/* Disposition */}
<ToggleGroupControl
className="deligraph-blocks__variant"
isBlock
label="Disposition"
onChange={onDispositionChange}
value={disposition}
>
<ToggleGroupControlOption label="Gauche" value="left" />
<ToggleGroupControlOption label="Droite" value="right" />
</ToggleGroupControl>
</PanelBody> </PanelBody>
{blockVariant === "backgrounded" && (
<PanelBody
className="deligraph-blocks-components-image__panel-body"
title={__("Arrière plan", "deligraph-blocks")}
>
<ToggleGroupControl
className="deligraph-blocks__variant"
isBlock
label="Type de forme"
onChange={(value) => setAttributes({ shapeType: value })}
value={shapeType}
>
<ToggleGroupControlOption
label="Variation A"
value="variationA"
/>
<ToggleGroupControlOption
label="Variation B"
value="variationB"
/>
</ToggleGroupControl>
<ColorPalette
colors={colors}
value={backgroundColor}
onChange={onBackgroundColorChange}
/>
</PanelBody>
)}
{blockVariant === "framed" && (
<PanelBody
className="deligraph-blocks-components-image__panel-body"
title={__("Bordure", "deligraph-blocks")}
>
<ToggleGroupControl
className="deligraph-blocks__variant"
isBlock
label="Type de forme"
onChange={(value) => setAttributes({ shapeType: value })}
value={shapeType}
>
<ToggleGroupControlOption
label="Variation A"
value="variationA"
/>
<ToggleGroupControlOption
label="Variation B"
value="variationB"
/>
</ToggleGroupControl>
<ColorPalette
colors={colors}
value={borderColor}
onChange={(value) => setAttributes({ borderColor: value })}
/>
</PanelBody>
)}
<PanelBody <PanelBody
className="deligraph-blocks-components-image__panel-body" className="deligraph-blocks-components-image__panel-body"
title={__("Image d'accompagnement", "deligraph-blocks")} title={__("Image d'accompagnement", "deligraph-blocks")}
initialOpen={false}
> >
{coverUrl && <img src={coverUrl} alt={coverAlt} />} {coverUrl && <img src={coverUrl} alt={coverAlt} />}
<div className="media-replace-container"> <div className="media-replace-container">
@ -141,16 +234,7 @@ export default function Edit({ attributes, setAttributes, ...props }) {
<ToggleGroupControlOption label="Classique" value="classic" /> <ToggleGroupControlOption label="Classique" value="classic" />
<ToggleGroupControlOption label="Encadrée" value="photoframe" /> <ToggleGroupControlOption label="Encadrée" value="photoframe" />
</ToggleGroupControl> </ToggleGroupControl>
<ToggleGroupControl
className="deligraph-blocks__variant"
isBlock
label="Disposition"
onChange={onDispositionChange}
value={disposition}
>
<ToggleGroupControlOption label="Gauche" value="left" />
<ToggleGroupControlOption label="Droite" value="right" />
</ToggleGroupControl>
<ToggleGroupControl <ToggleGroupControl
className="deligraph-blocks__variant" className="deligraph-blocks__variant"
isBlock isBlock
@ -165,45 +249,10 @@ export default function Edit({ attributes, setAttributes, ...props }) {
</ToggleGroupControl> </ToggleGroupControl>
</PanelBody> </PanelBody>
<PanelBody
className="deligraph-blocks-components-image__panel-body"
title={__("Arrière plan", "deligraph-blocks")}
>
<CheckboxControl
label="Arrière plan coloré"
checked={hasBackgroundColor}
onChange={onHasBackgroundColorChange}
/>
{hasBackgroundColor && (
<>
<ToggleGroupControl
className="deligraph-blocks__variant"
isBlock
label="Type de forme"
onChange={(value) => setAttributes({ shapeType: value })}
value={shapeType}
>
<ToggleGroupControlOption
label="Variation A"
value="variationA"
/>
<ToggleGroupControlOption
label="Variation B"
value="variationB"
/>
</ToggleGroupControl>
<ColorPalette
colors={colors}
value={backgroundColor}
onChange={onBackgroundColorChange}
/>
</>
)}
</PanelBody>
<PanelBody <PanelBody
className="deligraph-blocks-components-image__panel-body" className="deligraph-blocks-components-image__panel-body"
title={__("Couleur du texte", "deligraph-blocks")} title={__("Couleur du texte", "deligraph-blocks")}
initialOpen={false}
> >
<ColorPalette <ColorPalette
colors={colors} colors={colors}
@ -214,62 +263,47 @@ export default function Edit({ attributes, setAttributes, ...props }) {
</InspectorControls> </InspectorControls>
<section <section
{...useBlockProps({ {...useBlockProps({
className: `deligraph-blocks-chapter-section chapter-section chapter-section--${disposition} className: `deligraph-blocks-chapter-section chapter-section chapter-section--${disposition} chapter-section--${blockVariant}
${ ${
blockWidth === "full" blockWidth === "full"
? "chapter-section--width-full" ? "chapter-section--width-full"
: "chapter-section--width-contained" : "chapter-section--width-contained"
} }
${
hasBackgroundColor && backgroundColor ${
? "chapter-section--has-background" hasLightBackground
: "" ? "chapter-section--bg-light"
} : "chapter-section--bg-dark"
${ }`,
hasLightBackground
? "chapter-section--bg-light"
: "chapter-section--bg-dark"
}`,
style: { style: {
"--chapter-section-text-color": textColor ? textColor : "#136f63", "--chapter-section-text-color": textColor ? textColor : "#136f63",
"--cta-current-color":
blockVariant === "backgrounded"
? "inherit"
: "var(--wp--preset--color--primary) !important",
}, },
})} })}
> >
{hasBackgroundColor && {blockVariant === "backgrounded" &&
backgroundColor && backgroundColor &&
shapeType === "variationA" && ( shapeType === "variationA" && (
<> <ShapeA backgroundColor={backgroundColor} borderColor={"none"} />
<svg
width="1440"
height="744"
viewBox="0 0 1440 744"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={`chapter-section__background chapter-section__background--${backgroundOrientation}`}
preserveAspectRatio="none"
>
<path d="M0 0H1440V686.701L0 744V0Z" fill={backgroundColor} />
</svg>
</>
)} )}
{hasBackgroundColor && {blockVariant === "backgrounded" &&
backgroundColor && backgroundColor &&
shapeType === "variationB" && ( shapeType === "variationB" && (
<> <ShapeB backgroundColor={backgroundColor} borderColor={"none"} />
<svg )}
className={`chapter-section__background chapter-section__background--${backgroundOrientation}`} {blockVariant === "framed" &&
width="1302" backgroundColor &&
height="654" shapeType === "variationA" && (
viewBox="0 0 1302 654" <ShapeA backgroundColor={"none"} borderColor={borderColor} />
preserveAspectRatio="none" )}
> {blockVariant === "framed" &&
<path backgroundColor &&
d="M1302 0L0 15.8281V654L1302 642.633L1302 0Z" shapeType === "variationB" && (
fill={backgroundColor} <ShapeB backgroundColor={"none"} borderColor={borderColor} />
/>
</svg>
</>
)} )}
<div className="chapter-section__content"> <div className="chapter-section__content">
<div className="chapter-section__innerblocks"> <div className="chapter-section__innerblocks">

View File

@ -1,4 +1,6 @@
import { useBlockProps, RichText, InnerBlocks } from "@wordpress/block-editor"; import { useBlockProps, RichText, InnerBlocks } from "@wordpress/block-editor";
import ShapeA from "./shapeA.jsx";
import ShapeB from "./shapeB.jsx";
export default function save({ attributes }) { export default function save({ attributes }) {
const { const {
hasLightBackground, hasLightBackground,
@ -8,64 +10,57 @@ export default function save({ attributes }) {
coverSize, coverSize,
coverType, coverType,
backgroundColor, backgroundColor,
hasBackgroundColor,
backgroundOrientation,
blockWidth, blockWidth,
textColor, textColor,
shapeType, shapeType,
blockVariant,
borderColor,
} = attributes; } = attributes;
return ( return (
<section <section
{...useBlockProps.save({ {...useBlockProps.save({
className: `deligraph-blocks-chapter-section chapter-section chapter-section--${disposition} className: `deligraph-blocks-chapter-section chapter-section chapter-section--${disposition} chapter-section--${blockVariant}
${ ${
blockWidth === "full" blockWidth === "full"
? "chapter-section--width-full" ? "chapter-section--width-full"
: "chapter-section--width-contained" : "chapter-section--width-contained"
} }
${hasLightBackground ? "chapter-section--bg-light" : "chapter-section--bg-dark"}
${ ${
hasBackgroundColor && backgroundColor hasLightBackground
? "chapter-section--has-background" ? "chapter-section--bg-light"
: "" : "chapter-section--bg-dark"
}`, }`,
style: { style: {
"--chapter-section-text-color": textColor ? textColor : "#136f63", "--chapter-section-text-color": textColor ? textColor : "#136f63",
"--cta-current-color":
blockVariant === "backgrounded"
? "inherit"
: "var(--wp--preset--color--primary) !important",
}, },
})} })}
> >
{hasBackgroundColor && backgroundColor && shapeType === "variationA" && ( {blockVariant === "backgrounded" &&
<> backgroundColor &&
<svg shapeType === "variationA" && (
width="1440" <ShapeA backgroundColor={backgroundColor} borderColor={"none"} />
height="744" )}
viewBox="0 0 1440 744" {blockVariant === "backgrounded" &&
fill="none" backgroundColor &&
xmlns="http://www.w3.org/2000/svg" shapeType === "variationB" && (
className={`chapter-section__background chapter-section__background--${backgroundOrientation}`} <ShapeB backgroundColor={backgroundColor} borderColor={"none"} />
preserveAspectRatio="none" )}
> {blockVariant === "framed" &&
<path d="M0 0H1440V686.701L0 744V0Z" fill={backgroundColor} /> backgroundColor &&
</svg> shapeType === "variationA" && (
</> <ShapeA backgroundColor={"none"} borderColor={borderColor} />
)} )}
{hasBackgroundColor && backgroundColor && shapeType === "variationB" && ( {blockVariant === "framed" &&
<> backgroundColor &&
<svg shapeType === "variationB" && (
className={`chapter-section__background chapter-section__background--${backgroundOrientation}`} <ShapeB backgroundColor={"none"} borderColor={borderColor} />
width="1302" )}
height="654"
viewBox="0 0 1302 654"
preserveAspectRatio="none"
>
<path
d="M1302 0L0 15.8281V654L1302 642.633L1302 0Z"
fill={backgroundColor}
/>
</svg>
</>
)}
<div className="chapter-section__content"> <div className="chapter-section__content">
<div className="chapter-section__innerblocks"> <div className="chapter-section__innerblocks">

View File

@ -0,0 +1,32 @@
import React from "react";
export default function ShapeA({
backgroundOrientation,
backgroundColor,
borderColor,
}) {
return (
<svg
width="1440"
height="744"
viewBox="0 0 1440 744"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={`chapter-section__background chapter-section__background--${backgroundOrientation}`}
preserveAspectRatio="none"
vectorEffect="non-scaling-stroke"
overflow="visible"
>
<path
d="M0 0H1440V686.701L0 744V0Z"
fill={backgroundColor}
stroke={borderColor}
strokeWidth={borderColor ? "2px" : "0"}
style={{
strokeLinejoin: "round",
vectorEffect: "non-scaling-stroke",
}}
/>
</svg>
);
}

View File

@ -0,0 +1,30 @@
import React from "react";
export default function ShapeB({
backgroundOrientation,
backgroundColor,
borderColor,
}) {
return (
<svg
className={`chapter-section__background chapter-section__background--${backgroundOrientation}`}
width="1302"
height="654"
viewBox="0 0 1302 654"
preserveAspectRatio="none"
vectorEffect="non-scaling-stroke"
overflow="visible"
>
<path
d="M1302 0L0 15.8281V654L1302 642.633L1302 0Z"
fill={backgroundColor}
stroke={borderColor}
strokeWidth={borderColor ? "2px" : "0"}
style={{
strokeLinejoin: "round",
vectorEffect: "non-scaling-stroke",
}}
/>
</svg>
);
}