changes to blocks and styles

This commit is contained in:
Jeremy Rangel
2024-12-27 22:56:39 -08:00
parent 93cc7be3bf
commit 462cffdddc
39 changed files with 959 additions and 228 deletions

View File

@ -1,52 +1,66 @@
import { useState, useEffect } from 'react';
import { __ } from '@wordpress/i18n';
import { SelectControl } from '@wordpress/components';
export function IconSelectControl(props) {
const { iconSvgId, onIconChange } = props;
// Hardcoded icon data
const iconData = [
{
"uuid": "c0a8012345678f3d5b847ad0f8a890f1",
"iconId": "comment-dots",
"family": "Font Awesome",
"sub-family": "solid",
"name": "Comment Dots",
"path": "<path d='M168.2 384.9c-15-5.4-31.7-3.1-44.6 6.4c-8.2 6-22.3 14.8-39.4 22.7c5.6-14.7 9.9-31.3 11.3-49.4c1-12.9-3.3-25.7-11.8-35.5C60.4 302.8 48 272 48 240c0-79.5 83.3-160 208-160s208 80.5 208 160s-83.3 160-208 160c-31.6 0-61.3-5.5-87.8-15.1zM26.3 423.8c-1.6 2.7-3.3 5.4-5.1 8.1l-.3 .5c-1.6 2.3-3.2 4.6-4.8 6.9c-3.5 4.7-7.3 9.3-11.3 13.5c-4.6 4.6-5.9 11.4-3.4 17.4c2.5 6 8.3 9.9 14.8 9.9c5.1 0 10.2-.3 15.3-.8l.7-.1c4.4-.5 8.8-1.1 13.2-1.9c.8-.1 1.6-.3 2.4-.5c17.8-3.5 34.9-9.5 50.1-16.1c22.9-10 42.4-21.9 54.3-30.6c31.8 11.5 67 17.9 104.1 17.9c141.4 0 256-93.1 256-208S397.4 32 256 32S0 125.1 0 240c0 45.1 17.7 86.8 47.7 120.9c-1.9 24.5-11.4 46.3-21.4 62.9zM144 272a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm144-32a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm80 32a32 32 0 1 0 0-64 32 32 0 1 0 0 64z'/>"
},
{
"uuid": "a1b2c3d4e5f6789abcdef0123456789ab",
"iconId": "newspaper",
"family": "Font Awesome",
"sub-family": "solid",
"name": "Newspaper",
"path": "<path d='M168 80c-13.3 0-24 10.7-24 24l0 304c0 8.4-1.4 16.5-4.1 24L440 432c13.3 0 24-10.7 24-24l0-304c0-13.3-10.7-24-24-24L168 80zM72 480c-39.8 0-72-32.2-72-72L0 112C0 98.7 10.7 88 24 88s24 10.7 24 24l0 296c0 13.3 10.7 24 24 24s24-10.7 24-24l0-304c0-39.8 32.2-72 72-72l272 0c39.8 0 72 32.2 72 72l0 304c0 39.8-32.2 72-72 72L72 480zM176 136c0-13.3 10.7-24 24-24l96 0c13.3 0 24 10.7 24 24l0 80c0 13.3-10.7 24-24 24l-96 0c-13.3 0-24-10.7-24-24l0-80zm200-24l32 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-32 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zm0 80l32 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-32 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zM200 272l208 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-208 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zm0 80l208 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-208 0c-13.3 0-24-10.7-24-24s10.7-24 24-24z'/>"
}
];
const [iconData, setIconData] = useState([]);
useEffect(() => {
const fetchIconData = async () => {
try {
const response = await fetch('/wp-content/themes/local-content-pro/assets/json/icons.json');
const data = await response.json();
if (data && data.length > 0) {
setIconData(data[0].svgs); // Assuming the structure is correct
}
} catch (error) {
console.error('Error fetching icons:', error);
}
};
fetchIconData();
}, []);
// Handle icon selection from dropdown
const handleIconChange = (selectedIconId) => {
const selectedIcon = iconData.find(icon => icon.uuid === selectedIconId);
const selectedIcon = iconData.find(icon => icon.id === selectedIconId);
if (selectedIcon && onIconChange) {
// Send both icon ID and path (SVG) to the parent component
onIconChange({
iconSvgId: selectedIconId, // UUID of the selected icon
iconSvgPath: selectedIcon.path // SVG path of the selected icon
iconSvgId: selectedIcon.id, // Pass icon ID to parent
iconSvgPath: selectedIcon.path // Pass icon path (SVG) to parent
});
console.log("Selected Icon ID:", selectedIcon.id); // Debugging output
console.log("Selected Icon Path:", selectedIcon.path); // Debugging output
}
};
if (iconData.length === 0) {
return <p>{__('Loading icons...', 'lcp')}</p>; // Loading state
}
const iconOptions = iconData.map((icon) => ({
value: icon.id, // Use icon ID as value for the SelectControl
label: (
<div style={{ display: 'flex', alignItems: 'center' }}>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox={icon.viewBox || "0 0 512 512"} // Default viewBox if not present
style={{ width: '20px', height: '20px' }} // Control icon size
dangerouslySetInnerHTML={{ __html: icon.path }} // Insert SVG path
/>
<span style={{ marginLeft: '8px' }}>{icon.name}</span> {/* Show icon name */}
</div>
),
}));
return (
<>
<SelectControl
label={__("Select Icon")}
value={iconSvgId}
options={iconData.map((icon) => ({
label: icon.name,
value: icon.uuid, // Store the UUID as the value
}))}
onChange={handleIconChange}
/>
</>
<SelectControl
label={__('Select Icon', 'lcp')}
value={iconSvgId} // Current selected icon ID
options={iconOptions}
onChange={handleIconChange} // Handle icon change
/>
);
}

View File

@ -1,18 +0,0 @@
[
{
"uuid": "c0a8012345678f3d5b847ad0f8a890f1",
"iconId": "comment-dots",
"family": "Font Awesome",
"sub-family": "solid",
"name": "Comment Dots",
"path": "<path d='M168.2 384.9c-15-5.4-31.7-3.1-44.6 6.4c-8.2 6-22.3 14.8-39.4 22.7c5.6-14.7 9.9-31.3 11.3-49.4c1-12.9-3.3-25.7-11.8-35.5C60.4 302.8 48 272 48 240c0-79.5 83.3-160 208-160s208 80.5 208 160s-83.3 160-208 160c-31.6 0-61.3-5.5-87.8-15.1zM26.3 423.8c-1.6 2.7-3.3 5.4-5.1 8.1l-.3 .5c-1.6 2.3-3.2 4.6-4.8 6.9c-3.5 4.7-7.3 9.3-11.3 13.5c-4.6 4.6-5.9 11.4-3.4 17.4c2.5 6 8.3 9.9 14.8 9.9c5.1 0 10.2-.3 15.3-.8l.7-.1c4.4-.5 8.8-1.1 13.2-1.9c.8-.1 1.6-.3 2.4-.5c17.8-3.5 34.9-9.5 50.1-16.1c22.9-10 42.4-21.9 54.3-30.6c31.8 11.5 67 17.9 104.1 17.9c141.4 0 256-93.1 256-208S397.4 32 256 32S0 125.1 0 240c0 45.1 17.7 86.8 47.7 120.9c-1.9 24.5-11.4 46.3-21.4 62.9zM144 272a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm144-32a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm80 32a32 32 0 1 0 0-64 32 32 0 1 0 0 64z'/>"
},
{
"uuid": "a1b2c3d4e5f6789abcdef0123456789ab",
"iconId": "newspaper",
"family": "Font Awesome",
"sub-family": "solid",
"name": "Newspaper",
"path": "<path d='M168 80c-13.3 0-24 10.7-24 24l0 304c0 8.4-1.4 16.5-4.1 24L440 432c13.3 0 24-10.7 24-24l0-304c0-13.3-10.7-24-24-24L168 80zM72 480c-39.8 0-72-32.2-72-72L0 112C0 98.7 10.7 88 24 88s24 10.7 24 24l0 296c0 13.3 10.7 24 24 24s24-10.7 24-24l0-304c0-39.8 32.2-72 72-72l272 0c39.8 0 72 32.2 72 72l0 304c0 39.8-32.2 72-72 72L72 480zM176 136c0-13.3 10.7-24 24-24l96 0c13.3 0 24 10.7 24 24l0 80c0 13.3-10.7 24-24 24l-96 0c-13.3 0-24-10.7-24-24l0-80zm200-24l32 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-32 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zm0 80l32 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-32 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zM200 272l208 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-208 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zm0 80l208 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-208 0c-13.3 0-24-10.7-24-24s10.7-24 24-24z'/>"
}
]

View File

@ -1,23 +0,0 @@
[
{
"id": "comment-dots",
"family": "Font Awesome",
"sub-family": "solid",
"name": "Comment Dots",
"path": "<path d='M168.2 384.9c-15-5.4-31.7-3.1-44.6 6.4c-8.2 6-22.3 14.8-39.4 22.7c5.6-14.7 9.9-31.3 11.3-49.4c1-12.9-3.3-25.7-11.8-35.5C60.4 302.8 48 272 48 240c0-79.5 83.3-160 208-160s208 80.5 208 160s-83.3 160-208 160c-31.6 0-61.3-5.5-87.8-15.1zM26.3 423.8c-1.6 2.7-3.3 5.4-5.1 8.1l-.3 .5c-1.6 2.3-3.2 4.6-4.8 6.9c-3.5 4.7-7.3 9.3-11.3 13.5c-4.6 4.6-5.9 11.4-3.4 17.4c2.5 6 8.3 9.9 14.8 9.9c5.1 0 10.2-.3 15.3-.8l.7-.1c4.4-.5 8.8-1.1 13.2-1.9c.8-.1 1.6-.3 2.4-.5c17.8-3.5 34.9-9.5 50.1-16.1c22.9-10 42.4-21.9 54.3-30.6c31.8 11.5 67 17.9 104.1 17.9c141.4 0 256-93.1 256-208S397.4 32 256 32S0 125.1 0 240c0 45.1 17.7 86.8 47.7 120.9c-1.9 24.5-11.4 46.3-21.4 62.9zM144 272a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm144-32a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm80 32a32 32 0 1 0 0-64 32 32 0 1 0 0 64z'/>"
},
{
"id": "newspaper",
"family": "Font Awesome",
"sub-family": "solid",
"name": "Newspaper",
"path": "<path d='M168 80c-13.3 0-24 10.7-24 24l0 304c0 8.4-1.4 16.5-4.1 24L440 432c13.3 0 24-10.7 24-24l0-304c0-13.3-10.7-24-24-24L168 80zM72 480c-39.8 0-72-32.2-72-72L0 112C0 98.7 10.7 88 24 88s24 10.7 24 24l0 296c0 13.3 10.7 24 24 24s24-10.7 24-24l0-304c0-39.8 32.2-72 72-72l272 0c39.8 0 72 32.2 72 72l0 304c0 39.8-32.2 72-72 72L72 480zM176 136c0-13.3 10.7-24 24-24l96 0c13.3 0 24 10.7 24 24l0 80c0 13.3-10.7 24-24 24l-96 0c-13.3 0-24-10.7-24-24l0-80zm200-24l32 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-32 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zm0 80l32 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-32 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zM200 272l208 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-208 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zm0 80l208 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-208 0c-13.3 0-24-10.7-24-24s10.7-24 24-24z'/>"
},
{
"id": "map",
"family": "Font Awesome",
"sub-family": "solid",
"name": "Map",
"path": "<path d='M565.6 36.2C572.1 40.7 576 48.1 576 56l0 336c0 10-6.2 18.9-15.5 22.4l-168 64c-5.2 2-10.9 2.1-16.1 .3L192.5 417.5l-160 61c-7.4 2.8-15.7 1.8-22.2-2.7S0 463.9 0 456L0 120c0-10 6.1-18.9 15.5-22.4l168-64c5.2-2 10.9-2.1 16.1-.3L383.5 94.5l160-61c7.4-2.8 15.7-1.8 22.2 2.7zM48 136.5l0 284.6 120-45.7 0-284.6L48 136.5zM360 422.7l0-285.4-144-48 0 285.4 144 48zm48-1.5l120-45.7 0-284.6L408 136.5l0 284.6z'/>"
}
]

View File

@ -9,13 +9,24 @@
"description": "Example block scaffolded with Create Block tool.",
"example": {},
"supports": {
"html": false
"html": false,
"color": {
"background": true,
"link": true,
"text": true,
"gradients": true,
"button": true
}
},
"attributes": {
"buttonFunction": {
"buttonAction": {
"type": "string",
"default": "customUrl"
},
"customUrl": {
"type": "string",
"default": "#"
},
"buttonText": {
"type": "string",
"default": "Button Text"
@ -25,7 +36,7 @@
},
"iconSource": {
"type": "string",
"default": "svgPath"
"default": "manualSvgPath"
},
"iconSvgPath": {
"type": "string"
@ -36,9 +47,12 @@
},
"popUpId": {
"type": "number"
},
"manualIconSvgPath":{
"type": "string"
}
},
"textdomain": "button",
"textdomain": "lcp",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css",

View File

@ -3,95 +3,60 @@ import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
import { PanelBody, SelectControl, TextControl, TextareaControl, ToggleControl } from '@wordpress/components';
import { useState, useEffect } from '@wordpress/element';
import './editor.scss';
import { useSelect } from '@wordpress/data';
import { IconSelectControl } from '../components/IconSelectControl';
// Sample JSON data for icons (with UUIDs)
const iconData = [
{
"uuid": "c0a8012345678f3d5b847ad0f8a890f1",
"iconId": "comment-dots",
"family": "Font Awesome",
"sub-family": "solid",
"name": "Comment Dots",
"path": "<path d='M168.2 384.9c-15-5.4-31.7-3.1-44.6 6.4c-8.2 6-22.3 14.8-39.4 22.7c5.6-14.7 9.9-31.3 11.3-49.4c1-12.9-3.3-25.7-11.8-35.5C60.4 302.8 48 272 48 240c0-79.5 83.3-160 208-160s208 80.5 208 160s-83.3 160-208 160c-31.6 0-61.3-5.5-87.8-15.1zM26.3 423.8c-1.6 2.7-3.3 5.4-5.1 8.1l-.3 .5c-1.6 2.3-3.2 4.6-4.8 6.9c-3.5 4.7-7.3 9.3-11.3 13.5c-4.6 4.6-5.9 11.4-3.4 17.4c2.5 6 8.3 9.9 14.8 9.9c5.1 0 10.2-.3 15.3-.8l.7-.1c4.4-.5 8.8-1.1 13.2-1.9c.8-.1 1.6-.3 2.4-.5c17.8-3.5 34.9-9.5 50.1-16.1c22.9-10 42.4-21.9 54.3-30.6c31.8 11.5 67 17.9 104.1 17.9c141.4 0 256-93.1 256-208S397.4 32 256 32S0 125.1 0 240c0 45.1 17.7 86.8 47.7 120.9c-1.9 24.5-11.4 46.3-21.4 62.9zM144 272a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm144-32a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm80 32a32 32 0 1 0 0-64 32 32 0 1 0 0 64z'/>"
},
{
"uuid": "a1b2c3d4e5f6789abcdef0123456789ab",
"iconId": "newspaper",
"family": "Font Awesome",
"sub-family": "solid",
"name": "Newspaper",
"path": "<path d='M168 80c-13.3 0-24 10.7-24 24l0 304c0 8.4-1.4 16.5-4.1 24L440 432c13.3 0 24-10.7 24-24l0-304c0-13.3-10.7-24-24-24L168 80zM72 480c-39.8 0-72-32.2-72-72L0 112C0 98.7 10.7 88 24 88s24 10.7 24 24l0 296c0 13.3 10.7 24 24 24s24-10.7 24-24l0-304c0-39.8 32.2-72 72-72l272 0c39.8 0 72 32.2 72 72l0 304c0 39.8-32.2 72-72 72L72 480zM176 136c0-13.3 10.7-24 24-24l96 0c13.3 0 24 10.7 24 24l0 80c0 13.3-10.7 24-24 24l-96 0c-13.3 0-24-10.7-24-24l0-80zm200-24l32 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-32 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zm0 80l32 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-32 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zM200 272l208 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-208 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zm0 80l208 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-208 0c-13.3 0-24-10.7-24-24s10.7-24 24-24z'/>"
}
];
export default function Edit(props) {
const { attributes, setAttributes } = props;
const { buttonFunction, popUpId, buttonText, iconSvgId, iconSvgPath, displayIcon, iconSource} = attributes; // iconSvgId holds the UUID and iconSvgPath holds the SVG path
const [popups, setPopups] = useState([]);
// Fetch published popups (lcp-popup CPT)
useEffect(() => {
const fetchPopups = async () => {
const response = await fetch('/wp-json/wp/v2/lcp-popup');
const data = await response.json();
setPopups(data);
};
fetchPopups();
}, []);
const { buttonAction, buttonText, iconSvgId, iconSvgPath, displayIcon, iconSource, customUrl } = attributes;
// Handle icon selection from dropdown
const handleIconChange = (selectedIconId) => {
console.log("an icon is selected");
// Find the selected icon from the iconData array using the UUID
const selectedIcon = iconData.find(icon => icon.uuid === selectedIconId);
if (selectedIcon) {
// Update both iconSvgId (UUID) and iconSvgPath (SVG path)
setAttributes({
iconSvgId: selectedIconId, // UUID of the selected icon
iconSvgPath: selectedIcon.path // SVG path of the selected icon
});
}
};
const handleIconChanges = (selectedIcon) => {
console.log("Icon changed:", selectedIcon);
if (selectedIcon && selectedIcon.iconSvgPath) {
console.log("Selected Icon Path: ", selectedIcon.iconSvgPath); // Log the selected icon path for debugging
setAttributes({
iconSvgPath: selectedIcon.iconSvgPath // Set the SVG path in the attributes
});
}
};
const handleToggleChange = (value) => {
setAttributes({ displayIcon: value });
};
const handleCustomUrlChange = (value) => {
setAttributes({ customUrl: value });
};
const iconSourceOptions = [
{ value: 'manualSvgPath', label: 'SVG Path' },
{ value: 'iconSelector', label: 'Select Icon' },
{ value: 'iconSelector', label: 'Icon Library' },
];
const buttonFunctionOptions = [
const buttonActionOptions = [
{ value: 'customUrl', label: 'Custom URL' },
{ value: 'openPopup', label: 'Open Popup' },
{ value: 'showLoginForm', label: 'Show Login Form' },
{ value: 'logOut', label: 'Open Popup' },
{ value: 'shareCurrentPost', label: 'Share Current Post' }
{ value: 'shareCurrentPost', label: 'Share Current Post' },
{ value: 'displaySidecontent', label: 'Display Sidecontent' }
];
return (
<>
<InspectorControls>
<PanelBody title={__("Button Settings")}>
{/* Button Function */}
<SelectControl
label={__("Popup")}
value={popUpId}
options={iconSourceOptions}
onChange={(value) => setAttributes({ iconSource })}
/>
{buttonFunction === 'openPopup' && (
<SelectControl
label={__("Popup")}
value={popUpId}
options={iconSourceOptions}
onChange={(value) => setAttributes({ iconSource })}
label={__("Button Action")}
value={buttonAction}
options={buttonActionOptions}
onChange={(value) => setAttributes({ buttonAction: value })}
/>
{buttonAction === 'customUrl' && (
<TextControl
label={__("Custom URL")}
value={customUrl}
onChange={handleCustomUrlChange}
/>
)}
<TextControl
@ -103,50 +68,56 @@ export default function Edit(props) {
label="Display Icon"
checked={displayIcon}
onChange={handleToggleChange}
/>
{displayIcon && (
<>
<SelectControl
label={__("Icon Source")}
value={iconSource}
options={iconSourceOptions}
onChange={(value) => setAttributes({ iconSource: value })}
/>
{iconSource === 'manualSvgPath' && (
<TextareaControl
label="Icon SVG Path"
value={iconSvgPath}
onChange={(value) => props.setAttributes({ iconSvgPath: value })}
/>
{displayIcon && (
<>
<SelectControl
label={__("Icon Source")}
value={iconSource}
options={iconSourceOptions}
onChange={(value) => setAttributes({ iconSource: value })}
/>
{iconSource === 'manualSvgPath' && (
<TextareaControl
label="Icon SVG Path"
value={iconSvgPath} // Use the correct attribute `iconSvgPath`
onChange={(value) => setAttributes({ iconSvgPath: value })}
/>
)}
{iconSource === 'iconSelector' && (
<>
<SelectControl
label={__("Icon")}
value={iconSvgId}
options={iconData.map((icon) => ({
label: icon.name,
value: icon.uuid, // Store the UUID as the value
}))}
onChange={handleIconChange}
/>
{iconSource === 'iconSelector' && (
<IconSelectControl
value={props.attributes.icon}
onChange={handleIconChange}
iconSvgId={iconSvgId} // Pass current iconSvgId
onIconChange={handleIconChanges} // Handle icon selection
/>
</>
)}
)}
</>
)}
</PanelBody>
</InspectorControls>
<div {...useBlockProps()}>
<div className="button-container">
<span>{buttonText}</span>
</div>
</div>
<>
{buttonAction === 'customUrl' ? (
// Render an anchor tag if buttonAction is 'customUrl'
<a href={customUrl} className="lcp-button">
{/* Conditionally render the icon if displayIcon is true and iconSvgPath is available */}
{displayIcon && iconSvgPath && (
<svg className = "lcp-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 576" dangerouslySetInnerHTML={{ __html: iconSvgPath }} />
)}
{/* Render the button text */}
{buttonText || 'Button'} {/* Use buttonText or fallback */}
</a>
) : (
// Render a button if buttonAction is not 'customUrl'
<button className="lcp-button">
{/* Conditionally render the icon if displayIcon is true and iconSvgPath is available */}
{displayIcon && iconSvgPath && (
<svg className = "lcp-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 576" dangerouslySetInnerHTML={{ __html: iconSvgPath }} />
)}
{/* Render the button text */}
{buttonText || 'Button'} {/* Use buttonText or fallback */}
</button>
)}
</>
</>
);
}

View File

@ -7,3 +7,26 @@
.wp-block-create-block-button {
border: 1px dotted #f00;
}
.lcp-button {
display: inline-block;
background-color: var(--wp--preset--color--accent);
border: none;
color: #fff;
text-decoration: none;
padding: 10px;
font-weight: bold;
font-size: var(--wp--preset--font-size--small);
white-space: nowrap;
cursor: pointer;
margin:auto 5px;
}
.lcp-button .lcp-icon {
height: 1.2em;
max-height:100%;
width: auto;
vertical-align: middle; /* Aligns the icon with the text vertically */
margin-right: 10px; /* Space between the icon and the text */
fill:white;
}

View File

@ -2,7 +2,7 @@ import { useBlockProps } from '@wordpress/block-editor';
export default function save(props) {
const { attributes } = props;
const { type, popUpId, buttonText, iconSvgPath } = attributes; // Destructure buttonText and iconSvgPath from attributes
const { type, popUpId, buttonText, iconSvgPath, buttonAction } = attributes; // Destructure buttonText and iconSvgPath from attributes
// Get the block props for the button
const blockProps = useBlockProps.save();
@ -12,14 +12,30 @@ export default function save(props) {
blockProps['data-open-popup'] = popUpId; // Add the data attribute dynamically
}
// Conditionally render the link or button based on buttonAction
return (
<button {...blockProps}>
{/* Conditionally render the icon if iconSvgPath is set */}
{iconSvgPath && (
<svg className="icon" viewBox="0 0 24 24" width="100" height="100" dangerouslySetInnerHTML={{ __html: iconSvgPath }} />
<>
{buttonAction === 'customUrl' ? (
// Render an anchor tag if buttonAction is 'customUrl'
<a href={attributes.customUrl} {...blockProps} className="lcp-button">
{/* Conditionally render the icon if iconSvgPath is set */}
{iconSvgPath && (
<svg className="lcp-icon" viewBox="0 0 576 576" dangerouslySetInnerHTML={{ __html: iconSvgPath }} />
)}
{/* Render the button text */}
{buttonText || 'Button'} {/* Use buttonText or fallback */}
</a>
) : (
// Render a button if buttonAction is not 'customUrl'
<button {...blockProps} className="lcp-button">
{/* Conditionally render the icon if iconSvgPath is set */}
{iconSvgPath && (
<svg className="lcp-icon" viewBox="0 0 576 576" dangerouslySetInnerHTML={{ __html: iconSvgPath }} />
)}
{/* Render the button text */}
{buttonText || 'Button'} {/* Use buttonText or fallback */}
</button>
)}
{/* Render the button text */}
{buttonText || 'Button'} {/* Use buttonText or fallback */}
</button>
</>
);
}

View File

@ -10,3 +10,4 @@
color: #fff;
padding: 2px;
}

View File

@ -426,6 +426,12 @@ function build_gallery_styles($attributes, $unique_class) {
// Render the block
function render_lcp_gallery_block($attributes) {
$media_ids = get_media_ids($attributes);
// Check if any Media IDs are present
// If not, return null
// Later, more logic will be needed to verify if there are any gallery items from other sources
if ($media_ids) {
// Generate a unique class for each gallery
$unique_class = lcp_random_string(12, true);
// Get the media IDs based on the attributes
@ -478,7 +484,10 @@ function render_lcp_gallery_block($attributes) {
return "
<div class= '{$classes}' data-lgSettings='" . esc_attr($gallery_settings_json) . "'>
{$gallery_items_html}
</div>";
</div>"; }
else {
return null;
}
}
/* Initialize Gallery Block */
function lcp_gallery_block_init() {

View File

@ -0,0 +1,18 @@
# This file is for unifying the coding style for different editors and IDEs
# editorconfig.org
# WordPress Coding Standards
# https://make.wordpress.org/core/handbook/coding-standards/
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = tab
[*.{yml,yaml}]
indent_style = space
indent_size = 2

View File

@ -0,0 +1,30 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Coverage directory used by tools like istanbul
coverage
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Output of `npm pack`
*.tgz
# Output of `wp-scripts plugin-zip`
*.zip
# dotenv environment variables file
.env

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,62 @@
<?php
/**
* Plugin Name: Todo List
* Description: Example block scaffolded with Create Block tool.
* Requires at least: 6.6
* Requires PHP: 7.2
* Version: 0.1.0
* Author: The WordPress Contributors
* License: GPL-2.0-or-later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: todo-list
*
* @package CreateBlock
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Registers the block using the metadata loaded from the `block.json` file.
* Behind the scenes, it registers also all assets so they can be enqueued
* through the block editor in the corresponding context.
*
* @see https://developer.wordpress.org/reference/functions/register_block_type/
*/
function render_lcp_visualizer_block() {
$json_data = json_encode([
['x' => 0, 'y' => 10],
['x' => 1, 'y' => 20],
['x' => 2, 'y' => 15],
['x' => 3, 'y' => 25],
['x' => 4, 'y' => 30],
['x' => 5, 'y' => 40],
['x' => 6, 'y' => 45],
]);
return '<svg class="lcp-visualizer" data-visualizer-data="' . esc_attr($json_data) . '"></svg>';
}
function lcp_visualizer_block_init() {
register_block_type( __DIR__ . '/build', array(
'render_callback' => 'render_lcp_visualizer_block',
));
}
add_action( 'init', 'lcp_visualizer_block_init' );
function enqueue_d3_js() {
// Define the path to the D3.js file
$d3_js_path = get_template_directory_uri() . '/includes/blocks/lcp-visualizer/assets/js/d3.v7.min.js';
// Enqueue the D3.js file
wp_enqueue_script('d3-js', $d3_js_path, array(), null, false);
}
add_action('wp_enqueue_scripts', 'enqueue_d3_js');

View File

@ -0,0 +1,20 @@
{
"name": "todo-list",
"version": "0.1.0",
"description": "Example block scaffolded with Create Block tool.",
"author": "The WordPress Contributors",
"license": "GPL-2.0-or-later",
"main": "build/index.js",
"scripts": {
"build": "wp-scripts build",
"format": "wp-scripts format",
"lint:css": "wp-scripts lint-style",
"lint:js": "wp-scripts lint-js",
"packages-update": "wp-scripts packages-update",
"plugin-zip": "wp-scripts plugin-zip",
"start": "wp-scripts start"
},
"devDependencies": {
"@wordpress/scripts": "^30.7.0"
}
}

View File

@ -0,0 +1,55 @@
=== Todo List ===
Contributors: The WordPress Contributors
Tags: block
Tested up to: 6.6
Stable tag: 0.1.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Example block scaffolded with Create Block tool.
== Description ==
This is the long description. No limit, and you can use Markdown (as well as in the following sections).
For backwards compatibility, if this section is missing, the full length of the short description will be used, and
Markdown parsed.
== Installation ==
This section describes how to install the plugin and get it working.
e.g.
1. Upload the plugin files to the `/wp-content/plugins/todo-list` directory, or install the plugin through the WordPress plugins screen directly.
1. Activate the plugin through the 'Plugins' screen in WordPress
== Frequently Asked Questions ==
= A question that someone might have =
An answer to that question.
= What about foo bar? =
Answer to foo bar dilemma.
== Screenshots ==
1. This screen shot description corresponds to screenshot-1.(png|jpg|jpeg|gif). Note that the screenshot is taken from
the /assets directory or the directory that contains the stable readme.txt (tags or trunk). Screenshots in the /assets
directory take precedence. For example, `/assets/screenshot-1.png` would win over `/tags/4.3/screenshot-1.png`
(or jpg, jpeg, gif).
2. This is the second screen shot
== Changelog ==
= 0.1.0 =
* Release
== Arbitrary section ==
You may provide arbitrary sections, in the same format as the ones above. This may be of use for extremely complicated
plugins where more information needs to be conveyed that doesn't fit into the categories of "description" or
"installation." Arbitrary sections will be shown below the built-in sections outlined above.

View File

@ -0,0 +1,19 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "lcp/visualizer",
"version": "0.1.0",
"title": "Visualizer",
"category": "widgets",
"icon": "smiley",
"description": "Block for charts and data visualization",
"example": {},
"supports": {
"html": false
},
"textdomain": "lcp",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css",
"viewScript": "file:./view.js"
}

View File

@ -0,0 +1,38 @@
/**
* Retrieves the translation of text.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-i18n/
*/
import { __ } from '@wordpress/i18n';
/**
* React hook that is used to mark the block wrapper element.
* It provides all the necessary props like the class name.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-block-editor/#useblockprops
*/
import { useBlockProps } from '@wordpress/block-editor';
/**
* Lets webpack process CSS, SASS or SCSS files referenced in JavaScript files.
* Those files can contain any CSS code that gets applied to the editor.
*
* @see https://www.npmjs.com/package/@wordpress/scripts#using-css
*/
import './editor.scss';
/**
* The edit function describes the structure of your block in the context of the
* editor. This represents what the editor will render when the block is used.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#edit
*
* @return {Element} Element to render.
*/
export default function Edit() {
return (
<p { ...useBlockProps() }>
{ __( 'Todo List hello from the editor!', 'todo-list' ) }
</p>
);
}

View File

@ -0,0 +1,9 @@
/**
* The following styles get applied inside the editor only.
*
* Replace them with your own styles or remove the file completely.
*/
.wp-block-create-block-todo-list {
border: 1px dotted #f00;
}

View File

@ -0,0 +1,39 @@
/**
* Registers a new block provided a unique name and an object defining its behavior.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-registration/
*/
import { registerBlockType } from '@wordpress/blocks';
/**
* Lets webpack process CSS, SASS or SCSS files referenced in JavaScript files.
* All files containing `style` keyword are bundled together. The code used
* gets applied both to the front of your site and to the editor.
*
* @see https://www.npmjs.com/package/@wordpress/scripts#using-css
*/
import './style.scss';
/**
* Internal dependencies
*/
import Edit from './edit';
import save from './save';
import metadata from './block.json';
/**
* Every block starts by registering a new block type definition.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-registration/
*/
registerBlockType( metadata.name, {
/**
* @see ./edit.js
*/
edit: Edit,
/**
* @see ./save.js
*/
save,
} );

View File

@ -0,0 +1,22 @@
/**
* React hook that is used to mark the block wrapper element.
* It provides all the necessary props like the class name.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-block-editor/#useblockprops
*/
/**
* The save function defines the way in which the different attributes should
* be combined into the final markup, which is then serialized by the block
* editor into `post_content`.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#save
*
* @return {Element} Element to render.
*/
export default function save() {
return (
null
);
}

View File

@ -0,0 +1,24 @@
/**
* The following styles get applied both on the front of your site
* and in the editor.
*
* Replace them with your own styles or remove the file completely.
*/
.wp-block-create-block-todo-list {
background-color: #21759b;
color: #fff;
padding: 2px;
}
.line {
fill: none;
stroke-width: 2px;
}
.hover-line {
stroke-width: 4px;
}
.axis-label {
font-size: 12px;
}

View File

@ -0,0 +1,127 @@
/**
* Use this file for JavaScript code that you want to run in the front-end
* on posts/pages that contain this block.
*
* When this file is defined as the value of the `viewScript` property
* in `block.json` it will be enqueued on the front end of the site.
*
* Example:
*
* ```js
* {
* "viewScript": "file:./view.js"
* }
* ```
*
* If you're not making any changes to this file because your project doesn't need any
* JavaScript running in the front-end, then you should delete this file and remove
* the `viewScript` property from `block.json`.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#view-script
*/
/* eslint-disable no-console */
console.log( 'Hello World! (from lcp-visualizer)' );
/* eslint-enable no-console */
// JavaScript to initialize D3.js for all elements with the class .lcp-visualizer
document.addEventListener('DOMContentLoaded', function() {
const data = [
{ date: '2023-01-01', team: 'Manchester City', goals: 2 },
{ date: '2023-01-01', team: 'Liverpool', goals: 1 },
{ date: '2023-02-01', team: 'Manchester City', goals: 3 },
{ date: '2023-02-01', team: 'Liverpool', goals: 2 },
{ date: '2023-03-01', team: 'Manchester City', goals: 4 },
{ date: '2023-03-01', team: 'Liverpool', goals: 3 },
{ date: '2023-04-01', team: 'Manchester City', goals: 3 },
{ date: '2023-04-01', team: 'Liverpool', goals: 4 },
{ date: '2023-05-01', team: 'Manchester City', goals: 5 },
{ date: '2023-05-01', team: 'Liverpool', goals: 4 }
];
const parseDate = d3.timeParse("%Y-%m-%d");
data.forEach(d => {
d.date = parseDate(d.date);
d.goals = +d.goals;
});
const teams = Array.from(new Set(data.map(d => d.team)));
const color = d3.scaleOrdinal()
.domain(teams)
.range(d3.schemeCategory10);
const margin = { top: 20, right: 30, bottom: 40, left: 40 };
const width = 800 - margin.left - margin.right;
const height = 400 - margin.top - margin.bottom;
const svg = d3.select(".lcp-visualizer")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
const x = d3.scaleTime()
.domain(d3.extent(data, d => d.date))
.range([0, width]);
const y = d3.scaleLinear()
.domain([0, d3.max(data, d => d.goals)])
.nice()
.range([height, 0]);
const line = d3.line()
.x(d => x(d.date))
.y(d => y(d.goals));
svg.append("g")
.attr("transform", `translate(0,${height})`)
.call(d3.axisBottom(x));
svg.append("g")
.call(d3.axisLeft(y));
const teamData = teams.map(team => {
return {
team: team,
values: data.filter(d => d.team === team)
};
});
const path = svg.selectAll(".line")
.data(teamData)
.enter().append("path")
.attr("class", "line")
.attr("d", d => line(d.values))
.attr("stroke", d => color(d.team));
// Hover effect
teamData.forEach(team => {
svg.selectAll(`circle.${team.team}`)
.data(team.values)
.enter().append("circle")
.attr("class", team.team)
.attr("cx", d => x(d.date))
.attr("cy", d => y(d.goals))
.attr("r", 4)
.attr("fill", color(team.team))
.on("mouseover", function(event, d) {
d3.select(this)
.transition()
.duration(200)
.attr("r", 6)
.attr("fill", "orange");
d3.select(`path.${d.team}`).classed("hover-line", true);
})
.on("mouseout", function(event, d) {
d3.select(this)
.transition()
.duration(200)
.attr("r", 4)
.attr("fill", color(d.team));
d3.select(`path.${d.team}`).classed("hover-line", false);
});
});
});

View File

@ -115,6 +115,15 @@ function lcp_register_settings() {
'lcp_theme_settings_section' // Section where this field belongs
);
add_settings_field(
'enable_highlight_to_share', // Field ID
'Enable Highlight-to-Share', // Field title
'lcp_enable_highlight_to_share', // Field callback function
'lcp_theme_settings_page', // Page where this field appears
'lcp_theme_settings_section' // Section where this field belongs
);
// Add fields for custom breakpoints
add_settings_field(
'mobile_breakpoint', // Field ID
@ -176,7 +185,7 @@ function lcp_inject_breakpoints_to_frontend() {
}
</style>";
}
add_action('wp_head', 'lcp_inject_breakpoints_to_frontend',5);
add_action('wp_head', 'lcp_inject_breakpoints_to_frontend');
@ -191,6 +200,15 @@ function lcp_enable_key_points_meta_field() {
}
function lcp_enable_highlight_to_share() {
// Retrieve current value for 'enable_highlight_to_share'
$options = get_option( 'lcp_theme_settings', array() );
$checked = isset( $options['enable_highlight_to_share'] ) ? $options['enable_highlight_to_share'] : false;
// Output the checkbox
echo '<input type="checkbox" name="lcp_theme_settings[enable_highlight_to_share]" value="1" ' . checked( $checked, 1, false ) . ' />';
}
@ -327,3 +345,27 @@ function render_lcp_theme_settings_page() {
// Hooks
function highlight_to_share_popup() {
echo "
<div class=\"popup\" id=\"popup\">
<p>Hey there! Share this:</p>
<a href=\"#\" id=\"facebook-share\">Facebook</a> |
<a href=\"#\" id=\"twitter-share\">Twitter/X</a>
</div>
";
}
function lcp_wp_head_hooks(){
// Define lcp_theme_settings array from wp_options
$options = get_option('lcp_theme_settings', array());
// Echo highlight-to-share markup and enqueue javascript
// Highlight-to-share css is already in style.css
if ( isset($options['enable_highlight_to_share']) && $options['enable_highlight_to_share'] ) {
highlight_to_share_popup();
wp_enqueue_script( 'lcp-highlight-to-share', get_template_directory_uri() . '/assets/js/highlight-to-share.js', array(), null, true );
}
}
add_action('wp_head', 'lcp_wp_head_hooks');

View File

@ -18,6 +18,8 @@ class Lcp_Blocks {
include $this->template_directory. '/includes/blocks/lcp-dynamic-container/lcp-dynamic-container.php';
include $this->template_directory. '/includes/blocks/lcp-key-points/lcp-key-points.php';
include $this->template_directory. '/includes/blocks/lcp-button/lcp-button.php';
include $this->template_directory. '/includes/blocks/lcp-visualizer/lcp-visualizer.php';
}
}