diff --git a/.plugin-data b/.plugin-data index ce50bd5..9425050 100644 --- a/.plugin-data +++ b/.plugin-data @@ -1,4 +1,4 @@ { - "version": "1.0.8", + "version": "1.1.0", "slug": "blockparty-icons" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f42f76..106e882 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ This plugin **doesn't run any sanitization on SVGs** before using them. Only use ## Changelog +### 1.1.0 - 2026-08-14 + +- Add WP-CLI command to convert `beapi/icon-block` / `beapi/icon-item` old contents to `blockparty/icon` + ### 1.0.8 - 2026-06-26 - Fix icon padding values missing CSS units in the editor diff --git a/MIGRATION.md b/MIGRATION.md new file mode 100644 index 0000000..35b1bad --- /dev/null +++ b/MIGRATION.md @@ -0,0 +1,126 @@ +# Migrating from `beapi/icon-block` to `blockparty-icons` + +This document describes how to move from the abandoned [`beapi/icon-block`](https://github.com/BeAPI/beapi-icon-block) package to `beapi/blockparty-icons`. + +## Package swap + +```bash +composer remove beapi/icon-block +composer require beapi/blockparty-icons +``` + +Activate `blockparty-icons` and deactivate `icon-block`. + +## Theme API changes + +| `beapi/icon-block` | `blockparty-icons` | +|---|---| +| Namespace `Beapi\IconBlock\` | Namespace `Blockparty\Icons\` | +| Constant `BEAPI_ICON_DIR` | Constant `BLOCKPARTY_ICONS_DIR` | +| Action `icon_block_init` | Action `blockparty_icons_init` | +| `register_icon_collection()` | Same helper name under the new namespace | + +Example: + +```php +use Blockparty\Icons\Icon\Collection; +use function Blockparty\Icons\register_icon_collection; + +add_action( + 'blockparty_icons_init', + static function () { + register_icon_collection( + 'my_collection', + [ + 'label' => 'My custom icons collection', + 'type' => 'sprite', + 'source' => get_stylesheet_directory() . '/dist/icons/sprite.svg', + ] + ); + } +); +``` + +You can also pass a `Collection` instance built with `Collection::from_sprite()` / `Collection::from_folder()`. + +## Block model changes + +| Old | New | +|---|---| +| Parent `beapi/icon-block` + child `beapi/icon-item` | Single dynamic block `blockparty/icon` | +| Saved markup `ul` / `li` (v3) or `div.icon-container` (legacy) | Server-rendered `div.wp-block-blockparty-icon` | +| Allowlist / block styles on `beapi/icon-block` | Register against `blockparty/icon` | +| CSS `.wp-block-beapi-icon-block` | CSS `.wp-block-blockparty-icon` | + +### Attribute mapping + +| Old (`icon-item` / legacy parent) | New (`blockparty/icon`) | +|---|---| +| `icon` (`name`, `type`, `label`, optional `collection`) | `icon` (requires `collection` + `name`) | +| Parent `collection.name` (legacy object) | `icon.collection` | +| `iconColorValue` / legacy `iconColor.color` | `iconColor` (value kept as-is, including `inherit`) | +| `size` (int) | `size` (int) | +| `borderRadius` (int) | `borderRadius` (string, e.g. `0px`) | +| `url`, `label`, `className` | same | +| Custom attrs (e.g. `sharedBlockId`) | preserved | + +Empty parent shells (no icon selected) become an empty `blockparty/icon` with preserved `className` / custom attrs. + +Multiple `beapi/icon-item` children become sibling `blockparty/icon` blocks. + +## Content migration (WP-CLI) + +After activating `blockparty-icons` and updating theme collections: + +```bash +# Preview (current site) +wp blockparty-icons migrate-from-icon-block --dry-run + +# Apply on the current site +wp blockparty-icons migrate-from-icon-block + +# Limit post types +wp blockparty-icons migrate-from-icon-block --post-type=post,page +``` + +The command always targets **one site only**. On multisite, repeat it yourself with `--url=` for each site: + +```bash +wp blockparty-icons migrate-from-icon-block --url=https://example.com/ +wp blockparty-icons migrate-from-icon-block --url=https://example.com/site-2/ +``` + +The command: + +1. Scans `post_content` for `beapi/icon-block` / `beapi/icon-item` +2. Parses blocks, converts markup recursively, serializes back (attrs only — no asset resolution that aborts conversion) +3. Updates the post with `wp_slash()` on content (required so `\u002d` escapes for `--` in block comments are not stripped by `wp_update_post()`) +4. Logs migrated / skipped counts +5. Lists missing icon assets (`collection/name`) so you can add them manually to theme assets / collections + +When `collection` is missing on the icon object (and not on the parent attrs), the block is skipped — there is no default collection. Missing files among converted icons are reported, not skipped. + +### Revisions + +Only the scanned post types are migrated (public REST post types + `wp_block` by default). **Revisions are not included**, so parent posts are updated while historical revisions can still contain the old `beapi/icon-block` / `beapi/icon-item` markup. That is expected. To migrate revisions as well, pass them explicitly, for example: + +```bash +wp blockparty-icons migrate-from-icon-block --post-type=revision +``` + +### Duplicate Post (Yoast) + +If [Yoast Duplicate Post](https://wordpress.org/plugins/duplicate-post/) is active, updating a Rewrite & Republish **copy** via `wp_update_post()` (especially without `--user=`) can call `wp_die( 'You are not allowed to republish this post.' )` and abort the whole WP-CLI run. + +Preferred workaround: skip that plugin for the migration only (global WP-CLI flag): + +```bash +wp --skip-plugins=duplicate-post blockparty-icons migrate-from-icon-block --url=https://example.com/ +``` + +## Front-end checklist + +- Re-register custom block styles (e.g. `is-style-inline`) on `blockparty/icon` +- Update theme SCSS selectors from `.wp-block-beapi-icon-block` to `.wp-block-blockparty-icon` +- Update block patterns / allowlists +- Smoke-test sprite vs raw icons, colors, sizes, and shared blocks diff --git a/blockparty-icons.php b/blockparty-icons.php index 96a27b5..5ac3209 100644 --- a/blockparty-icons.php +++ b/blockparty-icons.php @@ -4,7 +4,7 @@ * Description: Provides blocks in WordPress editor to add custom SVG icons. * Requires at least: 6.2 * Requires PHP: 8.1 - * Version: 1.0.8 + * Version: 1.1.0 * Author: Be API Technical Team * Author URI: https://beapi.fr * License: GPL-2.0-or-later @@ -15,6 +15,7 @@ namespace Blockparty\Icons; +use Blockparty\Icons\Cli\MigrateFromIconBlockCommand; use Blockparty\Icons\Icon\Collection; use Blockparty\Icons\Icon\CollectionCreationException; use Blockparty\Icons\Icon\CollectionItemsFactory; @@ -29,7 +30,7 @@ include_once __DIR__ . '/vendor/autoload.php'; } -define( 'BLOCKPARTY_ICONS_VERSION', '1.0.8' ); +define( 'BLOCKPARTY_ICONS_VERSION', '1.1.0' ); define( 'BLOCKPARTY_ICONS_URL', plugin_dir_url( __FILE__ ) ); define( 'BLOCKPARTY_ICONS_DIR', plugin_dir_path( __FILE__ ) ); define( 'BLOCKPARTY_ICONS_PLUGIN_BASENAME', plugin_basename( __FILE__ ) ); @@ -333,3 +334,7 @@ function allow_css_attributes( $attr ) { } add_filter( 'safe_style_css', __NAMESPACE__ . '\\allow_css_attributes' ); + +if ( defined( 'WP_CLI' ) && WP_CLI ) { + \WP_CLI::add_command( 'blockparty-icons migrate-from-icon-block', MigrateFromIconBlockCommand::class ); +} diff --git a/includes/Cli/MigrateFromIconBlockCommand.php b/includes/Cli/MigrateFromIconBlockCommand.php new file mode 100644 index 0000000..84fa914 --- /dev/null +++ b/includes/Cli/MigrateFromIconBlockCommand.php @@ -0,0 +1,228 @@ +] + * : Comma-separated list of post types. Default: any public post type that shows in the REST API, plus wp_block. + * + * [--posts-per-page=] + * : Batch size. Default: 100. + * + * ## EXAMPLES + * + * wp blockparty-icons migrate-from-icon-block --dry-run + * wp blockparty-icons migrate-from-icon-block --post-type=post,page + * wp blockparty-icons migrate-from-icon-block --url=https://example.com/ + * + * @subcommand migrate-from-icon-block + * + * @param array $args Positional arguments. + * @param array $assoc_args Associative arguments. + * @return void + * @author Jules Fell + */ + public function __invoke( $args, $assoc_args ): void { + $dry_run = (bool) WP_CLI\Utils\get_flag_value( $assoc_args, 'dry-run', false ); + $posts_per_page = (int) ( $assoc_args['posts-per-page'] ?? 100 ); + $post_types = $this->resolve_post_types( $assoc_args['post-type'] ?? '' ); + + if ( empty( $post_types ) ) { + WP_CLI::error( 'No post types to migrate.' ); + } + + WP_CLI::log( + sprintf( + 'Migrating site %1$d (%2$s)%3$s — post types: %4$s', + get_current_blog_id(), + home_url( '/' ), + $dry_run ? ' [dry-run]' : '', + implode( ', ', $post_types ) + ) + ); + + $migrator = new IconBlockMigrator(); + $posts_updated = 0; + $posts_scanned = 0; + $page = 1; + $max_pages = 1; + $total_migrated = 0; + $total_skipped = 0; + + while ( $page <= $max_pages ) { + $query = new WP_Query( + [ + 'post_type' => $post_types, + 'post_status' => 'any', + 'posts_per_page' => $posts_per_page, + 'paged' => $page, + 'orderby' => 'ID', + 'order' => 'ASC', + 'ignore_sticky_posts' => true, + 'no_found_rows' => false, + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + ] + ); + + $max_pages = (int) $query->max_num_pages; + + if ( ! $query->have_posts() ) { + break; + } + + foreach ( $query->posts as $post ) { + ++$posts_scanned; + + if ( ! is_string( $post->post_content ) || '' === $post->post_content ) { + continue; + } + + if ( false === strpos( $post->post_content, 'beapi/icon-block' ) && false === strpos( $post->post_content, 'beapi/icon-item' ) ) { + continue; + } + + $before_migrated = $migrator->migrated; + $before_skipped = $migrator->skipped; + $new_content = $migrator->migrate_content( $post->post_content ); + + $delta_migrated = $migrator->migrated - $before_migrated; + $delta_skipped = $migrator->skipped - $before_skipped; + $total_migrated += $delta_migrated; + $total_skipped += $delta_skipped; + + if ( null === $new_content ) { + continue; + } + + ++$posts_updated; + + WP_CLI::log( + sprintf( + '%1$s post %2$d (%3$s) — blocks migrated: %4$d, skipped: %5$d', + $dry_run ? '[dry-run]' : '[update]', + (int) $post->ID, + $post->post_type, + $delta_migrated, + $delta_skipped + ) + ); + + if ( ! $dry_run ) { + // wp_update_post() expects slashed data; without wp_slash(), + // block comment escapes like \u002d (for "--") become bare "u002d". + $updated = wp_update_post( + [ + 'ID' => (int) $post->ID, + 'post_content' => wp_slash( $new_content ), + ], + true + ); + + if ( is_wp_error( $updated ) ) { + WP_CLI::warning( + sprintf( + 'Failed to update post %1$d: %2$s', + (int) $post->ID, + $updated->get_error_message() + ) + ); + } + } + } + + ++$page; + wp_reset_postdata(); + } + + WP_CLI::success( + sprintf( + 'Done. Posts scanned: %1$d, posts %2$s: %3$d, icon blocks migrated: %4$d, skipped: %5$d.', + $posts_scanned, + $dry_run ? 'that would update' : 'updated', + $posts_updated, + $total_migrated, + $total_skipped + ) + ); + + $this->report_missing_icons( $migrator->missing_icons ); + } + + /** + * Print icons referenced by migrated markup but missing from collections/assets. + * + * @param array $missing_icons Keys are "collection/name", values are counts. + * @return void + * @author Jules Fell + */ + private function report_missing_icons( array $missing_icons ): void { + if ( empty( $missing_icons ) ) { + WP_CLI::log( 'No missing icon assets detected.' ); + return; + } + + arsort( $missing_icons, SORT_NUMERIC ); + + WP_CLI::warning( + sprintf( + '%d icon asset(s) are referenced in migrated markup but were not found in registered collections. Add them to theme assets (or the matching collection) if needed:', + count( $missing_icons ) + ) + ); + + foreach ( $missing_icons as $key => $count ) { + WP_CLI::log( sprintf( ' - %s (%d)', $key, $count ) ); + } + } + + /** + * Resolve target post types. + * + * @param string $raw Comma-separated post types from CLI. + * @return string[] + * @author Jules Fell + */ + private function resolve_post_types( string $raw ): array { + if ( '' !== trim( $raw ) ) { + $types = array_filter( array_map( 'trim', explode( ',', $raw ) ) ); + + return array_values( $types ); + } + + $types = get_post_types( + [ + 'public' => true, + 'show_in_rest' => true, + ], + 'names' + ); + + $types[] = 'wp_block'; + $types = array_unique( array_values( $types ) ); + + return $types; + } +} diff --git a/includes/Migration/IconBlockMigrator.php b/includes/Migration/IconBlockMigrator.php new file mode 100644 index 0000000..d0d19e6 --- /dev/null +++ b/includes/Migration/IconBlockMigrator.php @@ -0,0 +1,354 @@ + count. + * + * @var array + */ + public $missing_icons = []; + + /** + * Entry point: rewrite post content, or return null if nothing to do. + * + * @param string $content Post content. + * @return string|null + * @author Jules Fell + */ + public function migrate_content( string $content ): ?string { + if ( false === strpos( $content, 'beapi/icon-block' ) && false === strpos( $content, 'beapi/icon-item' ) ) { + return null; + } + + // WP native: string → blocks → string. + $new = serialize_blocks( $this->migrate_blocks( parse_blocks( $content ) ) ); + + return $new === $content ? null : $new; + } + + /** + * Walk every block. Replace old icon blocks. Recurse into groups/columns/etc. + * + * Important: keep parent innerContent HTML strings (group/columns wrappers). + * Only replace the null placeholders that point to inner blocks. + * + * @param array $blocks Parsed blocks. + * @return array + * @author Jules Fell + */ + private function migrate_blocks( array $blocks ): array { + $out = []; + + foreach ( $blocks as $block ) { + $name = $block['blockName'] ?? ''; + + // Old parent block → one or more blockparty/icon. + if ( 'beapi/icon-block' === $name ) { + $out = array_merge( $out, $this->convert_old_block( $block ) ); + continue; + } + + // Rare: icon-item alone. + if ( 'beapi/icon-item' === $name ) { + $new = $this->build_blockparty_block( $block['attrs'] ?? [], [], (string) ( $block['innerHTML'] ?? '' ) ); + if ( null === $new ) { + ++$this->skipped; + $out[] = $block; + continue; + } + $out[] = $new; + continue; + } + + // Nested blocks (group, columns…): migrate children, keep wrapper HTML. + if ( ! empty( $block['innerBlocks'] ) ) { + $block = $this->migrate_inner_blocks( $block ); + } + + $out[] = $block; + } + + return $out; + } + + /** + * Migrate innerBlocks while preserving innerContent HTML chunks. + * + * innerContent looks like: [ '
', null, '', null, '
' ] + * Strings = wrappers to keep. null = slot for one inner block. + * + * @param array $block Parent block with children. + * @return array + * @author Jules Fell + */ + private function migrate_inner_blocks( array $block ): array { + $new_inners = []; + $new_content = []; + $inner_index = 0; + + foreach ( $block['innerContent'] as $chunk ) { + // Keep HTML wrappers as-is (opening/closing divs, separators…). + if ( is_string( $chunk ) ) { + $new_content[] = $chunk; + continue; + } + + // null placeholder → migrate that child (may become 1..n blocks). + $child = $block['innerBlocks'][ $inner_index ] ?? null; + ++$inner_index; + $replacements = null === $child ? [] : $this->migrate_blocks( [ $child ] ); + + foreach ( $replacements as $i => $replacement ) { + if ( $i > 0 ) { + // Extra siblings need an empty separator between null slots. + $new_content[] = ''; + } + $new_content[] = null; + $new_inners[] = $replacement; + } + } + + $block['innerBlocks'] = $new_inners; + $block['innerContent'] = $new_content; + + return $block; + } + + /** + * Convert one beapi/icon-block. + * + * Case A — v3: has beapi/icon-item children → one new icon per child. + * Case B — legacy / empty: convert the parent itself. + * + * @param array $block Old parent block. + * @return array New blocks (or the original block if conversion failed). + * @author Jules Fell + */ + private function convert_old_block( array $block ): array { + $parent_attrs = is_array( $block['attrs'] ?? null ) ? $block['attrs'] : []; + $items = array_values( + array_filter( + $block['innerBlocks'] ?? [], + static fn( $inner ) => ( $inner['blockName'] ?? '' ) === 'beapi/icon-item' + ) + ); + + // Case A: v3 children. All-or-nothing: if one child fails, keep the + // parent and roll back counters from successful siblings in this batch. + if ( $items ) { + $before_migrated = $this->migrated; + $before_missing = $this->missing_icons; + $converted = []; + + foreach ( $items as $item ) { + $new = $this->build_blockparty_block( + is_array( $item['attrs'] ?? null ) ? $item['attrs'] : [], + $parent_attrs, + (string) ( $item['innerHTML'] ?? '' ) + ); + if ( null === $new ) { + $this->migrated = $before_migrated; + $this->missing_icons = $before_missing; + ++$this->skipped; + return [ $block ]; + } + $converted[] = $new; + } + + return $converted; + } + + // Case B: legacy single icon or empty shell. + $new = $this->build_blockparty_block( $parent_attrs, [], (string) ( $block['innerHTML'] ?? '' ) ); + if ( null === $new ) { + ++$this->skipped; + return [ $block ]; + } + + return [ $new ]; + } + + /** + * Build a blockparty/icon from old attributes (+ HTML hints if needed). + * + * Markup only: always writes blockparty/icon when a name can be inferred. + * Missing assets are recorded, not used to abort the conversion. + * + * @param array $attrs Source attrs (item or legacy parent). + * @param array $parent_attrs Parent attrs (for className / collection). + * @param string $html Saved HTML of the old block. + * @return array|null Null when an icon was expected but name or collection is missing. + * @author Jules Fell + */ + private function build_blockparty_block( array $attrs, array $parent_attrs, string $html ): ?array { + $old_icon = is_array( $attrs['icon'] ?? null ) ? $attrs['icon'] : []; + $name = (string) ( $old_icon['name'] ?? '' ); + + // Legacy HTML fallback: class="icon-xxx". + // Skip structural fragments from wrappers / block classes (icon-container, + // wp-block-beapi-icon-block, wp-block-beapi-icon-item). + // Use (?![a-z0-9_-]) instead of \b after container|block|item: in PCRE, \b + // matches before "-", so icon-item-check / icon-block-quote would be rejected. + if ( '' === $name && preg_match( '/\bicon-(?!container(?![a-z0-9_-])|block(?![a-z0-9_-])|item(?![a-z0-9_-]))([a-z0-9_-]+)\b/i', $html, $m ) ) { + $name = $m[1]; + } + + // Do not treat the legacy icon-container wrapper alone as an expected icon: + // empty shells must become empty blockparty/icon blocks. + $expects_icon = ( '' !== $name || $old_icon ); + + // Collection from attrs only (no registry lookup, no project-specific default). + $collection = (string) ( $old_icon['collection'] ?? '' ); + if ( '' === $collection ) { + $raw = $attrs['collection'] ?? $parent_attrs['collection'] ?? null; + $collection = is_array( $raw ) ? (string) ( $raw['name'] ?? '' ) : (string) $raw; + } + + // Abort when we expected an icon but name or collection is missing. + if ( $expects_icon && ( '' === $name || '' === $collection ) ) { + return null; + } + + $new = []; + + if ( '' !== $name ) { + $type = (string) ( $old_icon['type'] ?? ( false !== strpos( $html, ' $collection, + 'name' => $name, + 'type' => $type, + 'label' => (string) ( $old_icon['label'] ?? $name ), + ]; + + $this->record_missing_icon( $collection, $name ); + } + + // Color: map attrs only (keep inherit/currentColor as stored; renderer may sanitize). + $color = $attrs['iconColorValue'] ?? $attrs['iconColor'] ?? $parent_attrs['iconColor'] ?? null; + if ( is_array( $color ) ) { + $color = $color['color'] ?? null; + } + if ( is_string( $color ) && '' !== $color ) { + $new['iconColor'] = $color; + } + + // Size (attr or CSS width in HTML). + $size = $attrs['size'] ?? null; + if ( null === $size && preg_match( '/width:\s*(\d+)px/i', $html, $m ) ) { + $size = (int) $m[1]; + } + if ( is_numeric( $size ) ) { + $new['size'] = (int) $size; + } + + // Border radius: old int → "Npx". + if ( isset( $attrs['borderRadius'] ) && is_numeric( $attrs['borderRadius'] ) ) { + $new['borderRadius'] = ( (int) $attrs['borderRadius'] ) . 'px'; + } elseif ( ! empty( $attrs['borderRadius'] ) && is_string( $attrs['borderRadius'] ) ) { + $new['borderRadius'] = $attrs['borderRadius']; + } + + if ( ! empty( $attrs['url'] ) && is_string( $attrs['url'] ) ) { + $new['url'] = $attrs['url']; + } + if ( ! empty( $attrs['label'] ) && is_string( $attrs['label'] ) ) { + $new['label'] = $attrs['label']; + } + + $class = $attrs['className'] ?? $parent_attrs['className'] ?? ''; + if ( is_string( $class ) && '' !== $class ) { + $new['className'] = $class; + } + + // Keep extra attrs (ex: sharedBlockId), drop old icon-only keys. + foreach ( array_merge( $parent_attrs, $attrs ) as $key => $value ) { + if ( ! isset( $new[ $key ] ) && ! in_array( + $key, + [ + 'icon', + 'iconColor', + 'iconColorValue', + 'iconBackgroundColor', + 'iconBackgroundColorValue', + 'backgroundColor', + 'collection', + 'maxIcons', + 'size', + 'borderRadius', + 'padding', + 'url', + 'label', + 'rel', + 'text', + 'content', + 'className', + ], + true + ) ) { + $new[ $key ] = $value; + } + } + + ++$this->migrated; + + return [ + 'blockName' => 'blockparty/icon', + 'attrs' => $new, + 'innerBlocks' => [], + 'innerHTML' => '', + 'innerContent' => [], + ]; + } + + /** + * Record a migrated icon that is not available in registered collections. + * + * @param string $collection Collection name. + * @param string $name Icon name. + * @return void + * @author Jules Fell + */ + private function record_missing_icon( string $collection, string $name ): void { + if ( '' === $collection || '' === $name ) { + return; + } + + if ( ! function_exists( '\\Blockparty\\Icons\\get_icon_collection' ) ) { + return; + } + + $col = \Blockparty\Icons\get_icon_collection( $collection ); + if ( $col && $col->get( $name ) ) { + return; + } + + $key = $collection . '/' . $name; + $this->missing_icons[ $key ] = ( $this->missing_icons[ $key ] ?? 0 ) + 1; + } +} diff --git a/package.json b/package.json index b6829db..60d0c3f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blockparty-icons", - "version": "1.0.8", + "version": "1.1.0", "description": "Provides blocks in WordPress editor to add custom SVG icons from your theme.", "author": "Be API Technical team", "license": "GPL-2.0-or-later", diff --git a/readme.txt b/readme.txt index 4d56440..12b6c02 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Tags: block, icons, svg, gutenberg, editor Requires at least: 6.2 Tested up to: 6.8 Requires PHP: 8.1 -Stable tag: 1.0.8 +Stable tag: 1.1.0 License: GPL-2.0-or-later License URI: https://www.gnu.org/licenses/gpl-2.0.html @@ -36,6 +36,9 @@ Yes. Register a collection with `type` set to `folder` and `source` pointing to == Changelog == += 1.1.0 = +* Add WP-CLI command to convert `beapi/icon-block` / `beapi/icon-item` old content to `blockparty/icon`. + = 1.0.8 = * Fix icon padding values missing CSS units in the editor. * Fix `addDefaultUnit` utility handling of undefined, null, and empty values. diff --git a/src/block.json b/src/block.json index 200d40b..37a95d2 100644 --- a/src/block.json +++ b/src/block.json @@ -2,7 +2,7 @@ "$schema": "https://schemas.wp.org/trunk/block.json", "apiVersion": 3, "name": "blockparty/icon", - "version": "1.0.8", + "version": "1.1.0", "title": "Icon", "category": "widgets", "description": "Easily add custom vector icon to your content.",