1/** 2 * CSS Grid Helper for Elementor 3 * 4 * This plugin, created by Mark Harris, is designed for use with the Elementor page builder 5 * in WordPress. It allows you to easily generate CSS code for defining grid layouts 6 * within Elementor using CSS Grid. You can customize the number of rows and columns 7 * and add multiple block sets with specific grid positions. 8 * 9 * Instructions: 10 * 1. Enter the total number of rows and columns in the grid. 11 * 2. Add block sets with specific grid positions (start and end rows/columns). 12 * 3. Click "Generate Block CSS" to generate the CSS code. 13 * 14 * The generated CSS code will be displayed below and can be used in your Elementor custom CSS settings. 15 * 16 * Author: Mark Harris 17 * Version: 1.0 18 * 19 * @package CSS_Grid_Helper 20 * @version 1.0 21 */ 22 23// Add a new menu item in the WordPress admin for the CSS Grid Helper 24function css_grid_helper_add_admin_page() 25{ 26 add_menu_page( 27 "CSS Grid Helper", // Page title 28 "CSS Grid Helper", // Menu title 29 "manage_options", // Capability 30 "css-grid-helper", // Menu slug 31 "css_grid_helper_admin_page", // Function to display the page 32 "dashicons-layout", // Icon 33 110 // Position 34 ); 35} 36 37// Display the admin page content 38function css_grid_helper_admin_page() 39{ 40 ?> 41 <div class="wrap"> 42 <h1>CSS Grid Helper</h1> 43 <form id="css-grid-helper-form"> 44 <h2>Grid Size</h2> 45 <div class="input-group"> 46 <label for="grid-rows">Total Rows:</label> 47 <input type="number" id="grid-rows" name="grid_rows" min="1" value="4"> 48 </div> 49 50 <div class="input-group"> 51 <label for="grid-columns">Total Columns:</label> 52 <input type="number" id="grid-columns" name="grid_columns" min="1" value="4"> 53 </div> 54 55 <h2>Block Position and Span</h2> 56 <div class="block-set"> 57 <h3>Block Set 1</h3> 58 <div class="input-group"> 59 <label for="block-start-row">Start Row:</label> 60 <input type="number" class="block-start-row" name="block_start_row" min="1" value="1"> 61 </div> 62 63 <div class="input-group"> 64 <label for="block-end-row">End Row:</label> 65 <input type="number" class="block-end-row" name="block_end_row" min="1" value="2"> 66 </div> 67 68 <div class="input-group"> 69 <label for="block-start-column">Start Column:</label> 70 <input type="number" class="block-start-column" name="block_start_column" min="1" value="1"> 71 </div> 72 73 <div class="input-group"> 74 <label for="block-end-column">End Column:</label> 75 <input type="number" class="block-end-column" name="block_end_column" min="1" value="2"> 76 </div> 77 </div> 78 79 <button id="add-block-set" type="button" class="button button-secondary">Add Block Set</button> 80 <input type="submit" class="button button-primary" value="Generate Block CSS"> 81 </form> 82 83 <h2>Generated Block CSS</h2> 84 <textarea id="generated-css" rows="5" readonly></textarea> 85 86 <h2>Grid Preview</h2> 87 <div id="grid-preview" class="grid-container"> 88 <!-- Grid items for visualization will be added here --> 89 </div> 90 </div> 91 92 <!-- JavaScript Section --> 93 <script type="text/javascript"> 94 jQuery(document).ready(function($) { 95 var blockSetColors = ['#FFA07A', '#20B2AA', '#778899', '#9370DB', '#3CB371', '#FFD700', 96 '#FF6347', '#4682B4', '#DA70D6', '#32CD32', '#FF4500', '#6A5ACD']; 97 98 var totalRows = parseInt($('#grid-rows').val(), 10); 99 var totalColumns = parseInt($('#grid-columns').val(), 10); 100 101 function updateGridContainerStyle() { 102 var gridContainer = $('.grid-container'); 103 gridContainer.css({ 104 'grid-template-columns': 'repeat(' + totalColumns + ', 50px)' 105 }); 106 } 107 108 function validateBlockSetInput() { 109 $('.block-set').each(function() { 110 $(this).find('.block-start-row, .block-end-row').attr('max', totalRows); 111 $(this).find('.block-start-column, .block-end-column').attr('max', totalColumns); 112 }); 113 } 114 115 function updateGridPreview() { 116 var gridPreview = $('#grid-preview'); 117 gridPreview.empty(); 118 119 for (let row = 1; row <= totalRows; row++) { 120 for (let col = 1; col <= totalColumns; col++) { 121 gridPreview.append($('<div class="grid-item">R' + row + ' C' + col + '</div>')); 122 } 123 } 124 125 var css = ''; 126 $('.block-set').each(function(index) { 127 var startRow = parseInt($(this).find('.block-start-row').val(), 10); 128 var endRow = parseInt($(this).find('.block-end-row').val(), 10); 129 var startColumn = parseInt($(this).find('.block-start-column').val(), 10); 130 var endColumn = parseInt($(this).find('.block-end-column').val(), 10); 131 132 var blockColor = blockSetColors[index % blockSetColors.length]; 133 134 var blockCss = 135 "/* Block " + (index + 1) + " */\n" + 136 "selector {\n" + // Replace "selector" with your custom selector 137 " grid-row: " + startRow + "/" + (endRow + 1) + ";\n" + 138 " grid-column: " + startColumn + "/" + (endColumn + 1) + ";\n" + 139 "}\n"; 140 css += blockCss; 141 142 $('#grid-preview .grid-item').each(function() { 143 var itemRow = parseInt($(this).text().match(/R(\d+)/)[1], 10); 144 var itemCol = parseInt($(this).text().match(/C(\d+)/)[1], 10); 145 146 if (itemRow >= startRow && itemRow <= endRow && itemCol >= startColumn && itemCol <= endColumn) { 147 $(this).css('background-color', blockColor); 148 } 149 }); 150 }); 151 152 $('#generated-css').val(css); 153 updateGridContainerStyle(); 154 } 155 156 function updateBlockSetLabels() { 157 $('.block-set').each(function(index) { 158 var blockColor = blockSetColors[index % blockSetColors.length]; 159 $(this).find('h3').html('Block Set ' + (index + 1) + ' <span class="color-indicator" style="background-color: ' + blockColor + ';"></span>'); 160 }); 161 } 162 163 function addBlockSet() { 164 var blockSet = $('.block-set').first().clone(); 165 blockSet.find('input').val(''); 166 $('.block-set').last().after(blockSet); 167 168 updateBlockSetLabels(); 169 updateGridPreview(); 170 validateBlockSetInput(); 171 } 172 173 $('#add-block-set').click(function() { 174 addBlockSet(); 175 }); 176 177 $('#grid-rows, #grid-columns').change(function() { 178 totalRows = parseInt($('#grid-rows').val(), 10); 179 totalColumns = parseInt($('#grid-columns').val(), 10); 180 181 validateBlockSetInput(); 182 updateGridPreview(); 183 }); 184 185 $('#css-grid-helper-form').submit(function(event) { 186 event.preventDefault(); 187 updateGridPreview(); 188 }); 189 190 updateBlockSetLabels(); 191 updateGridPreview(); 192 validateBlockSetInput(); 193 }); 194</script> 195 196 197 <!-- CSS Section --> 198 <style type="text/css"> 199 .wrap { 200 margin: 20px; 201 } 202 .input-group { 203 margin-bottom: 15px; 204 } 205 label { 206 display: block; 207 margin-bottom: 5px; 208 } 209 input[type="number"] { 210 width: 50px; 211 } 212 .button-secondary { 213 margin-left: 10px; 214 } 215 #generated-css { 216 width: 100%; 217 font-family: monospace; 218 background-color: #f7f7f7; 219 border: 1px solid #ccc; 220 padding: 10px; 221 } 222 .grid-container { 223 margin-top: 20px; 224 max-width: 100%; 225 display: grid; 226 grid-template-columns: repeat(4, 50px); 227 grid-gap: 4px; 228 background-color: #fff; 229 padding: 4px; 230 } 231 .grid-container .grid-item { 232 background-color: rgba(255, 255, 255, 0.8); 233 border: 1px solid rgba(0, 0, 0, 0.8); 234 padding: 8px; 235 font-size: 14px; 236 text-align: center; 237 overflow: hidden; 238 transition: background-color 0.3s; 239 } 240 .block-set { 241 background-color: #f0f0f0; 242 border: 1px solid #ccc; 243 padding: 10px; 244 margin-top: 20px; 245 } 246 .block-set h3 { 247 margin: 0; 248 padding: 0; 249 font-size: 16px; 250 } 251 .color-indicator { 252 display: inline-block; 253 width: 15px; 254 height: 15px; 255 border-radius: 50%; 256 margin-left: 10px; 257 vertical-align: middle; 258 } 259 </style> 260 <?php 261} 262 263add_action("admin_menu", "css_grid_helper_add_admin_page");