Skip to content

Commit

Permalink
[FEATURE] Add an icon block
Browse files Browse the repository at this point in the history
  • Loading branch information
jdamner committed Jun 19, 2024
1 parent 48847e3 commit 67c50c8
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 40 deletions.
12 changes: 12 additions & 0 deletions packages/iconography/includes/IconographyService.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,25 @@ public function __construct( private ConfigurationParser $configuration_parser )
* Init Hooks
*/
public function init(): void {
add_action( 'init', array( $this, 'register_block' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'register_assets' ) );
add_action( 'wp_footer', array( $this, 'enqueue_assets' ), 1, 0 );
add_action( 'enqueue_block_assets', array( $this, 'register_assets' ), 1, 0 );
add_action( 'enqueue_block_assets', array( $this, 'enqueue_editor_scripts' ) );
add_action( 'enqueue_block_assets', array( $this, 'enqueue_all_assets' ) );
}

/**
* Register the block
*
* @return void
*/
public function register_block(): void {
register_block_type_from_metadata(
plugin_dir_path( __DIR__ ) . 'build/block'
);
}

/**
* Register all assets in WP
*
Expand Down
4 changes: 2 additions & 2 deletions packages/iconography/src/block/Attributes.type.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { WPFormat } from '@wordpress/rich-text/build-types/register-format-type';

export type Attributes = Partial< {
className: WPFormat[ 'className' ];
tagName: WPFormat[ 'tagName' ];
iconClass: WPFormat[ 'className' ];
iconTag: WPFormat[ 'tagName' ];
iconContent: string;
} >;
46 changes: 34 additions & 12 deletions packages/iconography/src/block/Edit.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';

import { IconToolbarButton } from '../IconToolbarButton';
/* WordPress Dependencies */
import {
BlockControls,
InspectorControls,
Expand All @@ -9,14 +9,25 @@ import {
import { store as RichTextStore } from '@wordpress/rich-text';
import { useSelect } from '@wordpress/data';
import { useState } from '@wordpress/element';
import { Button, Panel, PanelBody } from '@wordpress/components';
import {
Button,
Panel,
PanelBody,
ToolbarButton,
Icon,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { replace } from '@wordpress/icons';

/* Internal deps */
import { IconModal } from '../IconModal';
import './style.scss';

/* Types */
import type { Attributes } from './Attributes.type';
import type { BlockEditProps } from '@wordpress/blocks';
import type { RichTextValue } from '@wordpress/rich-text';
import type { WPFormat } from '@wordpress/rich-text/build-types/register-format-type';
import { IconModal } from '../IconModal';

export const Edit = ( {
attributes,
Expand All @@ -42,35 +53,46 @@ export const Edit = ( {

setAttributes( {
iconContent: value.text,
tagName: format.tagName,
className: format.className,
iconTag: format.tagName,
iconClass: format.className,
} );
};

const TagName =
( attributes.tagName as keyof HTMLElementTagNameMap ) ?? 'span';
( attributes.iconTag as keyof HTMLElementTagNameMap ) ?? 'span';

const buttonText = attributes.iconContent
? __( 'Change Icon', 'boxuk' )
: __( 'Select Icon', 'boxuk' );

const ShowModalButton = () => (
<Button
variant={ 'primary' }
variant={ 'secondary' }
onClick={ () => setShowIconModal( ! showIconModal ) }
>
Select Icon
</Button>
text={ buttonText }
icon={ <Icon icon={ replace } /> }
/>
);

return (
<>
<InspectorControls>
<InspectorControls group="list">
<Panel>
<PanelBody>
<ShowModalButton />
</PanelBody>
</Panel>
</InspectorControls>
<BlockControls group="inline">
<ToolbarButton
icon={ <Icon icon={ replace } /> }
onClick={ () => setShowIconModal( ! showIconModal ) }
title={ buttonText }
/>
</BlockControls>
<div { ...blockProps }>
{ attributes.iconContent && (
<TagName className={ attributes.className ?? '' }>
<TagName className={ attributes.iconClass ?? '' }>
{ attributes.iconContent }
</TagName>
) }
Expand Down
7 changes: 4 additions & 3 deletions packages/iconography/src/block/Save.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import React from 'react';

/* WordPress Dependencies */
import { useBlockProps } from '@wordpress/block-editor';

/* Types */
import type { Attributes } from './Attributes.type';
import type { BlockSaveProps } from '@wordpress/blocks';

export const Save = ( { attributes }: BlockSaveProps< Attributes > ) => {
const { className, tagName, iconContent } = attributes;
const TagName = ( tagName as keyof HTMLElementTagNameMap ) ?? 'span';
const { iconClass, iconTag, iconContent } = attributes;
const TagName = ( iconTag as keyof HTMLElementTagNameMap ) ?? 'span';

return (
<div { ...useBlockProps.save() }>
<TagName className={ className ?? '' }>{ iconContent }</TagName>
<TagName className={ iconClass ?? '' }>{ iconContent }</TagName>
</div>
);
};
44 changes: 30 additions & 14 deletions packages/iconography/src/block/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,51 +8,67 @@
"icon": "star-filled",
"keywords": [ "icon", "emoji", "symbol" ],
"textdomain": "boxuk",
"style": "file:./style-index.css",
"editorScript": "file:./index.ts",
"supports": {
"align": [ "wide", "full" ],
"alignWide": true,
"anchor": false,
"align": [],
"alignWide": false,
"ariaLabel": true,
"background": {
"backgroundImage": false,
"backgroundSize": false
},
"className": true,
"color": {
"background": true,
"text": true
},
"background": { "backgroundImage": true, "backgroundSize": true },
"anchor": false,
"ariaLabel": true,
"className": true,
"customClassName": true,
"dimensions": { "aspectRatio": false, "minHeight": true },
"filter": { "duotone": false },
"dimensions": {
"aspectRatio": false,
"minHeight": false
},
"filter": {
"duotone": false
},
"html": false,
"inserter": true,
"interactivity": false,
"layout": true,
"lock": true,
"multiple": true,
"position": {
"sticky": false
},
"renaming": true,
"reusable": true,
"shadow": false,
"shadow": true,
"spacing": {
"margin": true,
"padding": true
"padding": true,
"blockGrap": false
},
"typography": {
"fontSize": true,
"lineHeight": true,
"lineHeight": false,
"textAlign": true
}
},
"attributes": {
"className": {
"iconClass": {
"type": "string"
},
"tagName": {
"iconTag": {
"type": "string"
},
"iconContent": {
"type": "string"
},
"style": {
"type": "object",
"default": {
"textAlign": "center"
}
}
},
"example": {}
Expand Down
14 changes: 14 additions & 0 deletions packages/iconography/src/block/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* WordPress Dependencies */
import { registerBlockType } from '@wordpress/blocks';

/* Internal deps */
import metadata from './block.json';
import { Edit } from './Edit';
import { Save } from './Save';
import { ReactComponent as AddReactionOutlined } from '../AddReactionOutlined.svg';

registerBlockType( metadata, {
icon: AddReactionOutlined,
edit: Edit,
save: Save,
} );
3 changes: 3 additions & 0 deletions packages/iconography/src/block/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.wp-block-boxuk-icon {
text-align: center;
}
9 changes: 0 additions & 9 deletions packages/iconography/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,9 @@ import React, { ComponentProps } from 'react';
/* WordPress Dependencies */
import domReady from '@wordpress/dom-ready';
import { registerFormatType } from '@wordpress/rich-text';
import { registerBlockType } from '@wordpress/blocks';
import { BlockControls } from '@wordpress/block-editor';

/* Internal deps */
import metadata from './block/block.json';
import { Edit } from './block/Edit';
import { Save } from './block/Save';
import { IconToolbarButton } from './IconToolbarButton';
import { getIconGroups, selectIconAtCurrentCursor } from './utils';

Expand Down Expand Up @@ -83,8 +79,3 @@ export const registerIconography = () => {
domReady( () => {
registerIconography();
} );

registerBlockType( metadata, {
edit: Edit,
save: Save,
} );
20 changes: 20 additions & 0 deletions packages/iconography/tests/TestIcononographyService.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class TestIcononographyService extends TestCase {
*/
public function testInit(): void {
$class_in_test = new IconographyService( new ConfigurationParser() );
\WP_Mock::expectActionAdded( 'init', array( $class_in_test, 'register_block' ) );
\WP_Mock::expectActionAdded( 'wp_enqueue_scripts', array( $class_in_test, 'register_assets' ) );
\WP_Mock::expectActionAdded( 'wp_footer', array( $class_in_test, 'enqueue_assets' ), 1, 0 );
\WP_Mock::expectActionAdded( 'enqueue_block_assets', array( $class_in_test, 'register_assets' ), 1, 0 );
Expand All @@ -35,6 +36,25 @@ public function testInit(): void {
$this->assertConditionsMet();
}

/**
* Test Register Block
*
* @return void
*/
public function testRegisterBlock(): void {
\WP_Mock::userFunction( 'plugin_dir_path' )
->once()
->andReturn( 'test/' );

\WP_Mock::userFunction( 'register_block_type_from_metadata' )
->once()
->with( 'test/build/block' );

$class_in_test = new IconographyService( new ConfigurationParser() );
$class_in_test->register_block();
$this->assertConditionsMet();
}

/**
* Test Register Assets
*
Expand Down
9 changes: 9 additions & 0 deletions packages/iconography/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );

module.exports = {
...defaultConfig,
entry: {
...defaultConfig.entry(),
index: './src/index.tsx',
},
};

0 comments on commit 67c50c8

Please sign in to comment.