add/update icon controls

This commit is contained in:
Ray Elliott 2020-08-14 18:38:15 +01:00
parent 8645088119
commit c032afc07a
4 changed files with 161 additions and 49 deletions

View File

@ -48,7 +48,7 @@ add_action( 'init', function() {
function room_vw_iconify_enqueue_assets() { function room_vw_iconify_enqueue_assets() {
wp_enqueue_script( 'iconify', 'https://code.iconify.design/1/1.0.7/iconify.min.js', array(), '1.0.7', false ); wp_enqueue_script( 'iconify', 'https://code.iconify.design/2/2.0.0-beta.6/iconify.min.js', array(), '2.0.0-beta.6', false );
} }
add_action( 'enqueue_block_assets', 'room_vw_iconify_enqueue_assets' ); add_action( 'enqueue_block_assets', 'room_vw_iconify_enqueue_assets' );
} ); } );

View File

@ -5,5 +5,5 @@
*/ */
.wp-block-room-vw-iconify { .wp-block-room-vw-iconify {
// TODO line-height: 1;
} }

View File

@ -1,15 +1,20 @@
/* global Iconify */
import './style.scss'; import './style.scss';
import './editor.scss'; import './editor.scss';
import { registerBlockType } from '@wordpress/blocks'; import { registerBlockType } from '@wordpress/blocks';
import { RawHTML, Fragment } from '@wordpress/element'; import { RawHTML, Fragment, useState } from '@wordpress/element';
import { InspectorControls } from '@wordpress/editor'; import { BlockControls, InspectorControls } from '@wordpress/editor';
import { import {
Button, Button,
Modal,
RangeControl,
TextControl, TextControl,
ToggleControl, ToggleControl,
Panel, Toolbar,
ToolbarButton,
PanelBody,
PanelRow, PanelRow,
} from '@wordpress/components'; } from '@wordpress/components';
import { __ } from '@wordpress/i18n'; import { __ } from '@wordpress/i18n';
@ -22,87 +27,188 @@ registerBlockType('room-vw/iconify', {
supports: { supports: {
// Removes support for an HTML mode. // Removes support for an HTML mode.
html: false, html: false,
align: ['left', 'center', 'right'],
}, },
attributes: { attributes: {
prefix: { prefix: {
type: 'string', type: 'string',
source: 'attribute', default: 'simple-icons',
selector: 'data-prefix',
default: 'noto-v1',
}, },
name: { name: {
type: 'string', type: 'string',
source: 'attribute', default: 'iconify',
selector: 'data-name',
default: 'unicorn',
}, },
inline: { isInline: {
type: 'boolean', type: 'boolean',
default: false, default: true,
}, },
svg: { svg: {
type: 'string', type: 'string',
source: 'html', source: 'html',
selector: '.icon', selector: '.icon',
default: '<span>Select an icon</span>', default: '',
},
fontUnit: {
type: 'string',
default: 'px',
},
fontSize: {
type: 'number',
default: 16,
}, },
}, },
edit({ className, attributes, setAttributes }) { edit({ className, attributes, setAttributes }) {
/* eslint-disable react-hooks/rules-of-hooks */
const [modalIsOpen, setOpen] = useState(false);
const [newPrefix, setNewPrefix] = useState(attributes.prefix);
const [newName, setNewName] = useState(attributes.name);
/* eslint-enable react-hooks/rules-of-hooks */
const updateIcon = () => {
const iconString = `${newPrefix}:${newName}`;
if (!Iconify.iconExists(iconString)) {
// TODO loading indicator
Iconify.loadIcons([iconString], () => {
// TODO if icon not found
setSVG(Iconify.renderHTML(iconString), newPrefix, newName);
closeModal();
});
} else {
setSVG(Iconify.renderHTML(iconString), newPrefix, newName);
closeModal();
}
};
const setSVG = (svg, prefix, name) => {
setAttributes({
svg,
prefix,
name,
});
};
const openModal = () => {
setOpen(true);
};
const closeModal = () => {
setOpen(false);
};
return ( return (
<Fragment> <Fragment>
<InspectorControls> <InspectorControls>
<Panel> <PanelBody title="Icon settings">
<RangeControl
label={`Font size (${attributes.fontUnit})`}
value={attributes.fontSize}
min={attributes.fontUnit === 'em' ? '0.5' : '8'}
max={attributes.fontUnit === 'em' ? '20' : '320'}
step={attributes.fontUnit === 'em' ? '0.1' : '1'}
onChange={(value) => {
setAttributes({ fontSize: value });
}}
/>
<PanelRow></PanelRow>
<PanelRow> <PanelRow>
<ToggleControl
label="Is isInline"
checked={attributes.isInline}
onChange={(state) => {
setAttributes({ isInline: state });
}}
/>
<ToggleControl
label="Use ems"
checked={attributes.fontUnit === 'em'}
onChange={(state) => {
setAttributes({
fontUnit: state ? 'em' : 'px',
fontSize: state
? attributes.fontSize / 16
: attributes.fontSize * 16,
});
}}
/>
</PanelRow>
</PanelBody>
</InspectorControls>
<BlockControls>
<Toolbar label="label">
<ToolbarButton
label="Replace icon"
icon="admin-generic"
onClick={openModal}
/>
</Toolbar>
</BlockControls>
<RawHTML
className={
className +
(attributes.isInline ? ' is-inline icon' : ' icon')
}
style={{
fontSize: attributes.fontSize + attributes.fontUnit,
}}
>
{attributes.svg}
</RawHTML>
{attributes.svg === '' && (
<Button
isBusy={false}
disabled={false}
isPrimary
onClick={openModal}
>
Choose Icon
</Button>
)}
{attributes.svg !== '' && (
<Button
isBusy={false}
disabled={false}
isTertiary
onClick={openModal}
>
Change Icon
</Button>
)}
{modalIsOpen && (
<Modal title="Select an Icon" onRequestClose={closeModal}>
<p>
<strong>TODO:</strong> Search for an icon
</p>
<TextControl <TextControl
label="Prefix" label="Prefix"
value={attributes.prefix} value={newPrefix}
onChange={(newPrefix) => { onChange={(value) => {
setAttributes({ prefix: newPrefix }); setNewPrefix(value);
}} }}
/> />
<TextControl <TextControl
label="Name" label="Name"
value={attributes.name} value={newName}
onChange={(newName) => { onChange={(value) => {
setAttributes({ name: newName }); setNewName(value);
}} }}
/> />
</PanelRow>
<PanelRow> <Button isPrimary onClick={updateIcon}>
<ToggleControl Select
label="Is inline"
checked={attributes.inline}
onChange={(state) => {
setAttributes({ inline: state });
}}
/>
<Button
isBusy={false}
disabled={false}
isSecondary
onClick={() => {
setAttributes({
svg: Iconify.getSVG(
`${attributes.prefix}:${attributes.name}`
),
});
}}
>
Get Icon
</Button> </Button>
</PanelRow>
</Panel> <Button isSecondary onClick={closeModal}>
</InspectorControls> Cancel
<RawHTML </Button>
className={ </Modal>
className + )}
(attributes.inline ? ' is-inline icon' : ' icon')
}
>
{attributes.svg}
</RawHTML>
</Fragment> </Fragment>
); );
}, },
@ -110,10 +216,12 @@ registerBlockType('room-vw/iconify', {
save({ attributes }) { save({ attributes }) {
return ( return (
<RawHTML <RawHTML
className={attributes.inline ? ' is-inline icon' : ' icon'} className={attributes.isInline ? ' is-inline icon' : ' icon'}
dataPrefix={attributes.prefix} dataPrefix={attributes.prefix}
dataName={attributes.name} dataName={attributes.name}
dataInline={attributes.inline} style={{
fontSize: attributes.fontSize + attributes.fontUnit,
}}
> >
{attributes.svg} {attributes.svg}
</RawHTML> </RawHTML>

View File

@ -1,3 +1,7 @@
.wp-block-room-vw-iconify { .wp-block-room-vw-iconify {
font-size: 4em; font-size: 4em;
&.is-inline {
display: inline;
}
} }