Skip to content

Commit

Permalink
Merge pull request #135 from 10up/feature/131-ux-improvements
Browse files Browse the repository at this point in the history
Improved UX with spacing & color options
  • Loading branch information
jeffpaul committed Aug 1, 2023
2 parents 8e579a7 + e86edc4 commit 0962c11
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 89 deletions.
10 changes: 9 additions & 1 deletion includes/blocks/safe-svg/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,15 @@
}
},
"supports": {
"html": false
"html": false,
"color": {
"text": true,
"background": true
},
"spacing": {
"margin": true,
"padding": true
}
},
"editorScript": "file:../../../dist/safe-svg-block.js",
"style": "file:../../../dist/safe-svg-block-frontend.css"
Expand Down
102 changes: 55 additions & 47 deletions includes/blocks/safe-svg/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@
import { __ } from '@wordpress/i18n';
import {
Placeholder,
Button,
PanelBody,
} from '@wordpress/components';
import {
useBlockProps,
MediaUpload,
BlockControls,
AlignmentToolbar,
InspectorControls,
__experimentalImageSizeControl as ImageSizeControl,
MediaReplaceFlow
MediaReplaceFlow,
MediaPlaceholder
} from '@wordpress/block-editor';
import PropTypes from 'prop-types';
import { ReactSVG } from 'react-svg'

/**
* Edit component.
Expand All @@ -33,6 +33,7 @@ import PropTypes from 'prop-types';
*/
const SafeSvgBlockEdit = ( props ) => {
const { attributes, setAttributes } = props;

const {
contentPostType,
svgURL,
Expand All @@ -45,7 +46,27 @@ const SafeSvgBlockEdit = ( props ) => {
dimensionWidth,
dimensionHeight
} = attributes;
const blockProps = useBlockProps();
const blockProps = useBlockProps(
{
className:` safe-svg-cover`,
style: {
textAlign: alignment,
}
}
);
const { className, style, ...containerBlockProps } = blockProps;

// Remove text alignment so we can apply to the parent container.
delete style.textAlign;
containerBlockProps.style = { textAlign: alignment };

// Remove core background & text color classes, so we can add our own.
const newClassName = className.replace(/has-[\w-]*-color|has-background/g, '').trim();
containerBlockProps.className = newClassName;

// Add the width and height to enforce dimensions and to keep parity with the frontend.
style.width = `${dimensionWidth}px`;
style.height = `${dimensionHeight}px`;

const ALLOWED_MEDIA_TYPES = [ 'image/svg+xml' ];

Expand Down Expand Up @@ -122,7 +143,7 @@ const SafeSvgBlockEdit = ( props ) => {
];

return (
<div { ...blockProps } style={{overflow: 'hidden'}}>
<>
{svgURL &&
<><InspectorControls>
<PanelBody
Expand Down Expand Up @@ -155,47 +176,34 @@ const SafeSvgBlockEdit = ( props ) => {
onError={onError} />
</BlockControls></>
}
<MediaUpload
onSelect={onSelectImage}
allowedTypes={ALLOWED_MEDIA_TYPES}
accept={ALLOWED_MEDIA_TYPES}
value={imageID}
render={({open}) => {
return (
<div
style={{
maxWidth: '100%',
textAlign: alignment
}}
>
{!svgURL &&
<Button variant="tertiary" onClick={open}>
{__('Select an SVG icon', 'safe-svg')}
</Button>
}
{svgURL &&
<svg
style={{
width: dimensionWidth,
height: dimensionHeight,
maxWidth: '100%',
maxHeight: '100%'
}}
>
<image
xlinkHref={svgURL}
src={svgURL}
width={dimensionWidth < dimensionHeight ? dimensionWidth : '100%'}
style={{
height: dimensionWidth > dimensionHeight ? dimensionHeight : 'auto'
}}
/>
</svg>
}
</div>
);
}}
/>


{!svgURL &&
<MediaPlaceholder
onSelect={onSelectImage}
allowedTypes = {ALLOWED_MEDIA_TYPES}
accept={ALLOWED_MEDIA_TYPES}
value={imageID}
labels={{
title: __( 'Inline SVG', 'safe-svg' ),
instructions: __( 'Upload an SVG or pick one from your media library.', 'safe-svg' )
}}
/>
}

{svgURL &&
<div { ...containerBlockProps }>
<div
style={style}
className="safe-svg-inside"
>
<ReactSVG src={svgURL} beforeInjection={(svg) => {
svg.setAttribute( 'style', `width: ${dimensionWidth}px; height: ${dimensionHeight}px;` );
}} />
</div>
</div>
}

{ contentPostType && (
<Placeholder
label={ __( 'SafeSvg', 'safe-svg' ) }
Expand All @@ -208,7 +216,7 @@ const SafeSvgBlockEdit = ( props ) => {
</p>
</Placeholder>
) }
</div>
</>
);
};
// Set the propTypes
Expand Down
11 changes: 7 additions & 4 deletions includes/blocks/safe-svg/frontend.scss
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
.safe-svg-cover {
text-align: center;

.safe-svg-inside {
max-width: 100%;
display: inline-block;
max-width: 100%;
}

svg {
max-width: 100%;
height: 100%;
max-height: 100%;
max-width: 100%;
width: 100%;
height: 100%;
}
}
}
8 changes: 5 additions & 3 deletions includes/blocks/safe-svg/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,20 @@ import save from './save';
import block from './block.json';

/* Uncomment for CSS overrides in the admin */
// import './index.css';
import './frontend.scss';

/**
* Register block
*/
registerBlockType( block.name, {
title: __( 'Safe SVG Icon', 'safe-svg' ),
title: __( 'Inline SVG', 'safe-svg' ),
description: __(
'Display an SVG icon',
'safe-svg'
),
edit,
save,
icon: 'format-image'
icon: {
src: <svg xmlns='http://www.w3.org/2000/svg' width='800' height='800' viewBox='0 0 512 512'><path fill='currentColor' fill-rule='evenodd' d='M321.838 42.667H87.171v234.666h42.667v-192h174.293l81.707 81.707v110.293h42.667v-128L321.838 42.667ZM85.333 441.734l4.17-24.65c14.68 6.163 27.126 9.244 37.337 9.244 6.645 0 11.54-1.631 14.68-4.894 2.72-2.84 4.079-6.313 4.079-10.422 0-3.685-1.33-6.555-3.988-8.61-2.658-2.053-9.213-5.225-19.665-9.515-7.734-3.202-13.186-5.588-16.358-7.16-3.172-1.57-6.087-3.352-8.745-5.346-7.552-5.619-11.328-13.715-11.328-24.287 0-9.123 2.477-17.129 7.43-24.016 7.613-10.694 20.12-16.04 37.52-16.04 12.566 0 26.22 2.325 40.962 6.977l-5.8 23.563c-8.7-3.202-15.24-5.317-19.62-6.344-4.38-1.027-8.957-1.54-13.73-1.54-5.437 0-9.576 1.208-12.416 3.625-2.96 2.597-4.44 5.89-4.44 9.878 0 3.443 1.253 6.147 3.76 8.11 2.508 1.964 8.535 4.91 18.08 8.837 9.486 3.927 15.77 6.66 18.85 8.201a55.772 55.772 0 0 1 8.7 5.392c7.432 5.68 11.147 14.35 11.147 26.01 0 13.775-4.682 24.197-14.047 31.265-7.975 5.982-19.152 8.972-33.53 8.972-14.984 0-29.333-2.417-43.048-7.25Zm146.722 4.985L183.39 318.303h30.087l21.388 57.637c5.437 14.682 9.515 26.765 12.234 36.25 4.169-13.291 8.126-24.982 11.872-35.071l22.022-58.816h28.637l-48.665 128.416h-28.91ZM429.8 374.853v65.522c-7.37 2.477-12.567 4.108-15.588 4.894-9.364 2.477-19.424 3.715-30.178 3.715-21.146 0-37.247-5.317-48.303-15.95-12.264-11.72-18.397-28.063-18.397-49.028 0-24.106 7.613-42.292 22.838-54.556 11.056-8.942 25.979-13.413 44.769-13.413 16.07 0 31.024 2.93 44.859 8.79l-9.878 22.567c-6.525-3.263-12.235-5.544-17.128-6.843-4.894-1.299-10.271-1.948-16.132-1.948-14.016 0-24.347 4.561-30.993 13.684-5.619 7.734-8.428 17.914-8.428 30.54 0 15.165 4.229 26.584 12.687 34.257 6.767 6.163 15.165 9.244 25.194 9.244 5.86 0 11.419-.997 16.675-2.99v-25.829h-22.113v-22.656H429.8Z'></path></svg>
}
} );
34 changes: 30 additions & 4 deletions includes/blocks/safe-svg/register.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ function register() {
* @return string|\WP_Post[] The rendered block markup.
*/
function render_block_callback( $attributes ) {
// If image is not an SVG return empty string
// If image is not an SVG return empty string.
if ( 'image/svg+xml' !== get_post_mime_type( $attributes['imageID'] ) ) {
return '';
}

// If we couldn't get the contents of the file, empty string again
// If we couldn't get the contents of the file, empty string again.
if ( ! $contents = file_get_contents( get_attached_file( $attributes['imageID'] ) ) ) { // phpcs:ignore
return '';
}
Expand Down Expand Up @@ -67,18 +67,44 @@ function render_block_callback( $attributes ) {
return apply_filters(
'safe_svg_inline_markup',
sprintf(
'<div class="safe-svg-cover" style="text-align:%s">
<div class="safe-svg-inside %s%s" style="width: %spx; height: %spx;">%s</div>
'<div class="safe-svg-cover" style="text-align: %s;">
<div class="safe-svg-inside %s%s" style="width: %spx; height: %spx; background-color: var(--wp--preset--color--%s); color: var(--wp--preset--color--%s); padding-top: %s; padding-right: %s; padding-bottom: %s; padding-left: %s; margin-top: %s; margin-right: %s; margin-bottom: %s; margin-left: %s;">%s</div>
</div>',
isset( $attributes['alignment'] ) ? esc_attr( $attributes['alignment'] ) : 'left',
esc_attr( $class_name ),
isset( $attributes['className'] ) ? ' ' . esc_attr( $attributes['className'] ) : '',
isset( $attributes['dimensionWidth'] ) ? esc_attr( $attributes['dimensionWidth'] ) : '',
isset( $attributes['dimensionHeight'] ) ? esc_attr( $attributes['dimensionHeight'] ) : '',
isset( $attributes['backgroundColor'] ) ? esc_attr( $attributes['backgroundColor'] ) : '',
isset( $attributes['textColor'] ) ? esc_attr( $attributes['textColor'] ) : '',
isset( $attributes['style']['spacing']['padding']['top'] ) ? esc_attr( convert_to_css_variable( $attributes['style']['spacing']['padding']['top'] ) ) : '',
isset( $attributes['style']['spacing']['padding']['right'] ) ? esc_attr( convert_to_css_variable( $attributes['style']['spacing']['padding']['right'] ) ) : '',
isset( $attributes['style']['spacing']['padding']['bottom'] ) ? esc_attr( convert_to_css_variable( $attributes['style']['spacing']['padding']['bottom'] ) ) : '',
isset( $attributes['style']['spacing']['padding']['left'] ) ? esc_attr( convert_to_css_variable( $attributes['style']['spacing']['padding']['left'] ) ) : '',
isset( $attributes['style']['spacing']['margin']['top'] ) ? esc_attr( convert_to_css_variable( $attributes['style']['spacing']['margin']['top'] ) ) : '',
isset( $attributes['style']['spacing']['margin']['right'] ) ? esc_attr( convert_to_css_variable( $attributes['style']['spacing']['margin']['right'] ) ) : '',
isset( $attributes['style']['spacing']['margin']['bottom'] ) ? esc_attr( convert_to_css_variable( $attributes['style']['spacing']['margin']['bottom'] ) ) : '',
isset( $attributes['style']['spacing']['margin']['left'] ) ? esc_attr( convert_to_css_variable( $attributes['style']['spacing']['margin']['left'] ) ) : '',
$contents
),
$contents,
$class_name,
$attributes['imageID']
);
}

/**
* Converts a given value to a CSS variable if it starts with 'var:'.
*
* @param string $value The value to be converted.
* @return string The converted value or the original value if it doesn't start with 'var:'.
*/
function convert_to_css_variable( $value ) {
if ( strpos( $value, 'var:' ) === 0 ) {
$parts = explode( '|', $value );
if ( count( $parts ) === 3 ) {
return 'var(--wp--preset--' . $parts[1] . '--' . $parts[2] . ')';
}
}
return $value;
}
Loading

0 comments on commit 0962c11

Please sign in to comment.