changes to blocks and styles
This commit is contained in:
@ -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
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@ -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'/>"
|
||||
}
|
||||
]
|
||||
@ -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'/>"
|
||||
}
|
||||
]
|
||||
@ -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",
|
||||
|
||||
@ -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>
|
||||
)}
|
||||
</>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@ -10,3 +10,4 @@
|
||||
color: #fff;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
|
||||
@ -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() {
|
||||
|
||||
18
includes/blocks/lcp-visualizer/.editorconfig
Normal file
18
includes/blocks/lcp-visualizer/.editorconfig
Normal 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
|
||||
30
includes/blocks/lcp-visualizer/.gitignore
vendored
Normal file
30
includes/blocks/lcp-visualizer/.gitignore
vendored
Normal 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
|
||||
2
includes/blocks/lcp-visualizer/assets/js/d3.v7.min.js
vendored
Normal file
2
includes/blocks/lcp-visualizer/assets/js/d3.v7.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
62
includes/blocks/lcp-visualizer/lcp-visualizer.php
Normal file
62
includes/blocks/lcp-visualizer/lcp-visualizer.php
Normal 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');
|
||||
20
includes/blocks/lcp-visualizer/package.json
Normal file
20
includes/blocks/lcp-visualizer/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
55
includes/blocks/lcp-visualizer/readme.txt
Normal file
55
includes/blocks/lcp-visualizer/readme.txt
Normal 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.
|
||||
19
includes/blocks/lcp-visualizer/src/block.json
Normal file
19
includes/blocks/lcp-visualizer/src/block.json
Normal 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"
|
||||
}
|
||||
38
includes/blocks/lcp-visualizer/src/edit.js
Normal file
38
includes/blocks/lcp-visualizer/src/edit.js
Normal 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>
|
||||
);
|
||||
}
|
||||
9
includes/blocks/lcp-visualizer/src/editor.scss
Normal file
9
includes/blocks/lcp-visualizer/src/editor.scss
Normal 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;
|
||||
}
|
||||
39
includes/blocks/lcp-visualizer/src/index.js
Normal file
39
includes/blocks/lcp-visualizer/src/index.js
Normal 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,
|
||||
} );
|
||||
22
includes/blocks/lcp-visualizer/src/save.js
Normal file
22
includes/blocks/lcp-visualizer/src/save.js
Normal 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
|
||||
);
|
||||
}
|
||||
24
includes/blocks/lcp-visualizer/src/style.scss
Normal file
24
includes/blocks/lcp-visualizer/src/style.scss
Normal 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;
|
||||
}
|
||||
127
includes/blocks/lcp-visualizer/src/view.js
Normal file
127
includes/blocks/lcp-visualizer/src/view.js
Normal 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);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user