Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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: 5px;
}

.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',
},
});
83 changes: 83 additions & 0 deletions src/font-size/inline-ui.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* 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
>
<div style={ { padding: '16px', minWidth: '220px' } }>
<FontSizePicker
value={ fontSizeValue }
onChange={ onFontSizeChange }
fontSizes={ fontSizes }
__next40pxDefaultSize
/>
<Button
className="reset-button"
disabled={ ! fontSizeValue }
onClick={ handleClear }
variant="tertiary"
>
{ __( 'Clear', 'blablablocks-formats' ) }
</Button>
</div>
</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';