Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved UX with spacing & color options #135

Merged
merged 4 commits into from
Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading