Changes to lcp-button
This commit is contained in:
@ -0,0 +1,96 @@
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { BaseControl, __experimentalNumberControl as NumberControl, SelectControl, __experimentalHStack as HStack } from '@wordpress/components';
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
/**
|
||||
* Control component with a number input and a select dropdown for units (px, rem, em, % etc.).
|
||||
* Accepts a default value as a string (e.g., "15px", "10rem", etc.).
|
||||
* Includes an optional 'auto' unit if includeAuto is true, and handles autoReturnsNull behavior.
|
||||
*/
|
||||
export function DimensionValueControl({ value = '10px', onChange, includeAuto = false, autoReturnsNull = false }) {
|
||||
// Options for select control (CSS units) including 'auto' if enabled
|
||||
const unitOptions = [
|
||||
{ label: __('px'), value: 'px' },
|
||||
{ label: __('%'), value: '%' },
|
||||
{ label: __('em'), value: 'em' },
|
||||
{ label: __('rem'), value: 'rem' },
|
||||
{ label: __('vw'), value: 'vw' },
|
||||
{ label: __('vh'), value: 'vh' },
|
||||
...(includeAuto ? [{ label: __('auto'), value: 'auto' }] : []), // Add 'auto' option if includeAuto is true
|
||||
];
|
||||
|
||||
// Parse the value string into a number and unit
|
||||
const parseValue = (value) => {
|
||||
const regex = /([0-9]+)([a-zA-Z%]+)?/; // Capture the number and the unit
|
||||
const match = value.match(regex);
|
||||
if (match) {
|
||||
return {
|
||||
numberValue: parseInt(match[1], 10), // Number part
|
||||
unitValue: match[2] || 'px' // Unit part (default to 'px' if no unit found)
|
||||
};
|
||||
}
|
||||
return { numberValue: 0, unitValue: 'px' }; // Fallback if invalid format
|
||||
};
|
||||
|
||||
// Use the parsed value to set initial state
|
||||
const { numberValue: initialNumber, unitValue: initialUnit } = parseValue(value);
|
||||
const [numberValue, setNumberValue] = useState(initialNumber);
|
||||
const [unitValue, setUnitValue] = useState(initialUnit);
|
||||
|
||||
// Combine the number and unit into a string like "15px"
|
||||
const dimensionValue = `${numberValue}${unitValue}`;
|
||||
|
||||
// Handle number change
|
||||
const onNumberChange = (newValue) => {
|
||||
setNumberValue(newValue);
|
||||
if (onChange && unitValue !== 'auto') {
|
||||
onChange(`${newValue}${unitValue}`); // Pass updated value back to parent
|
||||
}
|
||||
};
|
||||
|
||||
// Handle unit change
|
||||
const onUnitChange = (newUnit) => {
|
||||
if (newUnit === 'auto') {
|
||||
setNumberValue(null); // Reset the number value when 'auto' is selected
|
||||
}
|
||||
setUnitValue(newUnit);
|
||||
if (onChange) {
|
||||
const updatedValue = newUnit === 'auto'
|
||||
? (autoReturnsNull ? null : 'auto')
|
||||
: `${numberValue}${newUnit}`; // Pass 'auto' or null or updated value back to parent
|
||||
onChange(updatedValue);
|
||||
}
|
||||
};
|
||||
|
||||
// Effect to handle when value prop changes (useful for syncing)
|
||||
useEffect(() => {
|
||||
const { numberValue, unitValue } = parseValue(value);
|
||||
setNumberValue(numberValue);
|
||||
setUnitValue(unitValue);
|
||||
}, [value]);
|
||||
|
||||
return (
|
||||
<BaseControl className="lcp-dimension-value-control">
|
||||
<HStack>
|
||||
{/* Number input control, disabled when 'auto' is selected */}
|
||||
<NumberControl
|
||||
className="lcp-number-control"
|
||||
value={numberValue || ''}
|
||||
onChange={onNumberChange}
|
||||
min={0}
|
||||
step={0.1}
|
||||
spinControls={'none'}
|
||||
disabled={unitValue === 'auto'} // Disable number input if 'auto' is selected
|
||||
/>
|
||||
|
||||
{/* Select dropdown control for units */}
|
||||
<SelectControl
|
||||
className="lcp-select-control"
|
||||
value={unitValue}
|
||||
options={unitOptions}
|
||||
onChange={onUnitChange}
|
||||
/>
|
||||
</HStack>
|
||||
</BaseControl>
|
||||
);
|
||||
}
|
||||
59
includes/blocks/lcp-button/components/IconSelectControl.js
Normal file
59
includes/blocks/lcp-button/components/IconSelectControl.js
Normal file
@ -0,0 +1,59 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { SelectControl } from '@wordpress/components';
|
||||
|
||||
export function IconSelectControl(props) {
|
||||
const { iconSvgId, onIconChange } = props;
|
||||
|
||||
const [iconData, setIconData] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchIconData = async () => {
|
||||
try {
|
||||
const response = await fetch('/wp-json/lcp/v1/icons');
|
||||
const data = await response.json();
|
||||
if (Array.isArray(data) && data.length > 0) {
|
||||
setIconData(data); // Set the fetched data directly
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching icons:', error);
|
||||
}
|
||||
};
|
||||
|
||||
fetchIconData();
|
||||
}, []);
|
||||
|
||||
const handleIconChange = (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.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.iconSvgId); // Debugging output
|
||||
console.log("Selected Icon Path:", selectedIcon.iconSvgPaths); // Debugging output
|
||||
console.log("Selected Icon Viewbox:", selectedIcon.selectedIconViewbox); // Debugging output
|
||||
}
|
||||
};
|
||||
|
||||
if (iconData.length === 0) {
|
||||
return <p>{__('Loading icons...', 'lcp')}</p>; // Loading state
|
||||
}
|
||||
|
||||
const iconOptions = iconData.map((icon) => ({
|
||||
value: icon.iconSvgId, // Use icon ID as value for the SelectControl
|
||||
label: icon.name, // Directly use the icon's name as the label
|
||||
}));
|
||||
|
||||
|
||||
return (
|
||||
<SelectControl
|
||||
label={__('Select Icon', 'lcp')}
|
||||
value={iconSvgId} // Current selected icon ID
|
||||
options={iconOptions}
|
||||
onChange={handleIconChange} // Handle icon change
|
||||
/>
|
||||
);
|
||||
}
|
||||
103
includes/blocks/lcp-button/components/PaddingControl.js
Normal file
103
includes/blocks/lcp-button/components/PaddingControl.js
Normal file
@ -0,0 +1,103 @@
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { BaseControl, Button, RangeControl, __experimentalHStack as HStack, __experimentalVStack as VStack } from '@wordpress/components';
|
||||
import { DimensionValueControl } from './DimensionValueControl';
|
||||
|
||||
/**
|
||||
* Padding Control component to manage padding values for different screen sizes.
|
||||
*/
|
||||
export function PaddingControl() {
|
||||
return (
|
||||
<BaseControl className="lcp-padding-control">
|
||||
|
||||
|
||||
{/* Padding label and Unlink button */}
|
||||
<HStack>
|
||||
<span>{__('Padding')}</span>
|
||||
<Button
|
||||
variant="secondary"
|
||||
aria-label={__('Unlink sides')}
|
||||
onClick={() => {}}
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false">
|
||||
<path d="M10 17.389H8.444A5.194 5.194 0 1 1 8.444 7H10v1.5H8.444a3.694 3.694 0 0 0 0 7.389H10v1.5ZM14 7h1.556a5.194 5.194 0 0 1 0 10.39H14v-1.5h1.556a3.694 3.694 0 0 0 0-7.39H14V7Zm-4.5 6h5v-1.5h-5V13Z"></path>
|
||||
</svg>
|
||||
</Button>
|
||||
</HStack>
|
||||
|
||||
{/* Extra Large Padding Controls */}
|
||||
{/* Will update all padding values for all screen sizes if updateAllScreenSizes is true */}
|
||||
|
||||
{/* Top and Bottom HStack */}
|
||||
<HStack style={{ flex: 1 }}>
|
||||
{/* Top and Bottom Icon */}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" className="spacing-sizes-control__icon" aria-hidden="true" focusable="false">
|
||||
<path d="m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z" style={{ opacity: 0.25 }}></path>
|
||||
<path d="m7.5 6h9v-1.5h-9z"></path>
|
||||
<path d="m7.5 19.5h9v-1.5h-9z"></path>
|
||||
</svg>
|
||||
|
||||
{/* RangeControl wrapped in HStack with flex: 1 applied to its parent */}
|
||||
<HStack style={{ flex: 1 }}>
|
||||
<DimensionValueControl/>
|
||||
<RangeControl
|
||||
withInputField={false}
|
||||
value={10} // Placeholder value
|
||||
onChange={() => {}}
|
||||
min={0}
|
||||
max={50}
|
||||
/>
|
||||
</HStack>
|
||||
|
||||
{/* Custom Padding Button */}
|
||||
<Button
|
||||
style={{padding:0,background:'none',color:'var(--wp-components-color-foreground)'} }
|
||||
variant="primary"
|
||||
onClick={() => {}}
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false">
|
||||
<path d="m19 7.5h-7.628c-.3089-.87389-1.1423-1.5-2.122-1.5-.97966 0-1.81309.62611-2.12197 1.5h-2.12803v1.5h2.12803c.30888.87389 1.14231 1.5 2.12197 1.5.9797 0 1.8131-.62611 2.122-1.5h7.628z"></path>
|
||||
<path d="m19 15h-2.128c-.3089-.8739-1.1423-1.5-2.122-1.5s-1.8131.6261-2.122 1.5h-7.628v1.5h7.628c.3089.8739 1.1423 1.5 2.122 1.5s1.8131-.6261 2.122-1.5h2.128z"></path>
|
||||
</svg>
|
||||
</Button>
|
||||
</HStack>
|
||||
|
||||
{/* Left and Right HStack */}
|
||||
<HStack style={{ flex: 1 }}>
|
||||
{/* Left and Right Icon */}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" className="spacing-sizes-control__icon" aria-hidden="true" focusable="false">
|
||||
<path d="m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z" style={{ opacity: 0.25 }}></path>
|
||||
<path d="m7.5 6h9v-1.5h-9z"></path>
|
||||
<path d="m4.5 7.5v9h1.5v-9z"></path>
|
||||
<path d="m18 7.5v9h1.5v-9z"></path>
|
||||
</svg>
|
||||
|
||||
{/* RangeControl wrapped in HStack with flex: 1 applied to its parent */}
|
||||
|
||||
<RangeControl
|
||||
withInputField={false}
|
||||
value={10} // Placeholder value
|
||||
onChange={() => {}}
|
||||
min={0}
|
||||
max={50}
|
||||
/>
|
||||
|
||||
|
||||
{/* Custom Padding Button */}
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={() => {}}
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false">
|
||||
<path d="m19 7.5h-7.628c-.3089-.87389-1.1423-1.5-2.122-1.5-.97966 0-1.81309.62611-2.12197 1.5h-2.12803v1.5h2.12803c.30888.87389 1.14231 1.5 2.12197 1.5.9797 0 1.8131-.62611 2.122-1.5h7.628z"></path>
|
||||
<path d="m19 15h-2.128c-.3089-.8739-1.1423-1.5-2.122-1.5s-1.8131.6261-2.122 1.5h-7.628v1.5h7.628c.3089.8739 1.1423 1.5 2.122 1.5s1.8131-.6261 2.122-1.5h2.128z"></path>
|
||||
</svg>
|
||||
</Button>
|
||||
</HStack>
|
||||
|
||||
{/* Additional controls can be added here in a VStack */}
|
||||
<VStack>
|
||||
{/* Placeholder for additional components */}
|
||||
</VStack>
|
||||
</BaseControl>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user