Skip to content
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
4 changes: 4 additions & 0 deletions _playground/blueprint-local.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"landingPage": "/wp-admin/post.php?post=4&action=edit",
"preferredVersions": {
"php": "8.2",
"wp": "6.7"
},
"login": true,
"features": {
"networking": true
Expand Down
12 changes: 8 additions & 4 deletions blablablocks-formats.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,12 @@ function blablablocks_formats_enqueue_assets()
wp_enqueue_style('blablablocks-formats-styles');
}

$needs_marker = blablablocks_has_format('has-marker-format');
$needs_infotip = blablablocks_has_format('has-infotip-format');
$needs_marker = blablablocks_has_format('has-marker-format');
$needs_infotip = blablablocks_has_format('has-infotip-format');
$needs_fontsize = blablablocks_has_format('has-font-size-format');

// If neither format is present, do nothing.
if (! $needs_marker && ! $needs_infotip) {
// If no format is present, do nothing.
if (! $needs_marker && ! $needs_infotip && ! $needs_fontsize) {
return;
}

Expand All @@ -156,5 +157,8 @@ function blablablocks_formats_enqueue_assets()
if ($needs_infotip) {
wp_enqueue_script('blablablocks-infotip-format-asset');
}

// Font-size format doesn't need additional scripts on frontend
// The inline styles handle the rendering
}
add_action('enqueue_block_assets', 'blablablocks_formats_enqueue_assets');
55 changes: 55 additions & 0 deletions src/font-size/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
import { RichTextToolbarButton } from '@wordpress/block-editor';
import { textHorizontal } from '@wordpress/icons';

/**
* Internal dependencies
*/
import InlineUI from './inline-ui';

/**
* Edit component for the FontSize format in the block editor.
*
* @param {Object} props - The component properties.
* @param {Object} props.value - The current value of the rich text.
* @param {Function} props.onChange - Function to update the rich text value.
* @param {boolean} props.isActive - Indicates if the format is currently active.
* @param {Object} props.contentRef - Reference to the editable content element.
* @param {Object} props.activeAttributes - The currently active attributes.
* @return {JSX.Element} - The rendered FontSize format.
*/
export function Edit({
value,
onChange,
isActive,
contentRef,
activeAttributes,
}) {
const [isSettingOpen, setIsSettingOpen] = useState(false);

return (
<>
<RichTextToolbarButton
icon={textHorizontal}
title={__('Font Size', 'blablablocks-formats')}
onClick={() => setIsSettingOpen(true)}
isActive={isActive}
/>

{isSettingOpen && (
<InlineUI
value={value}
onChange={onChange}
onClose={() => setIsSettingOpen(false)}
activeAttributes={activeAttributes}
contentRef={contentRef.current}
isActive={isActive}
/>
)}
</>
);
}
16 changes: 16 additions & 0 deletions src/font-size/editor.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Editor styles for the font-size format.
*/

.block-editor-format-toolbar__blablablocks-font-size-popover {
.components-popover__content {
min-width: 20.625rem;
padding: 16px;
}

.reset-button {
margin-top: 1rem;
display: block;
margin-left: auto;
}
}
103 changes: 103 additions & 0 deletions src/font-size/hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/**
* WordPress dependencies
*/
import { useSelect } from '@wordpress/data';
import { removeFormat } from '@wordpress/rich-text';

/**
* Internal dependencies
*/
import { createFormatHelpers } from '../utils';

/**
* Custom hook for handling font size formatting.
*
* @param {Object} props - The hook properties.
* @param {string} props.value - The current rich text value.
* @param {Function} props.onChange - Callback to update the format.
* @param {Object} props.activeAttributes - The currently active format attributes.
* @return {Object} The font size state and handlers.
*/
export const useFontSize = ( { value, onChange, activeAttributes } ) => {
const { replace } = createFormatHelpers( {
value,
onChange,
formatType: 'blablablocks/font-size',
activeAttributes,
} );

const fontSizes = useSelect(
( select ) => select( 'core/block-editor' ).getSettings().fontSizes,
[]
);

/**
* Extract current font size from class or style attribute.
*
* @return {string|null} Current font size.
*/
const getCurrentFontSize = () => {
const { class: classAttr, style: styleAttr } = activeAttributes;

if ( classAttr ) {
const match = classAttr.match( /has-([a-z0-9-]+)-font-size/ );
if ( match ) {
const slug = match[ 1 ];
const fontSizeObj = fontSizes?.find(
( size ) => size.slug === slug
);
return fontSizeObj ? fontSizeObj.size : null;
}
}

if ( styleAttr ) {
const match = styleAttr.match( /font-size:\s*([^;]+)/ );
if ( match ) {
return match[ 1 ].trim();
}
}

return null;
};

/**
* Handle font size changes.
*
* @param {string} newFontSize The new font size value.
*/
const onFontSizeChange = ( newFontSize ) => {
if ( ! newFontSize ) {
onChange( removeFormat( value, 'blablablocks/font-size' ) );
return;
}

const fontSizeObj = fontSizes?.find(
( size ) =>
size.size === newFontSize || size.slug === newFontSize
);

if ( fontSizeObj && fontSizeObj.slug ) {
replace( {
class: `has-${ fontSizeObj.slug }-font-size`,
} );
} else {
replace( {
style: `font-size: ${ newFontSize }`,
} );
}
};

/**
* Clear the font size format.
*/
const onClear = () => {
onChange( removeFormat( value, 'blablablocks/font-size' ) );
};

return {
fontSizes,
fontSizeValue: getCurrentFontSize(),
onFontSizeChange,
onClear,
};
};
26 changes: 26 additions & 0 deletions src/font-size/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { registerFormatType } from '@wordpress/rich-text';

/**
* Internal dependencies
*/
import './editor.scss';
import './style.scss';
import { Edit } from './edit';

/**
* Registers the FontSize format type.
*/
registerFormatType('blablablocks/font-size', {
title: __('Font Size', 'blablablocks-formats'),
tagName: 'span',
className: 'has-font-size-format',
edit: Edit,
attributes: {
class: 'class',
style: 'style',
},
});
78 changes: 78 additions & 0 deletions src/font-size/inline-ui.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { useAnchor } from '@wordpress/rich-text';
import { Popover, Button, FontSizePicker } from '@wordpress/components';

/**
* Internal dependencies
*/
import { useFontSize } from './hooks';

/**
* InlineUI component for handling FontSize text formatting options.
*
* @param {Object} props - The component properties.
* @param {string} props.value - The current rich text value.
* @param {Function} props.onChange - Callback to update the format.
* @param {Function} props.onClose - Callback to close the UI.
* @param {Object} props.activeAttributes - The currently active format attributes.
* @param {Object} props.contentRef - Reference to the content element.
* @param {boolean} props.isActive - Indicates if the format is active.
* @return {JSX.Element} - The rendered component.
*/
function InlineUI( {
value,
onChange,
onClose,
activeAttributes,
contentRef,
isActive,
} ) {
const anchor = useAnchor( {
editableContentElement: contentRef,
settings: { isActive },
} );

const { fontSizes, fontSizeValue, onFontSizeChange, onClear } = useFontSize(
{
value,
onChange,
activeAttributes,
}
);

const handleClear = () => {
onClear();
onClose();
};

return (
<Popover
anchor={ anchor }
className="block-editor-format-toolbar__blablablocks-font-size-popover"
offset={ 20 }
onClose={ onClose }
placement="bottom"
shift
>
<FontSizePicker
value={ fontSizeValue }
onChange={ onFontSizeChange }
fontSizes={ fontSizes }
__next40pxDefaultSize
/>
<Button
className="reset-button"
disabled={ ! fontSizeValue }
onClick={ handleClear }
variant="tertiary"
>
{ __( 'Clear', 'blablablocks-formats' ) }
</Button>
</Popover>
);
}

export default InlineUI;
8 changes: 8 additions & 0 deletions src/font-size/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* Frontend styles for the font-size format.
*/

.has-font-size-format {
// The inline style attribute will handle the actual font-size
// This class is mainly for identification and potential future styling
}
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
*/
import './marker';
import './infotip';
import './font-size';