Instantly share code, notes, and snippets.
gin0115/class-icon_button.php Secret
Created
October 4, 2025 17:01
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save gin0115/130d981aa3b85ef5ac3ecdb2fbe13caa to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Icon_Button Class | |
| */ | |
| class Icon_Button { | |
| /** | |
| * Initialize the service. | |
| * | |
| * @return void | |
| */ | |
| public static function init(): void { | |
| $instance = new self(); | |
| $instance->setup_hooks(); | |
| } | |
| /** | |
| * Setup WordPress hooks. | |
| * | |
| * @return void | |
| */ | |
| public function setup_hooks(): void { | |
| add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_editor_assets' ) ); | |
| add_filter( 'render_block', array( $this, 'render_button_with_icon' ), 10, 2 ); | |
| } | |
| /** | |
| * Enqueue editor assets for block customizations. | |
| * | |
| * @return void | |
| */ | |
| public function enqueue_editor_assets(): void { | |
| // Only enqueue in post editor, not in widgets editor | |
| if ( get_current_screen()->id === 'widgets' ) { | |
| return; | |
| } | |
| wp_enqueue_script( | |
| 'block-customizations', | |
| SOME_URL_CONST . 'assets/js/icon-button-variation.js', | |
| array( 'wp-blocks', 'wp-dom-ready', 'wp-edit-post', 'wp-components', 'wp-element', 'wp-block-editor' ), | |
| '1.0.0', | |
| true | |
| ); | |
| } | |
| /** | |
| * Render button with icon. | |
| * | |
| * @param string $block_content The block content. | |
| * @param array $block The block data. | |
| * | |
| * @return string The modified block content. | |
| */ | |
| public function render_button_with_icon( string $block_content, array $block ): string { | |
| // Only process core/button blocks. | |
| if ( 'core/button' !== $block['blockName'] ) { | |
| return $block_content; | |
| } | |
| // Only process on frontend, not in editor | |
| if ( is_admin() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) { | |
| return $block_content; | |
| } | |
| // Get icon attributes. | |
| $icon_svg = $block['attrs']['iconSvg'] ?? ''; | |
| $icon_position = $block['attrs']['iconPosition'] ?? 'left'; | |
| $icon_only = $block['attrs']['iconOnly'] ?? false; | |
| // Handle string values from JavaScript | |
| if ( is_string( $icon_only ) ) { | |
| $icon_only = ( $icon_only === 'true' || $icon_only === '1' ); | |
| } | |
| $icon_size = $block['attrs']['iconSize'] ?? '32px'; | |
| $icon_color = $block['attrs']['iconColor'] ?? 'currentColor'; | |
| if ( empty( $icon_svg ) ) { | |
| return $block_content; | |
| } | |
| // Get button text for tooltip/alt | |
| $button_text = ''; | |
| if ( preg_match( '/<a[^>]*>([^<]+)<\/a>/', $block_content, $matches ) ) { | |
| $button_text = $matches[1]; | |
| } | |
| // Create icon element with positioning styles | |
| $icon_styles = array( | |
| 'display: inline-block', | |
| 'vertical-align: middle', | |
| 'width: ' . $icon_size, | |
| 'height: ' . $icon_size | |
| ); | |
| // Add positioning margins (matching JavaScript logic) | |
| if ( $icon_only ) { | |
| // No margins for icon-only mode | |
| $icon_styles[] = 'margin: 0'; | |
| } else { | |
| switch ( $icon_position ) { | |
| case 'right': | |
| $icon_styles[] = 'margin-left: 0.5em'; | |
| $icon_styles[] = 'margin-right: 0'; | |
| break; | |
| case 'top': | |
| $icon_styles[] = 'margin-bottom: 0.25em'; | |
| $icon_styles[] = 'margin-top: 0'; | |
| $icon_styles[] = 'margin-left: 0'; | |
| $icon_styles[] = 'margin-right: 0'; | |
| break; | |
| case 'bottom': | |
| $icon_styles[] = 'margin-top: 0.25em'; | |
| $icon_styles[] = 'margin-bottom: 0'; | |
| $icon_styles[] = 'margin-left: 0'; | |
| $icon_styles[] = 'margin-right: 0'; | |
| break; | |
| default: // left | |
| $icon_styles[] = 'margin-right: 0.5em'; | |
| $icon_styles[] = 'margin-left: 0'; | |
| } | |
| } | |
| // Apply color if specified | |
| if ( $icon_color && $icon_color !== 'clear' ) { | |
| $icon_styles[] = 'color: ' . $icon_color; | |
| } | |
| $icon_html = '<span class="button-icon" style="' . implode( '; ', $icon_styles ) . '"' . | |
| ( $icon_only ? ' title="' . esc_attr( $button_text ) . '"' : '' ) . '>' . | |
| $icon_svg . '</span>'; | |
| // Handle icon-only mode | |
| if ( $icon_only ) { | |
| // For icon-only, just replace the button content with the icon | |
| $modified_content = str_replace( | |
| '>' . $button_text . '</a>', | |
| '>' . $icon_html . '</a>', | |
| $block_content | |
| ); | |
| } else { | |
| // Handle different positions | |
| switch ( $icon_position ) { | |
| case 'right': | |
| $modified_content = str_replace( | |
| '</a>', | |
| $icon_html . '</a>', | |
| $block_content | |
| ); | |
| break; | |
| case 'top': | |
| $modified_content = str_replace( | |
| '<a class="wp-block-button__link', | |
| '<a class="wp-block-button__link" style="display: flex !important; flex-direction: column !important; align-items: center !important; justify-content: center !important;"', | |
| $block_content | |
| ); | |
| $modified_content = str_replace( | |
| '>' . $button_text, | |
| '>' . $icon_html . $button_text, | |
| $modified_content | |
| ); | |
| break; | |
| case 'bottom': | |
| $modified_content = str_replace( | |
| '<a class="wp-block-button__link', | |
| '<a class="wp-block-button__link" style="display: flex !important; flex-direction: column !important; align-items: center !important; justify-content: center !important;"', | |
| $block_content | |
| ); | |
| $modified_content = str_replace( | |
| '>' . $button_text, | |
| '>' . $button_text . $icon_html, | |
| $modified_content | |
| ); | |
| break; | |
| default: // left | |
| $modified_content = str_replace( | |
| '>' . $button_text, | |
| '>' . $icon_html . $button_text, | |
| $block_content | |
| ); | |
| } | |
| } | |
| return $modified_content; | |
| } | |
| } | |
| // Initialize the service. | |
| Icon_Button::init(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (function() { | |
| 'use strict'; | |
| const { registerBlockVariation } = wp.blocks; | |
| const { createElement: el } = wp.element; | |
| const { InspectorControls } = wp.blockEditor; | |
| const { PanelBody, TextareaControl, Button, SelectControl, ToggleControl, ColorPicker } = wp.components; | |
| const { addFilter } = wp.hooks; | |
| const { Fragment } = wp.element; | |
| // Icon collection | |
| const iconCollection = { | |
| 'GitHub': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>', | |
| 'WordPress': '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="currentColor" version="1.1" id="Capa_1" width="800px" height="800px" viewBox="0 0 96.24 96.24" xml:space="preserve"><g><path d="M48.122,0C21.587,0,0.001,21.585,0.001,48.118c0,26.535,21.587,48.122,48.12,48.122c26.532,0,48.117-21.587,48.117-48.122 C96.239,21.586,74.654,0,48.122,0z M4.857,48.118c0-6.271,1.345-12.227,3.746-17.606l20.638,56.544 C14.81,80.042,4.857,65.243,4.857,48.118z M48.122,91.385c-4.247,0-8.346-0.623-12.222-1.763L48.88,51.903l13.301,36.433 c0.086,0.215,0.191,0.411,0.308,0.596C57.992,90.514,53.16,91.385,48.122,91.385z M54.083,27.834 c2.604-0.137,4.953-0.412,4.953-0.412c2.33-0.276,2.057-3.701-0.277-3.564c0,0-7.007,0.549-11.532,0.549 c-4.25,0-11.396-0.549-11.396-0.549c-2.332-0.137-2.604,3.427-0.273,3.564c0,0,2.208,0.275,4.537,0.412l6.74,18.469l-9.468,28.395 L21.615,27.835c2.608-0.136,4.952-0.412,4.952-0.412c2.33-0.275,2.055-3.702-0.278-3.562c0,0-7.004,0.549-11.53,0.549 c-0.813,0-1.77-0.021-2.784-0.052C19.709,12.611,33.008,4.856,48.122,4.856c11.265,0,21.519,4.306,29.215,11.357 c-0.187-0.01-0.368-0.035-0.562-0.035c-4.248,0-7.264,3.702-7.264,7.679c0,3.564,2.055,6.582,4.248,10.146 c1.647,2.882,3.567,6.585,3.567,11.932c0,3.704-1.422,8-3.293,13.986l-4.315,14.421L54.083,27.834z M69.871,85.516l13.215-38.208 c2.471-6.171,3.29-11.106,3.29-15.497c0-1.591-0.104-3.07-0.292-4.449c3.38,6.163,5.303,13.236,5.301,20.758 C91.384,64.08,82.732,78.016,69.871,85.516z"/></g></svg>', | |
| 'Download': '<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="800px" height="800px" viewBox="0 0 32 32" version="1.1"><title>download-cloud</title><path d="M0 16q0 2.912 1.824 5.088t4.576 2.752q0.032 0 0.032-0.032v-0.064t0.032-0.032q0.544-1.344 1.344-2.176t2.208-1.184v-2.336q0-2.496 1.728-4.256t4.256-1.76 4.256 1.76 1.76 4.256v2.336q1.376 0.384 2.176 1.216t1.344 2.144l0.096 0.288h0.384q2.464 0 4.224-1.76t1.76-4.224v-2.016q0-2.464-1.76-4.224t-4.224-1.76q-0.096 0-0.32 0.032 0.32-1.152 0.32-2.048 0-3.296-2.368-5.632t-5.632-2.368q-2.88 0-5.056 1.824t-2.784 4.544q-1.152-0.352-2.176-0.352-3.296 0-5.664 2.336t-2.336 5.664v1.984zM10.016 25.824q-0.096 0.928 0.576 1.6l4 4q0.576 0.576 1.408 0.576t1.408-0.576l4-4q0.672-0.672 0.608-1.6-0.064-0.32-0.16-0.576-0.224-0.576-0.736-0.896t-1.12-0.352h-1.984v-5.984q0-0.832-0.608-1.408t-1.408-0.608-1.408 0.608-0.576 1.408v5.984h-2.016q-0.608 0-1.12 0.352t-0.736 0.896q-0.096 0.288-0.128 0.576z"/></svg>', | |
| 'Direct Download': '<svg xmlns="http://www.w3.org/2000/svg" width="800px" height="800px" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 22C10.1144 22 9.17157 22 8.58579 21.4142C8 20.8284 8 19.8856 8 18C8 16.1144 8 15.1716 8.58579 14.5858C9.17157 14 10.1144 14 12 14C13.8856 14 14.8284 14 15.4142 14.5858C16 15.1716 16 16.1144 16 18C16 19.8856 16 20.8284 15.4142 21.4142C14.8284 22 13.8856 22 12 22ZM12.9159 16.2492C13.1762 15.9888 13.1762 15.5667 12.9159 15.3064C12.6555 15.046 12.2334 15.046 11.9731 15.3064L9.75084 17.5286C9.56017 17.7193 9.50313 18.006 9.60632 18.2551C9.70951 18.5042 9.9526 18.6667 10.2222 18.6667H12.1683L11.0842 19.7508C10.8238 20.0112 10.8238 20.4333 11.0842 20.6936C11.3445 20.954 11.7666 20.954 12.027 20.6936L14.2492 18.4714C14.4399 18.2807 14.4969 17.994 14.3937 17.7449C14.2905 17.4958 14.0474 17.3333 13.7778 17.3333H11.8317L12.9159 16.2492Z"/><path d="M6.49999 17.9105L6.5 18H6.28571C3.91878 18 2 16.1038 2 13.7647C2 11.4256 3.91878 9.52941 6.28571 9.52941C6.56983 9.52941 6.8475 9.55673 7.11616 9.60887C6.88706 8.9978 6.7619 8.33687 6.7619 7.64706C6.7619 4.52827 9.32028 2 12.4762 2C15.4159 2 17.8371 4.19371 18.1551 7.01498C20.393 7.78024 22 9.88113 22 12.3529C22 15.0599 20.0726 17.3221 17.5 17.8722C17.5001 17.0215 17.4989 16.2417 17.4134 15.6056C17.3178 14.8946 17.0929 14.1432 16.4749 13.5251C15.8568 12.9071 15.1054 12.6822 14.3944 12.5866C13.7488 12.4998 12.9551 12.4999 12.0895 12.5L12 12.5L11.9105 12.5C11.0449 12.4999 10.2512 12.4998 9.60558 12.5866C8.89462 12.6822 8.14317 12.9071 7.52513 13.5251C6.90708 14.1432 6.68219 14.8946 6.5866 15.6056C6.4998 16.2512 6.49989 17.0449 6.49999 17.9105Z"/></svg>', | |
| 'Documentation': '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800px" height="800px" viewBox="0 0 512 512" version="1.1" fill="currentColor"><title>doc-document</title><g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g id="icon" fill="currentColor" transform="translate(71.778133, 42.666667)"><path d="M28.864,383.082667 L34.368,383.082667 C47.5093333,383.082667 57.2373333,380.928 63.5733333,376.661333 C69.12,372.970667 73.1306667,367.296 75.584,359.573333 C77.3973333,353.856 78.3146667,347.776 78.3146667,341.312 C78.3146667,334.378667 77.2693333,327.957333 75.1573333,322.048 C73.024,316.138667 70.144,311.530667 66.4746667,308.202667 C62.976,305.088 58.9866667,302.954667 54.528,301.845333 C50.0693333,300.736 43.3493333,300.16 34.368,300.16 L28.864,300.16 L28.864,383.082667 Z M-1.42108547e-14,405.696 L-1.42108547e-14,277.568 L35.456,277.568 C50.5386667,277.568 62.5706667,279.018667 71.616,281.92 C83.4346667,285.717333 92.4586667,292.757333 98.7306667,303.018667 C105.002667,313.301333 108.16,326.186667 108.16,341.674667 C108.16,357.589333 105.002667,370.581333 98.7306667,380.650667 C90.9013333,393.344 78.8053333,401.088 62.4,403.797333 C54.8693333,405.056 45.2266667,405.696 33.472,405.696 L-1.42108547e-14,405.696 Z M186.389333,297.915733 C175.957333,297.915733 167.914667,302.2464 162.24,310.929067 C157.12,318.779733 154.56,328.827733 154.56,341.115733 C154.56,355.345067 157.589333,366.395733 163.690667,374.225067 C169.408,381.649067 177.024,385.339733 186.474667,385.339733 C196.842667,385.339733 204.928,380.987733 210.709333,372.219733 C215.829333,364.5184 218.389333,354.3424 218.389333,341.6704 C218.389333,327.739733 215.338667,316.881067 209.258667,309.0304 C203.541333,301.627733 195.904,297.915733 186.389333,297.915733 M186.474667,275.3024 C206.613333,275.3024 222.037333,281.681067 232.768,294.481067 C243.072,306.705067 248.213333,322.427733 248.213333,341.6704 C248.213333,362.705067 242.133333,379.4304 229.973333,391.8464 C219.477333,402.577067 204.970667,407.931733 186.474667,407.931733 C166.357333,407.931733 150.912,401.553067 140.181333,388.7744 C129.877333,376.5504 124.714667,360.571733 124.714667,340.859733 C124.714667,320.251733 130.816,303.7184 142.997333,291.3024 C153.536,280.635733 168.042667,275.3024 186.474667,275.3024 M362.7456,375.477333 L371.172267,398.538667 C363.556267,402.229333 356.942933,404.704 351.268267,406.005333 C345.5936,407.285333 338.596267,407.925333 330.2976,407.925333 C317.7536,407.925333 307.3856,406.133333 299.1936,402.528 C287.716267,397.450667 279.076267,389.472 273.252267,378.570667 C268.004267,368.8 265.380267,356.853333 265.380267,342.752 C265.380267,318.965333 272.6336,300.917333 287.1616,288.693333 C297.700267,279.776 311.6096,275.317333 328.846933,275.317333 C336.206933,275.317333 342.884267,275.978667 348.9216,277.322667 C354.9376,278.688 361.7856,281.077333 369.422933,284.512 L359.758933,306.229333 C349.582933,300.682667 339.812267,297.909333 330.468267,297.909333 C319.204267,297.909333 310.5856,301.770667 304.612267,309.472 C298.340267,317.557333 295.204267,328.224 295.204267,341.493333 C295.204267,355.232 298.4896,365.984 305.060267,373.728 C311.630933,381.472 320.6976,385.333333 332.2816,385.333333 C337.508267,385.333333 342.350933,384.650667 346.7456,383.221333 C351.140267,381.813333 356.4736,379.232 362.7456,375.477333 M248.221867,7.10542736e-15 L13.5552,7.10542736e-15 L13.5552,234.666667 L56.2218667,234.666667 L56.2218667,192 L56.2218667,169.6 L56.2218667,42.6666667 L230.5152,42.6666667 L312.221867,124.373333 L312.221867,169.6 L312.221867,192 L312.221867,234.666667 L354.888533,234.666667 L354.888533,106.666667 L248.221867,7.10542736e-15 L248.221867,7.10542736e-15 Z" id="DOC"></path></g></g></svg>', | |
| 'Packagist': '<svg xmlns="http://www.w3.org/2000/svg" role="img" viewBox="0 0 24 24" fill="currentColor"><title>Packagist</title><path d="M13.214 23.975c-.098-.053-.329-.062-1.615-.062h-1.26l-.017-.088-.096-.431a3.622 3.622 0 0 1-.07-.354c.005-.007-.012-.056-.038-.107l-.048-.094-.547.085c-.301.046-.598.1-.659.116-.1.03-.11.03-.103.004.038-.14.044-.201.028-.266-.018-.07-.017-.072.238-.645.276-.622.266-.594.237-.634-.018-.025-.042-.02-.307.07-.159.05-.294.093-.301.09a16.82 16.82 0 0 1 .414-.732c.451-.773.566-.976.566-1.003 0-.01-.12-.146-.271-.304-.15-.157-.311-.329-.357-.384a.584.584 0 0 0-.112-.11c-.05-.017-.264-.231-.738-.734a16.196 16.196 0 0 0-.525-.542c-.062-.05-.077-.074-.107-.175a6.511 6.511 0 0 0-.291-.714l-.096-.201v-.178c0-.271-.056-.542-.277-1.331l-.054-.191-.087-.01c-.193-.017-.283-.123-.431-.504a6.231 6.231 0 0 0-.231-.472c-.1-.191-.221-.428-.271-.532l-.086-.185-.08-.01a.72.72 0 0 0-.361.05c-.12.05-.345.063-.618.037l-.399-.038-.199-.02-.107-.191c-.161-.284-.161-.285-.238-.324-.09-.046-.161-.046-.572 0l-.325.035-.245-.035c-.645-.094-.797-.166-.797-.375 0-.042-.045-.261-.102-.489-.13-.528-.218-1.126-.195-1.332.034-.294.273-.996.636-1.87l.142-.341.023-.547c.142-3.274.178-3.76.284-3.951.035-.062.468-.431.644-.552.335-.224 1.503-.8 2.802-1.379l.384-.171.195-.012.193-.01.522.329.521.329.423-.2.658-.308c.235-.108.236-.11.367-.253.184-.201.492-.566.592-.703.118-.161.395-.388.816-.672.147-.098.185-.116.569-.264l.231-.09h.49c.451 0 .502.003.655.037.358.078.652.193.686.267.022.05.07.08.187.12.14.048.311.168 1.224.863.489.373.472.366 1.539.719l.298.1.176.211c.201.241.358.404.404.419.07.022.485-.08 1.009-.249.266-.085.303-.093.351-.077.03.01.175.02.321.02.271.005.514.034 1.117.137.153.027.281.048.283.048.002 0 .244.419.537.933.293.512.61 1.048.705 1.192.167.249.174.264.189.375.026.191.08 1.008.09 1.309l.023.896c.02.843.036 1.04.09 1.154.093.199.276.747.572 1.719l.12.401.008.930-.14.728-.158.813-.016.083-.439.264-.441.265-.321-.016c-.179-.01-.335-.016-.349-.016-.03 0-.066.113-.135.411-.04.176-.042.178-.092.187l-.666.106c-.92.145-1.037.181-1.341.424-.264.211-.264.208-.556 1.681a16.97 16.97 0 0 1-.185.856c-.105.317-.941 1.708-1.246 2.074l-.165.199.064.228c.035.126.073.265.083.309.016.07.314 1.206.421 1.609l.038.14-.201-.084-.328-.136a.549.549 0 0 0-.13-.046c-.003.004.033.15.08.327.08.288.187.763.177.773-.003 0-.15-.008-.331-.022a6.185 6.185 0 0 0-.381-.02l-.055.005-.181.662c-.1.363-.184.664-.187.667-.01.007-.536-.02-1.005-.05-.54-.035-.7-.032-.836.017-.125.045-.241.05-.306.014l.002-.001zm1.957-.348c0-.026.023-.181.05-.345.027-.165.05-.337.05-.383 0-.056.013-.116.04-.175.02-.05.036-.09.033-.093-.002-.002-.368-.03-.813-.062-.637-.046-.86-.067-1.053-.103l-.244-.046-.58.072c-.414.05-.588.078-.607.095-.02.02-.201.042-.712.094-.376.038-.717.075-.756.083l-.072.013.004.083c.003.065.02.115.083.231.06.113.088.191.12.331.02.1.042.184.046.188.003.003.973.014 2.157.023 2.034.016 2.154.018 2.191.045.046.035.064.02.064-.05l-.001-.001zm-4.782-1.179c.873-.123 1.226-.168 1.572-.194.387-.028.897-.087 1.259-.143.057-.01.248-.02.424-.026l.321-.01.377.097.379.098.682.04c.377.023.687.04.69.036a2.93 2.93 0 0 0-.07-.229c-.042-.122-.11-.333-.155-.468l-.077-.244-.231-.072-.231-.073-.156.066-.156.065-1.776.057-1.774.058-.118-.06-.118-.057H9.8l-.269.597c-.148.328-.271.602-.276.609-.008.016-.124.03 1.134-.147zm6.127-1.036c0-.017-.431-1.435-.444-1.457-.007-.012-.05.024-.115.096l-.105.115.154.568.153.568.169.06c.181.064.191.067.191.05zm-6.788-.713l.191-.355-.057-.083c-.032-.046-.063-.08-.068-.073-.007.006-.142.238-.303.515s-.297.511-.302.517c-.004.01.072-.026.171-.075l.176-.09.192-.356zm2.957-.072c.106-.306.193-.562.193-.57a.856.856 0 0 0-.198-.075 3.495 3.495 0 0 1-.201-.066.578.578 0 0 1 .063-.11l.068-.104.405-.02c.706-.033 1.114-.155 1.51-.451.15-.11.214-.128.296-.085.07.04.12.128.106.191-.01.042-.028.056-.241.197-.201.13-.876.428-1.114.492-.136.035-.289.12-.323.181-.04.066-.159.92-.132.947.006.006 1.148-.04 1.33-.056.11-.008.117-.01.161-.067.024-.032.13-.153.238-.267.106-.113.301-.333.431-.488.13-.154.328-.381.437-.502.171-.189.263-.318.619-.857.878-1.324.937-1.441 1.003-1.969.045-.375.067-.447.214-.697.146-.249.294-.965.213-1.033-.072-.06-.153-.032-.427.15-.512.341-1.039.841-1.114 1.053-.034.095-.223.373-.285.418l-.519.369c-.582.414-.52.349-.849.879l-.11.174-.327.173-.328.171-.616.015c-1.23.028-1.288.022-1.943-.207l-.431-.153-.344-.303c-.191-.168-.53-.47-.754-.672l-.407-.368-.142-.321a28.99 28.99 0 0 1-.497-1.15c-.084-.226-.09-.231-.275-.428-.341-.361-.529-.757-.757-1.612-.045-.165-.078-.259-.1-.281-.018-.016-.028-.022-.023-.012.006.01 0 .046-.012.082-.157.441-.209.768-.249 1.559-.02.359-.02.351.096.983.225 1.226.296 1.5.409 1.565.04.024.165.146.291.286.341.376.448.485.604.61.285.231.735.71.901.961.04.06.102.14.135.177.15.163.462.6.899 1.259l.314.475.13-.007c.09-.006.329.012.74.054.336.035.635.064.665.065h.056l.191-.555zm-2.276.455a1.103 1.103 0 0 0-.122-.201c-.075-.107-.14-.195-.15-.191-.01.003-.138.268-.181.374-.01.031.341.044.453.018zm2.766-2.758c.046-.033.127-.055.376-.105.311-.06.375-.083.628-.211a.309.309 0 0 0 .092-.11.74.74 0 0 1 .11-.138c.04-.036.055-.062.055-.098 0-.078.227-.275 1.091-.946a.9.9 0 0 0 .245-.268c.074-.11.158-.211.263-.309.085-.08.291-.284.459-.451.168-.171.391-.376.497-.462a3.44 3.44 0 0 0 .241-.204c.03-.032.157-.106.335-.196.159-.08.295-.156.301-.168.018-.03.09-.06.508-.217.889-.331 1.479-.492 1.79-.492.08 0 .096-.052.067-.219-.068-.395-.296-.552-.808-.552h-.181l-.063-.067c-.06-.065-.067-.087-.124-.325-.115-.485-.185-.532-.742-.516-.435.013-.552.06-1.754.718-.602.331-1.035.702-1.543 1.33a.964.964 0 0 1-.11.123c-.311-.002-.303-.472.017-.949l.106-.157-.084-.035c-.236-.107-.532-.123-.74-.04-.291.116-1.023.525-1.117.622-.098.103-.187.106-.187.007 0-.122.114-.285.289-.411.04-.032.11-.088.153-.127a1.63 1.63 0 0 1 .435-.261c.147-.06.142-.052.09-.15-.14-.255-.525-.546-.915-.689-.05-.02-.169-.07-.263-.112-.221-.102-.331-.124-.672-.136-.244-.01-.283-.014-.267-.033.074-.09.311-.133.79-.144l.384-.01.248.11c.697.301.963.462 1.074.645.076.128.084.133.194.112.266-.05.518.032.765.249.135.12.184.13.274.063a.773.773 0 0 0 .273-.502c.035-.271-.06-1.136-.153-1.385-.07-.188-.057-.196.087-.046.171.178.171.178.326-.11.04-.076.103-.176.138-.221.291-.367.281-1.047-.017-1.347-.15-.15-.404-.291-.815-.446-.403-.155-.47-.211-.77-.628-.361-.506-.425-.567-.724-.708-.617-.293-2.101-.562-2.57-.467-.441.09-1.04.447-1.32.789-.175.213-.63.377-1.274.462-.84.108-1.254.828-1.041 1.806.04.191.038.189.165.034.405-.505 1.209-.976 1.93-1.13.575-.12 1.475-.126 2.01-.01l.096.022h-.144c-.75.01-1.904.257-2.722.584l-.176.07-.016.087c-.015.083-.022.093-.281.351-.536.539-.69.796-.775 1.286-.04.239.036.589.15.678.027.022.047.05.042.06a2.825 2.825 0 0 0-.026.225c-.076.845.323 1.866.96 2.453l.144.133.108-.09c.317-.259.859-.614.888-.582.043.05.034.09-.033.155-.085.082-.196.226-.496.642l-.259.361.007.104c.01.13.076.337.147.451.03.046.09.15.136.229.167.284.321.52.424.642.096.117.184.241.284.401.028.046.05.064.07.06.04-.01.09.026.279.204.186.171.083.122.845.408.823.309 1.131.369 1.465.286.09-.022.097-.022.168.015.09.047.09.047.163-.002v.005zm-6.348-3.82c.003-.003.02-.103.037-.225.017-.12.053-.286.08-.367l.193-.644c.177-.602.159-.55.178-.52.025.042.015-.01-.016-.074a1.69 1.69 0 0 1-.066-.171l-.034-.108.034-.588.034-.589-.055-.397a6.234 6.234 0 0 0-.064-.406c-.032-.032-.464.145-.599.245-.175.13-.401.679-.492 1.194-.12.694-.008 1.647.226 1.916.07.08.226.378.357.68l.034.077.075-.01a.347.347 0 0 0 .078-.013zm14.775-1.31c.126-.088.238-.177.246-.196.015-.037.213-1.099.281-1.507l.042-.257-.042-.447-.042-.446-.125-.48c-.124-.475-.128-.484-.264-.755-.216-.431-.194-.236-.379-3.358l-.035-.578-.053-.055c-.07-.075-.337-.458-.963-1.388a14.255 14.255 0 0 0-.546-.781 16.04 16.04 0 0 0-.821-.146c-.395-.055-.736-.025-1.055.094-.128.048-.14.05-.201.03-.138-.047-.293-.003-.569.164l-.145.087-.166-.221c-.191-.251-.194-.255-.57-.502-.64-.416-.716-.449-1.632-.692-.353-.094-.311-.062-.993-.742l-.535-.532-.585.008c-.989.015-1.482.06-1.6.142-.712.508-1.094.888-1.538 1.531l-.103.15-.386.184c-.422.203-1.034.392-1.201.369-.092-.012-.421-.18-.658-.341-.438-.291-.739-.326-1.088-.124-.284.163-.483.269-1.286.675-.861.437-.965.496-1.246.705l-.164.123-.143.288c-.311.626-.305.602-.321 1.415-.03 1.52-.035 2.008-.016 2.122.03.179.036.374.016.505-.028.171-.387 1.387-.585 1.977-.066.199-.135.52-.159.736-.01.07 0 .175.036.391.026.164.07.451.097.64.066.464.12.562.358.64.209.07.309.063.732-.045.793-.203.813-.197 1.134.378.078.137.112.184.143.193.105.03.725.01.866-.027l.194-.05.056-.015-.02-.096a2.414 2.414 0 0 1-.023-.624c.024-.268.064-.506.153-.889.004-.017-.006-.004-.022.03l-.03.06-.035-.157a1.876 1.876 0 0 0-.291-.672 6.435 6.435 0 0 1-.421-.87l-.093-.231.01-.161c.05-.718.224-1.186.597-1.595.227-.248.293-.351.325-.522.025-.13.106-.807.171-1.395l.057-.547.241-.715c.13-.394.231-.722.225-.728a9.003 9.003 0 0 0-.693-.321c-.124-.035-.412-.023-.632.027-.705.161-1.224.532-1.25.893-.007.08-.362.827-.395.828-.02 0-.074-.098-.093-.169-.02-.074-.012-.115.073-.351.032-.088.097-.307.145-.487.12-.443.14-.477.405-.599l.467-.221c.675-.325 1.657-.578 1.899-.49.143.05.359.226.552.446l.092.104-.09.246c-.458 1.266-.575 1.617-.606 1.823-.071.458-.066 1.465.008 1.695.058.188.054.195-.223.377-.477.316-.953.919-.973 1.233-.013.211.09.634.221.888.052.105.589.913.606.913.006 0 .03-.04.057-.09a1.9 1.9 0 0 1 .704-.773c.316-.204.317-.204.341-.313.161-.725.425-1.144.88-1.385l.197-.105-.095-.035c-.145-.053-.271-.143-.428-.308-.697-.733-.966-1.566-.688-2.127.02-.04.052-.122.072-.184.245-.755.931-1.164 1.842-1.101.896.063 1.294.296 1.618.94.311.624.294 1.191-.055 1.751l-.066.106.06-.058c.068-.063.766-.374.946-.421.268-.07.659-.03 1.894.193.499.09.584.125.823.341.05.048.09.076.09.064s-.01-.104-.025-.206c-.083-.617.034-1.401.269-1.786.284-.466 1.375-.883 1.974-.754.301.065.769.355 1.021.635.032.036.06.056.06.045 0-.01-.02-.325-.04-.699a11.12 11.12 0 0 1-.03-.689c.008-.006.144-.084.306-.174l.293-.161.052.04c.044.032.169.063.78.191l.763.164c.027.006.085.09.216.307.097.164.271.448.388.632.425.68.502.856.411.941-.093.087-.108.086-.169-.007-.03-.045-.201-.314-.379-.595a16.068 16.068 0 0 0-.351-.539c-.02-.02-.998-.346-1.487-.497-.239-.073-.492 1.151-.434 2.099.02.319.02.321.291.57.169.156.858 1.126.993 1.397l.067.136-.006.826-.005.825-.105.177c-.441.742-.694 1.021-.985 1.096-.161.04-.339.175-.324.241.005.022.013.154.02.291.006.167.016.253.027.253.01 0 .073-.01.14-.023.455-.087.958-.057 1.261.073.11.047.116.064.128.344.017.375.042.407.353.457.348.055.468.114.695.344l.128.13.462.002.462.002.245-.168zM9.954 3.808a13.19 13.19 0 0 0-.833-.494c-.338-.171-.351-.201-.117-.309.341-.157.474-.11.908.315.168.165.369.349.448.411.156.118.328.275.328.297 0 .027-.115.14-.14.14a8.7 8.7 0 0 1-.594-.36zm3.987.19a.518.518 0 0 1-.235-.191l-.042-.07.03-.068c.04-.095.076-.13.231-.231.074-.05.159-.11.188-.134.159-.14 1.179-.558 1.358-.558.1 0 .13.02.176.125a.63.63 0 0 0 .065.12c.05.056-.06.115-.341.179-.15.034-.502.176-.818.328l-.258.125-.148.201c-.08.11-.15.201-.15.201L13.94 4l.001-.002zm2.25 8.609c.117-.103.612-.334.898-.418.104-.03.171-.307.171-.72v-.234l-.092-.191c-.097-.201-.203-.378-.221-.371-.006.002-.203.251-.437.556l-.427.552.01.249.01.444c0 .225-.006.218.09.134l-.002-.001zm1.639-1.799l.344-.132.112-.169c.391-.592.512-.901.529-1.379l.01-.308-.228-.361c-.386-.607-.636-1.018-.722-1.187a.36.36 0 0 0-.062-.1c-.062-.04-.245.12-.458.401-.15.201-.226.254-.674.478-.592.295-.876.341-1.292.213a7.003 7.003 0 0 0-.552-.156c-.042 0 .133.206.294.347.126.11.221.161.346.181.191.03.547.231 1.094.612.303.214.261.133.291.55l.027.351.08.078c.1.098.214.251.381.51.07.112.13.205.132.205l.348-.134zm-1.719-3.119c.446-.164.704-.665.527-1.023-.194-.391-.634-.702-.998-.702-.425 0-.979.482-.979.853 0 .008.058-.038.127-.104.329-.311.692-.346 1.05-.105.385.258.469.77.173 1.064-.078.08-.067.08.1.02v-.003zm-7.704-.16a.963.963 0 0 1-.026-.396c.145-.778 1.09-1.005 1.51-.364l.064.1-.009-.129c-.069-.971-1.094-1.234-1.726-.443-.356.447-.299 1.13.105 1.274.103.036.107.034.08-.042h.002zm8.86-.527c.261-.439.226-1.053-.088-1.53-.421-.642-1.084-.841-1.806-.542-.559.231-.776.517-.825 1.081-.022.251-.012.281.058.176.238-.354.644-.547 1.094-.522.712.038 1.24.539 1.385 1.316l.034.183.008.04.04-.05a1.56 1.56 0 0 0 .1-.154v.002zm-1.431.09a.125.125 0 0 0 .04-.096.127.127 0 0 0-.04-.095.128.128 0 0 0-.096-.04c-.04 0-.07.013-.097.04a.13.13 0 0 0-.038.096c0 .123.146.185.233.098l-.002-.003zm-8.218-.209c.138-.773.732-1.289 1.48-1.289.485 0 .838.274 1.043.809.054.14.06.143.087.035.07-.274-.01-.848-.163-1.149-.26-.518-1.032-.779-1.751-.591-.415.106-.9.64-.997 1.097-.1.468-.038.849.191 1.167.077.108.077.108.11-.08v.001zm1.928 0a.128.128 0 0 0 .04-.096c0-.04-.013-.07-.04-.097-.027-.028-.056-.041-.096-.041s-.07.013-.096.04a.128.128 0 0 0-.04.097.136.136 0 0 0 .232.097z"/></svg>' | |
| }; | |
| // Register Button with Icon variation | |
| registerBlockVariation('core/button', { | |
| name: 'button-with-icon', | |
| title: 'Button with Icon', | |
| description: 'A button block with SVG icon support', | |
| attributes: { | |
| iconSvg: { | |
| type: 'string', | |
| default: '' | |
| }, | |
| iconPosition: { | |
| type: 'string', | |
| default: 'left' | |
| }, | |
| iconOnly: { | |
| type: 'boolean', | |
| default: false | |
| }, | |
| iconSize: { | |
| type: 'string', | |
| default: '16px' | |
| }, | |
| iconColor: { | |
| type: 'string', | |
| default: 'currentColor' | |
| } | |
| }, | |
| isActive: (blockAttributes) => { | |
| return blockAttributes.iconSvg && blockAttributes.iconSvg.length > 0; | |
| }, | |
| scope: ['inserter', 'transform'] | |
| }); | |
| // Add iconSvg attribute to core/button block | |
| const addIconSvgAttribute = (settings, name) => { | |
| if (name !== 'core/button') { | |
| return settings; | |
| } | |
| return { | |
| ...settings, | |
| attributes: { | |
| ...settings.attributes, | |
| iconSvg: { | |
| type: 'string', | |
| default: '' | |
| }, | |
| iconPosition: { | |
| type: 'string', | |
| default: 'left' | |
| }, | |
| iconOnly: { | |
| type: 'boolean', | |
| default: false | |
| }, | |
| iconSize: { | |
| type: 'string', | |
| default: '32px' | |
| }, | |
| iconColor: { | |
| type: 'string', | |
| default: 'currentColor' | |
| } | |
| } | |
| }; | |
| }; | |
| addFilter( | |
| 'blocks.registerBlockType', | |
| 'glynnquelch2025/add-icon-svg-attribute', | |
| addIconSvgAttribute | |
| ); | |
| // Add custom controls to Button block | |
| const addButtonIconControls = (settings, name) => { | |
| if (name !== 'core/button') { | |
| return settings; | |
| } | |
| const newSettings = { | |
| ...settings, | |
| edit: (props) => { | |
| const { attributes, setAttributes } = props; | |
| const { iconSvg, iconPosition, iconOnly, iconSize, iconColor } = attributes; | |
| // Create icon grid | |
| const iconGrid = Object.entries(iconCollection).map(([name, svg]) => | |
| el(Button, { | |
| key: name, | |
| onClick: () => { | |
| setAttributes({ iconSvg: svg }); | |
| }, | |
| style: { | |
| width: '100%', | |
| height: '40px', | |
| padding: '4px', | |
| display: 'flex', | |
| alignItems: 'center', | |
| justifyContent: 'center', | |
| border: '1px solid #ddd', | |
| borderRadius: '4px', | |
| marginBottom: '8px' | |
| }, | |
| title: name | |
| }, | |
| el('div', { | |
| dangerouslySetInnerHTML: { | |
| __html: svg.replace(/width="[^"]*"/g, '').replace(/height="[^"]*"/g, '') | |
| }, | |
| style: { width: '16px', height: '16px' } | |
| }) | |
| ) | |
| ); | |
| // Get the original edit component | |
| const OriginalEdit = settings.edit; | |
| // Create enhanced edit component that adds CSS-based icon | |
| const EnhancedEdit = (editProps) => { | |
| // Call the original edit component | |
| const originalEdit = OriginalEdit(editProps); | |
| // If we have an icon, add CSS to inject it | |
| if (iconSvg) { | |
| // Use the existing button ID from the props | |
| const buttonId = props.clientId || `button-${Math.random().toString(36).substr(2, 9)}`; | |
| // Create CSS to inject the SVG using appropriate pseudo-element | |
| const pseudoElement = iconPosition === 'right' || iconPosition === 'bottom' ? '::after' : '::before'; | |
| // Encode SVG properly for data URL (without color modification) | |
| const encodedSvg = encodeURIComponent(iconSvg); | |
| const iconCSS = ` | |
| #block-${buttonId} .wp-block-button__link${pseudoElement} { | |
| content: ''; | |
| display: inline-block; | |
| width: ${iconSize}; | |
| height: ${iconSize}; | |
| margin-right: ${iconOnly ? '0' : (iconPosition === 'right' ? '0' : (iconPosition === 'top' || iconPosition === 'bottom' ? '0' : '0.5em'))}; | |
| margin-left: ${iconOnly ? '0' : (iconPosition === 'right' ? '0.5em' : (iconPosition === 'top' || iconPosition === 'bottom' ? '0' : '0'))}; | |
| margin-bottom: ${iconOnly ? '0' : (iconPosition === 'top' ? '0.25em' : (iconPosition === 'bottom' ? '0' : '0'))}; | |
| margin-top: ${iconOnly ? '0' : (iconPosition === 'bottom' ? '0.25em' : '0')}; | |
| vertical-align: middle; | |
| ${iconColor && iconColor !== 'clear' ? ` | |
| -webkit-mask: url('data:image/svg+xml;charset=utf-8,${encodedSvg}') no-repeat center; | |
| mask: url('data:image/svg+xml;charset=utf-8,${encodedSvg}') no-repeat center; | |
| -webkit-mask-size: contain; | |
| mask-size: contain; | |
| background-color: ${iconColor}; | |
| background-image: none; | |
| ` : ` | |
| background-image: url('data:image/svg+xml;charset=utf-8,${encodedSvg}'); | |
| background-size: contain; | |
| background-repeat: no-repeat; | |
| background-position: center; | |
| color: inherit; | |
| `} | |
| } | |
| ${(iconPosition === 'top' || iconPosition === 'bottom') && !iconOnly ? ` | |
| #block-${buttonId}.wp-block-button .wp-block-button__link { | |
| display: flex !important; | |
| flex-direction: column !important; | |
| align-items: center !important; | |
| justify-content: center !important; | |
| } | |
| ` : ''} | |
| ${iconOnly ? ` | |
| #block-${buttonId} .wp-block-button__link { | |
| text-indent: -9999px; | |
| overflow: hidden; | |
| white-space: nowrap; | |
| min-width: 40px; | |
| min-height: 40px; | |
| display: flex !important; | |
| flex-direction: unset !important; | |
| align-items: center !important; | |
| justify-content: center !important; | |
| } | |
| #block-${buttonId} .wp-block-button__link * { | |
| display: none !important; | |
| } | |
| ` : ''} | |
| `; | |
| // Create style element as sibling | |
| const styleElement = el('style', { | |
| dangerouslySetInnerHTML: { __html: iconCSS } | |
| }); | |
| return el(Fragment, {}, styleElement, originalEdit); | |
| } | |
| return originalEdit; | |
| }; | |
| const originalEdit = EnhancedEdit(props); | |
| return el(Fragment, {}, | |
| originalEdit, | |
| el(InspectorControls, {}, | |
| el(PanelBody, { | |
| title: 'Icon Settings', | |
| initialOpen: false | |
| }, | |
| el('div', { style: { marginBottom: '16px' } }, | |
| el('label', { style: { fontWeight: 'bold', marginBottom: '8px', display: 'block' } }, 'Preset Icons'), | |
| el('div', { | |
| style: { | |
| display: 'grid', | |
| gridTemplateColumns: '1fr 1fr', | |
| gap: '8px' | |
| } | |
| }, ...iconGrid) | |
| ), | |
| el(TextareaControl, { | |
| label: 'Custom SVG Icon Code', | |
| help: 'Paste your custom SVG code here. The icon will appear before the button text.', | |
| value: iconSvg || '', | |
| onChange: (value) => { | |
| setAttributes({ iconSvg: value }); | |
| }, | |
| rows: 4, | |
| placeholder: '<svg>...</svg>' | |
| }), | |
| el(SelectControl, { | |
| label: 'Icon Position', | |
| value: iconPosition || 'left', | |
| options: [ | |
| { label: 'Left', value: 'left' }, | |
| { label: 'Right', value: 'right' }, | |
| { label: 'Top', value: 'top' }, | |
| { label: 'Bottom', value: 'bottom' } | |
| ], | |
| onChange: (value) => setAttributes({ iconPosition: value }) | |
| }), | |
| el(ToggleControl, { | |
| label: 'Icon Only', | |
| help: 'Show only the icon. Button text will be used as tooltip/alt text.', | |
| checked: iconOnly || false, | |
| onChange: (value) => setAttributes({ iconOnly: value }) | |
| }), | |
| el(TextareaControl, { | |
| label: 'Icon Size', | |
| help: 'Size of the icon (e.g., 16px, 20px, 1.5em)', | |
| value: iconSize || '16px', | |
| onChange: (value) => setAttributes({ iconSize: value }), | |
| rows: 1, | |
| placeholder: '16px' | |
| }), | |
| el('div', { style: { marginBottom: '16px' } }, | |
| el('label', { style: { fontWeight: 'bold', marginBottom: '8px', display: 'block' } }, 'Icon Color'), | |
| el('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } }, | |
| el(ColorPicker, { | |
| color: iconColor && iconColor !== 'clear' ? iconColor : 'currentColor', | |
| onChange: (value) => setAttributes({ iconColor: value }) | |
| }), | |
| el(Button, { | |
| isSmall: true, | |
| variant: 'secondary', | |
| onClick: () => setAttributes({ iconColor: 'clear' }) | |
| }, 'Clear') | |
| ) | |
| ) | |
| ) | |
| ) | |
| ); | |
| } | |
| }; | |
| return newSettings; | |
| }; | |
| // Apply the filter | |
| addFilter( | |
| 'blocks.registerBlockType', | |
| 'glynnquelch2025/button-icon-controls', | |
| addButtonIconControls | |
| ); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment