changes to lcp-button and icon uploader

This commit is contained in:
Jeremy Rangel
2024-12-29 22:52:17 -08:00
parent 372d5aa2c1
commit 0d59719440
8 changed files with 13490 additions and 13212 deletions

View File

@ -1,10 +1,34 @@
[
{
"id": "3cd46d8957ea8cf1a80ee6bcef7251de",
"id": 1,
"setName": "Font Awesome - Regular",
"setFamily": "Font Awesome",
"version": "6.7.1",
"fileName": "font-awesome-v6.7.1-regular-svgs.json"
"file": "/font-awesome/v6.1.7/font-awesome-v6.7.1-regular-svgs.json"
},
{
"id": 2,
"setName": "Font Awesome - Solid",
"setFamily": "Font Awesome",
"version": "6.7.1",
"fileName": "/font-awesome/v6.1.7/font-awesome-v6.7.1-solid-svgs.json"
},
{
"id": 3,
"setName": "Font Awesome - Brands",
"setFamily": "Font Awesome",
"version": "6.7.1",
"fileName": "/font-awesome/v6.1.7/font-awesome-v6.7.1-brands-svgs.json"
},
{
"id": 4,
"setName": "Material Icons - Baseline",
"setFamily": "Material Icons",
"version": "1.0.32",
"fileName": "/material-icons/v1.0.32/material-icons-v1.0.32-baseline-svgs.json"
}
]

View File

@ -1,8 +1,21 @@
<?php
// Path to the input JSON file
$inputFile = 'material-icons-baseline.json';
// Path to the output JSON file
$outputFile = 'material-icons-baseline-unescaped.json';
$outputFile = 'material-icons-baseline-unescaped-with-ids.json';
// Function to generate a MySQL-style UUID
function generateUUID() {
// Generates a version 4 UUID (random)
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
mt_rand(0, 0xffff), mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0x0fff) | 0x4000,
mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
);
}
// Step 1: Load the JSON data
$jsonData = file_get_contents($inputFile);
@ -20,10 +33,13 @@ if ($data === null) {
die("Error decoding the JSON data.");
}
// Step 3: Iterate through each item and unescape the 'paths' key
// Step 3: Iterate through each item and unescape the 'paths' key, and generate a new 'id'
foreach ($data as &$icon) {
// Unescape only HTML entities (without affecting forward slashes)
$icon['paths'] = html_entity_decode($icon['paths'], ENT_QUOTES | ENT_HTML5);
// Generate a new MySQL-style UUID for each 'id'
$icon['id'] = generateUUID();
}
// Step 4: Encode the modified data back into JSON format
@ -42,5 +58,6 @@ if (file_put_contents($outputFile, $newJsonData) === false) {
die("Error saving the modified JSON data.");
}
echo "Paths have been unescaped and saved to '$outputFile'.\n";
echo "Paths have been unescaped, IDs have been added, and saved to '$outputFile'.\n";
?>

View File

@ -0,0 +1,86 @@
<?php
// Function to capitalize the 'name' field (capitalizes acronyms fully)
function capitalizeName($name) {
// Define a pattern to match acronyms (words in uppercase with no spaces)
$acronymPattern = '/\b[A-Z]{2,}\b/';
// Capitalize each word, and keep acronyms fully uppercase
$name = preg_replace_callback('/\b\w+\b/', function ($matches) use ($acronymPattern) {
$word = $matches[0];
// If it's an acronym (all uppercase), return as is
if (preg_match($acronymPattern, $word)) {
return strtoupper($word);
}
// Otherwise capitalize the first letter of each word and lowercase the rest
return ucfirst(strtolower($word));
}, $name);
return $name;
}
// Function to generate a MySQL UUID format (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
function generateMysqlUuid() {
// Generate a UUID using PHP's random_bytes for a total of 16 random bytes
$data = random_bytes(16);
// Set the version to 4 (random UUID)
$data[6] = chr(ord($data[6]) & 0x0f | 0x40); // Version 4
// Set the variant to RFC4122
$data[8] = chr(ord($data[8]) & 0x3f | 0x80); // RFC4122 variant
// Now unpack the data into 5 parts for formatting as UUID
$hexData = unpack('H8a/H4b/H4c/H4d/H12e', $data);
// Return the UUID in the format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
return $hexData['a'] . '-' . $hexData['b'] . '-' . $hexData['c'] . '-' . $hexData['d'] . '-' . $hexData['e'];
}
// Get the current directory of the script
$currentDir = __DIR__;
// Get all JSON files in the current directory
$jsonFiles = glob($currentDir . '/*.json');
// Iterate over each JSON file
foreach ($jsonFiles as $file) {
// Read the content of the file
$jsonContent = file_get_contents($file);
// Decode JSON to array
$data = json_decode($jsonContent, true);
// Check if the data is valid
if (json_last_error() === JSON_ERROR_NONE) {
// Process each SVG object
foreach ($data as &$set) {
if (isset($set['svgs'])) {
foreach ($set['svgs'] as &$svg) {
// Capitalize the 'name' field
if (isset($svg['name'])) {
$svg['name'] = capitalizeName($svg['name']);
}
// Generate a new MySQL UUID for the 'id' field
if (isset($svg['id'])) {
$svg['id'] = generateMysqlUuid();
}
}
}
}
// Re-encode the modified data to JSON
$newJsonContent = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
// Define the output file name (you can change this as needed)
$outputFile = $currentDir . '/modified_' . basename($file);
// Save the updated content back to a new file
file_put_contents($outputFile, $newJsonContent);
echo "Processed and saved to: " . basename($outputFile) . "\n";
} else {
echo "Invalid JSON in file: " . basename($file) . "\n";
}
}
?>

View File

@ -28,6 +28,8 @@ function lcp_enqueue() {
add_action('wp_enqueue_scripts', 'lcp_enqueue');
function lcp_backend_enqueue() {
// Enqueue the theme's main stylesheet (style.css)
wp_enqueue_style('lcp-style', get_stylesheet_uri());
@ -158,18 +160,7 @@ add_action('save_post', 'save_key_points_meta_box');
/* INSERT ICONS TO DB */
// Function to load the JSON file and insert SVG data into the database
function load_material_icons_into_db() {
// Path to the input JSON file in the theme's directory
$inputFile = get_template_directory() . '/assets/json/material-icons-baseline-unescaped.json';
// Step 1: Load the JSON data
$jsonData = file_get_contents($inputFile);
// Check if the file was read successfully
if ($jsonData === false) {
die("Error reading the JSON file.");
}
function load_material_icons_into_db($jsonData) {
// Step 2: Decode the JSON data into a PHP array
$data = json_decode($jsonData, true);
@ -185,7 +176,7 @@ function load_material_icons_into_db() {
// Create the table if it does not exist
$sql = "
CREATE TABLE IF NOT EXISTS $table_name (
id INT(11) NOT NULL AUTO_INCREMENT,
id VARCHAR(255) NOT NULL, -- Use the id from the JSON file
set_name VARCHAR(255) NOT NULL,
set_family VARCHAR(255) NOT NULL,
name VARCHAR(255) NOT NULL,
@ -214,9 +205,11 @@ function load_material_icons_into_db() {
$paths = stripslashes($paths); // Remove any additional escaping, such as slashes
$viewbox = sanitize_text_field($svg['viewBox']);
$id = sanitize_text_field($svg['id']); // Use the id from the JSON object
// Prepare the data for insertion
$data = array(
'id' => $id, // Use the id from the JSON object
'set_name' => $setName,
'set_family' => $setFamily,
'name' => $name,
@ -230,13 +223,12 @@ function load_material_icons_into_db() {
}
}
echo '<p>Icons have been imported into the database.</p>';
}
// Hook the function to the theme activation process
// Register the function to run after the theme is switched
add_action('after_switch_theme', 'load_material_icons_into_db');
// Function to drop the lcp_icons table when the theme is deactivated
function drop_lcp_icons_table() {
@ -258,3 +250,132 @@ function drop_lcp_icons_table() {
// Register the function to run when the theme is switched (deactivated)
add_action('switch_theme', 'drop_lcp_icons_table');
/* BACKEND ICON ADDER */
function icon_sets_dashboard_callback() {
// Get the file path to the JSON file
$json_file_path = get_template_directory() . '/assets/json/icons/icon-definitions.json';
// Check if the file exists
if (file_exists($json_file_path)) {
// Read the file contents and decode the JSON
$json_data = file_get_contents($json_file_path);
$icon_sets = json_decode($json_data, true);
if ($icon_sets) {
// Group icon sets by setFamily
$grouped_sets = [];
foreach ($icon_sets as $set) {
// Check if the set has the setFamily key
$setFamily = isset($set['setFamily']) ? $set['setFamily'] : 'Unknown';
// Initialize the family group if not already initialized
if (!isset($grouped_sets[$setFamily])) {
$grouped_sets[$setFamily] = [];
}
// Handle both 'file' and 'fileName'
// Check if 'file' is set or fallback to 'fileName'
$setFile = isset($set['file']) ? $set['file'] : (isset($set['fileName']) ? $set['fileName'] : '');
// Ensure we are correctly adding the set data
$grouped_sets[$setFamily][] = [
'id' => $set['id'],
'setName' => $set['setName'],
'file' => $setFile
];
}
// Output the HTML for the dashboard
echo '<div class="wrap">';
echo '<h1>' . esc_html('Icon Sets Dashboard') . '</h1>';
// Loop through each setFamily and create a section with checkboxes
foreach ($grouped_sets as $setFamily => $sets) {
echo '<div class="lcp-icon-set">';
echo '<h2>' . esc_html($setFamily) . '</h2>';
echo '<ul>';
// Loop through each setName and create a checkbox
foreach ($sets as $set) {
$checkbox_id = 'icon_set_' . $set['id'];
echo '<li><input type="checkbox" id="' . esc_attr($checkbox_id) . '" name="icon_sets[]" value="' . esc_attr($set['file']) . '" data-icon-set-id="' . esc_attr($set['id']) . '">';
echo '<label for="' . esc_attr($checkbox_id) . '">' . esc_html($set['setName']) . '</label></li>';
}
echo '</ul>';
echo '</div>';
}
// Add submit button
echo '<form method="POST" action="">'; // Ensure the form method is POST
echo '<input type="submit" name="submit_icon_sets" value="Import Selected Icons" class="button-primary">';
echo '</form>';
echo '</div>';
// Handle form submission
if (isset($_POST['submit_icon_sets'])) {
// Debugging: Check if form is actually submitting data
echo '<pre>';
var_dump($_POST['icon_sets']); // Check if checkboxes are selected
echo '</pre>';
// Debugging: Display selected icon sets
if (isset($_POST['icon_sets']) && !empty($_POST['icon_sets'])) {
echo '<p>Selected icon sets:</p>';
echo '<pre>';
var_dump($_POST['icon_sets']); // Output the selected icon set values
echo '</pre>';
// Loop through selected icon sets and process the corresponding JSON files
foreach ($_POST['icon_sets'] as $file) {
// Look for the icon set that matches the selected file path
foreach ($icon_sets as $set) {
// Check if the 'file' or 'fileName' matches the selected file
if ($set['file'] == $file || (isset($set['fileName']) && $set['fileName'] == $file)) {
// Get the JSON file for the selected set
$jsonFilePath = get_template_directory() . '/assets/json/icons' . (isset($set['file']) ? $set['file'] : $set['fileName']);
// Debugging: Print the json file path being used
echo '<p>Loading file: ' . esc_html($jsonFilePath) . '</p>';
if (file_exists($jsonFilePath)) {
$jsonData = file_get_contents($jsonFilePath);
load_material_icons_into_db($jsonData); // Pass the JSON data to the function
} else {
echo '<p>Error: File ' . esc_html($jsonFilePath) . ' not found.</p>';
}
break;
}
}
}
} else {
echo '<p>No icon sets selected.</p>';
}
}
} else {
echo '<p>No icon sets found in the JSON file.</p>';
}
} else {
echo '<p>Icon definitions JSON file not found.</p>';
}
}
function register_icon_dashboard_page() {
add_menu_page(
'Icon Sets', // Page Title
'Icon Sets', // Menu Title
'manage_options', // Capability required
'icon-sets-dashboard', // Menu slug
'icon_sets_dashboard_callback', // Callback function
'dashicons-admin-generic', // Icon
60 // Position in the menu
);
}
add_action('admin_menu', 'register_icon_dashboard_page');

View File

@ -1,47 +1,44 @@
import { __ } from '@wordpress/i18n';
import { BaseControl, NumberControl, SelectControl, __experimentalHStack as HStack } from '@wordpress/components';
import { BaseControl, __experimentalNumberControl as 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() {
export function DimensionValueControl() {
// 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: __('em'), value: 'em' },
{ label: __('rem'), value: 'rem' },
{ label: __('vw'), value: 'vw' },
{ label: __('pt'), value: 'pt' },
{ label: __('cm'), value: 'cm' },
{ label: __('mm'), value: 'mm' },
{ label: __('vh'), value: 'vh' }
];
// State to manage the number and unit values
const [value, setValue] = React.useState(10);
const [unit, setUnit] = React.useState('px');
return (
<BaseControl label={__('Padding with Unit')}>
<BaseControl className="lcp-dimension-value-control" // Custom class for styling parent
>
<div style={{ position: 'relative', padding: '5px', border:'1px solid red'}}>
<HStack>
{/* Number input control */}
<NumberControl
value={value}
onChange={(newValue) => setValue(newValue)}
className="lcp-number-control" // Custom class for styling parent
value={10} // Placeholder value
onChange={() => {}} // No-op for onChange
min={0}
step={1}
label={__('Value')}
/>
/>
{/* Select dropdown control for units */}
<SelectControl
value={unit}
className="lcp-select-control" // Custom class for styling parent
style={{ marginBottom: '0' }} // Applying in-line style for margin value={'px'} // Placeholder value
options={unitOptions}
onChange={(newUnit) => setUnit(newUnit)}
label={__('Unit')}
onChange={() => {}} // No-op for onChange
/>
</HStack>
</div>
</BaseControl>
);
}

View File

@ -1,12 +1,15 @@
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>
<BaseControl className="lcp-padding-control">
{/* Padding label and Unlink button */}
<HStack>
<span>{__('Padding')}</span>
@ -21,20 +24,21 @@ export function PaddingControl() {
</Button>
</HStack>
{/* Extra Large Padding Controls */}
{/* Will update all padding values for all screen sizes if updateAllScreenSizes is true */}
{/* Extra Large Padding Controls */}
{/* Will update all padding values for all screen sizes if updateAllScreenSizes is true */}
{/* Top and Bottom HStack */}
{/* 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" class="spacing-sizes-control__icon" aria-hidden="true" focusable="false">
<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 */}
<div style={{ flex: 1 }}>
<HStack style={{ flex: 1 }}>
<DimensionValueControl/>
<RangeControl
withInputField={false}
value={10} // Placeholder value
@ -42,10 +46,11 @@ export function PaddingControl() {
min={0}
max={50}
/>
</div>
</HStack>
{/* Custom Padding Button */}
<Button
style={{padding:0,background:'none',color:'var(--wp-components-color-foreground)'} }
variant="primary"
onClick={() => {}}
>
@ -56,17 +61,18 @@ export function PaddingControl() {
</Button>
</HStack>
{/* Left and Right HStack */}
<HStack style={{ flex: 1 }}>
{/* 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" class="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>
<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 */}
<div style={{ flex: 1 }}>
<RangeControl
withInputField={false}
value={10} // Placeholder value
@ -74,7 +80,7 @@ export function PaddingControl() {
min={0}
max={50}
/>
</div>
{/* Custom Padding Button */}
<Button
@ -88,7 +94,6 @@ export function PaddingControl() {
</Button>
</HStack>
{/* Additional controls can be added here in a VStack */}
<VStack>
{/* Placeholder for additional components */}

View File

@ -179,3 +179,30 @@ Version: 1.0
margin-right: 10px; /* Space between the icon and the text */
fill: var(--wp--preset--color--font-color-1);
}
/* Backend */
.lcp-dimension-value-control .lcp-number-control {margin:0;flex:3;border:0}
.lcp-dimension-value-control .components-input-control__backdrop{border:0!important}
.lcp-padding-control .lcp-dimension-value-control,.lcp-padding-control .components-range-control {flex:1!important}
.lcp-dimension-value-control .lcp-select-control{padding:0;flex:1}
.lcp-dimension-value-control .components-base-control__field {margin-bottom:0!important}
.lcp-padding-control .components-input-control__suffix {display:none!important}
.lcp-dimension-value-control .components-select-control__input {padding:5px!important}
.lcp-padding-control .lcp-dimension-value-control .lcp-number-control input,.components-select-control__input {height:25px!important;min-height:25px!important;line-height:13px!important}
.lcp-dimension-value-control .lcp-number-control input[type="number"]::-webkit-outer-spin-button,
.lcp-dimension-value-control .lcp-number-control input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* For Firefox */
.lcp-dimension-value-control .lcp-number-control input[type="number"] {
-moz-appearance: textfield; /* Hide the spinner */
}
/* Optional: Remove the appearance in other browsers */
.lcp-dimension-value-control .lcp-number-control input[type="number"] {
appearance: none;
}