diff --git a/includes/blocks/lcp-button/components/DimensionValueControl.js b/includes/blocks/lcp-button/components/DimensionValueControl.js new file mode 100644 index 0000000..113f8fe --- /dev/null +++ b/includes/blocks/lcp-button/components/DimensionValueControl.js @@ -0,0 +1,47 @@ +import { __ } from '@wordpress/i18n'; +import { BaseControl, NumberControl, SelectControl, __experimentalHStack as HStack } from '@wordpress/components'; + +/** + * Control component with a number input and a select dropdown for units (px, rem, em, % etc.). + */ +export function NumberWithUnitControl() { + // Example options for select control (CSS units) + const unitOptions = [ + { label: __('px'), value: 'px' }, + { label: __('rem'), value: 'rem' }, + { label: __('em'), value: 'em' }, + { label: __('%'), value: '%' }, + { label: __('vh'), value: 'vh' }, + { label: __('vw'), value: 'vw' }, + { label: __('pt'), value: 'pt' }, + { label: __('cm'), value: 'cm' }, + { label: __('mm'), value: 'mm' }, + ]; + + // State to manage the number and unit values + const [value, setValue] = React.useState(10); + const [unit, setUnit] = React.useState('px'); + + return ( + + + {/* Number input control */} + setValue(newValue)} + min={0} + step={1} + label={__('Value')} + /> + + {/* Select dropdown control for units */} + setUnit(newUnit)} + label={__('Unit')} + /> + + + ); +} diff --git a/includes/blocks/lcp-button/components/IconSelectControl.js b/includes/blocks/lcp-button/components/IconSelectControl.js index ecaa8bb..1c00e70 100644 --- a/includes/blocks/lcp-button/components/IconSelectControl.js +++ b/includes/blocks/lcp-button/components/IconSelectControl.js @@ -10,10 +10,10 @@ export function IconSelectControl(props) { useEffect(() => { const fetchIconData = async () => { try { - const response = await fetch('/wp-content/themes/local-content-pro/assets/json/icons.json'); + const response = await fetch('/wp-json/lcp/v1/icons'); const data = await response.json(); - if (data && data.length > 0) { - setIconData(data[0].svgs); // Assuming the structure is correct + if (Array.isArray(data) && data.length > 0) { + setIconData(data); // Set the fetched data directly } } catch (error) { console.error('Error fetching icons:', error); @@ -24,15 +24,17 @@ export function IconSelectControl(props) { }, []); const handleIconChange = (selectedIconId) => { - const selectedIcon = iconData.find(icon => icon.id === selectedIconId); + const selectedIcon = iconData.find(icon => icon.iconSvgId === selectedIconId); if (selectedIcon && onIconChange) { // Send both icon ID and path (SVG) to the parent component onIconChange({ - iconSvgId: selectedIcon.id, // Pass icon ID to parent - iconSvgPath: selectedIcon.path // Pass icon path (SVG) to parent + iconSvgId: selectedIcon.iconSvgId, // Pass icon ID to parent + iconSvgPath: selectedIcon.iconSvgPaths, // Pass icon paths to parent + viewbox: selectedIcon.selectedIconViewbox // Pass the viewbox to parent }); - console.log("Selected Icon ID:", selectedIcon.id); // Debugging output - console.log("Selected Icon Path:", selectedIcon.path); // Debugging output + console.log("Selected Icon ID:", selectedIcon.iconSvgId); // Debugging output + console.log("Selected Icon Path:", selectedIcon.iconSvgPaths); // Debugging output + console.log("Selected Icon Viewbox:", selectedIcon.selectedIconViewbox); // Debugging output } }; @@ -41,20 +43,11 @@ export function IconSelectControl(props) { } const iconOptions = iconData.map((icon) => ({ - value: icon.id, // Use icon ID as value for the SelectControl - label: ( -
- - {icon.name} {/* Show icon name */} -
- ), + value: icon.iconSvgId, // Use icon ID as value for the SelectControl + label: icon.name, // Directly use the icon's name as the label })); - + + return ( + {/* Padding label and Unlink button */} + + {__('Padding')} + + + + {/* Extra Large Padding Controls */} + {/* Will update all padding values for all screen sizes if updateAllScreenSizes is true */} + + {/* Top and Bottom HStack */} + + {/* Top and Bottom Icon */} + + + {/* RangeControl wrapped in HStack with flex: 1 applied to its parent */} +
+ {}} + min={0} + max={50} + /> +
+ + {/* Custom Padding Button */} + +
+ + + {/* Left and Right HStack */} + + {/* Left and Right Icon */} + + {/* RangeControl wrapped in HStack with flex: 1 applied to its parent */} +
+ {}} + min={0} + max={50} + /> +
+ + {/* Custom Padding Button */} + +
+ + + {/* Additional controls can be added here in a VStack */} + + {/* Placeholder for additional components */} + + + ); +} diff --git a/includes/blocks/lcp-button/lcp-button.php b/includes/blocks/lcp-button/lcp-button.php index 29437d8..98fe98a 100644 --- a/includes/blocks/lcp-button/lcp-button.php +++ b/includes/blocks/lcp-button/lcp-button.php @@ -28,3 +28,42 @@ function create_block_button_block_init() { register_block_type( __DIR__ . '/build' ); } add_action( 'init', 'create_block_button_block_init' ); + + +/* REST API */ +function register_icons_rest_api_endpoint() { + register_rest_route( 'lcp/v1', '/icons', array( + 'methods' => 'GET', + 'callback' => 'get_icons_data_from_db', + 'permission_callback' => '__return_true', // Public access; modify this if needed + ) ); +} + +add_action( 'rest_api_init', 'register_icons_rest_api_endpoint' ); + +function get_icons_data_from_db() { + global $wpdb; + + // Query the lcp_icons table + $results = $wpdb->get_results( + "SELECT id, name, paths, viewbox FROM {$wpdb->prefix}lcp_icons" + ); + + // If no icons are found, return an empty array + if ( empty( $results ) ) { + return []; + } + + // Format the results for the frontend + $icons = array_map( function( $icon ) { + return [ + 'iconSvgId' => $icon->id, // Icon ID + 'iconSvgPaths' => $icon->paths, // SVG paths (can be multiple) + 'selectedIconViewbox' => $icon->viewbox, // ViewBox for the SVG + 'name' => $icon->name, // Add name field + ]; + }, $results ); + + return $icons; +} + diff --git a/includes/blocks/lcp-button/src/block.json b/includes/blocks/lcp-button/src/block.json index c435ed6..95f5b02 100644 --- a/includes/blocks/lcp-button/src/block.json +++ b/includes/blocks/lcp-button/src/block.json @@ -45,11 +45,27 @@ "type": "string", "default": "" }, + "iconSvgViewbox": { + "type": "string", + "default": "0 0 510 510" + }, "popUpId": { "type": "number" }, "manualIconSvgPath":{ "type": "string" + }, + "buttonPadding":{ + "type": "string", + "default": "10px" + }, + "iconHeight": { + "type": "string", + "default": "15px" + }, + "iconWidth": { + "type": "string", + "default": "15px" } }, "textdomain": "lcp", diff --git a/includes/blocks/lcp-button/src/edit.js b/includes/blocks/lcp-button/src/edit.js index 127ce4f..23995a1 100644 --- a/includes/blocks/lcp-button/src/edit.js +++ b/includes/blocks/lcp-button/src/edit.js @@ -4,18 +4,22 @@ import { PanelBody, SelectControl, TextControl, TextareaControl, ToggleControl } import { useState, useEffect } from '@wordpress/element'; import './editor.scss'; import { IconSelectControl } from '../components/IconSelectControl'; +import { PaddingControl } from '../components/PaddingControl'; export default function Edit(props) { const { attributes, setAttributes } = props; - const { buttonAction, buttonText, iconSvgId, iconSvgPath, displayIcon, iconSource, customUrl } = attributes; + const { buttonAction, buttonText, iconSvgId, iconSvgPath, iconSvgViewbox, displayIcon, iconSource, customUrl, buttonPadding } = attributes; // Handle icon selection from dropdown 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 + console.log("Selected Icon Viewbox: ", selectedIcon.viewbox); // Log the selected icon viewbox for debugging setAttributes({ - iconSvgPath: selectedIcon.iconSvgPath // Set the SVG path in the attributes + iconSvgPath: selectedIcon.iconSvgPath, // Set the SVG path in the attributes + iconSvgId: selectedIcon.iconSvgId, // Set the icon ID + iconSvgViewbox: selectedIcon.viewbox // Set the icon viewbox in the attributes }); } }; @@ -28,6 +32,14 @@ export default function Edit(props) { setAttributes({ customUrl: value }); }; + const handlePaddingChange = (value) => { + // If the padding value is a number, make sure to append 'px' to it + if (typeof value === 'number') { + value = `${value}px`; // Convert to string with 'px' + } + setAttributes({ buttonPadding: value }); + }; + const iconSourceOptions = [ { value: 'manualSvgPath', label: 'SVG Path' }, { value: 'iconSelector', label: 'Icon Library' }, @@ -45,7 +57,11 @@ export default function Edit(props) { <> - {/* Button Function */} + {/* Pass the necessary props to PaddingControl */} + + {/* Button Action */} - <> - {buttonAction === 'customUrl' ? ( - // Render an anchor tag if buttonAction is 'customUrl' - - {/* Conditionally render the icon if displayIcon is true and iconSvgPath is available */} - {displayIcon && iconSvgPath && ( - - )} - {/* Render the button text */} - {buttonText || 'Button'} {/* Use buttonText or fallback */} - - ) : ( - // Render a button if buttonAction is not 'customUrl' - - )} - +
+ {buttonAction === 'customUrl' ? ( + // Render an anchor tag if buttonAction is 'customUrl' + + {/* Conditionally render the icon if displayIcon is true and iconSvgPath is available */} + {displayIcon && iconSvgPath && ( + + )} + {/* Render the button text */} + {buttonText || 'Button'} {/* Use buttonText or fallback */} + + ) : ( + // Render a button if buttonAction is not 'customUrl' + + )} +
); } diff --git a/includes/blocks/lcp-button/src/save.js b/includes/blocks/lcp-button/src/save.js index 4fddfe2..4bed09a 100644 --- a/includes/blocks/lcp-button/src/save.js +++ b/includes/blocks/lcp-button/src/save.js @@ -2,25 +2,20 @@ import { useBlockProps } from '@wordpress/block-editor'; export default function save(props) { const { attributes } = props; - const { type, popUpId, buttonText, iconSvgPath, buttonAction } = attributes; // Destructure buttonText and iconSvgPath from attributes + const { buttonText, iconSvgPath, iconSvgViewbox, buttonAction, customUrl } = attributes; // Destructure buttonText, iconSvgPath, and iconSvgViewbox // Get the block props for the button const blockProps = useBlockProps.save(); - // Conditionally add data-open-popup if type is 'openPopUp' and popUpId is not empty - if (type === 'openPopUp' && popUpId) { - blockProps['data-open-popup'] = popUpId; // Add the data attribute dynamically - } - // Conditionally render the link or button based on buttonAction return ( <> {buttonAction === 'customUrl' ? ( // Render an anchor tag if buttonAction is 'customUrl' - + {/* Conditionally render the icon if iconSvgPath is set */} {iconSvgPath && ( - + )} {/* Render the button text */} {buttonText || 'Button'} {/* Use buttonText or fallback */} @@ -30,7 +25,7 @@ export default function save(props) {