Skip to content

Commit

Permalink
feature: Add ability for themes to configure font sizes; Extract font…
Browse files Browse the repository at this point in the history
…Size logic from paragraph (#6628)

Extracts the logic to manage font sizes in a similar way to what we used to abstract the color logic.
Refactors the styles, so they are not specific to paragraphs. Now, other blocks can make use of the same classes.
The class names were renamed from the format is-large-text to has-large-font-size, this makes the names consistent with the names used in color classes. The new name makes clear that the primary style set is the font-size.
Font sizes are now read from editor settings instead of being a constant in the paragraph block.
  • Loading branch information
jorgefilipecosta authored Jul 27, 2018
1 parent 94f5489 commit a975273
Show file tree
Hide file tree
Showing 11 changed files with 312 additions and 66 deletions.
80 changes: 14 additions & 66 deletions core-blocks/paragraph/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* External dependencies
*/
import classnames from 'classnames';
import { isFinite, find, omit } from 'lodash';
import { isFinite, omit } from 'lodash';

/**
* WordPress dependencies
Expand All @@ -14,20 +14,22 @@ import {
RawHTML,
} from '@wordpress/element';
import {
FontSizePicker,
PanelBody,
ToggleControl,
withFallbackStyles,
} from '@wordpress/components';
import {
getColorClass,
getFontSizeClass,
withColors,
AlignmentToolbar,
BlockControls,
ContrastChecker,
FontSizePicker,
InspectorControls,
PanelColorSettings,
RichText,
ContrastChecker,
withFontSizes,
} from '@wordpress/editor';
import {
createBlock,
Expand Down Expand Up @@ -55,37 +57,12 @@ const FallbackStyles = withFallbackStyles( ( node, ownProps ) => {
};
} );

const FONT_SIZES = [
{
name: 'small',
shortName: 'S',
size: 14,
},
{
name: 'regular',
shortName: 'M',
size: 16,
},
{
name: 'large',
shortName: 'L',
size: 36,
},
{
name: 'larger',
shortName: 'XL',
size: 48,
},
];

class ParagraphBlock extends Component {
constructor() {
super( ...arguments );

this.onReplace = this.onReplace.bind( this );
this.toggleDropCap = this.toggleDropCap.bind( this );
this.getFontSize = this.getFontSize.bind( this );
this.setFontSize = this.setFontSize.bind( this );
this.splitBlock = this.splitBlock.bind( this );
}

Expand All @@ -112,36 +89,6 @@ class ParagraphBlock extends Component {
return checked ? __( 'Showing large initial letter.' ) : __( 'Toggle to show a large initial letter.' );
}

getFontSize() {
const { customFontSize, fontSize } = this.props.attributes;
if ( fontSize ) {
const fontSizeObj = find( FONT_SIZES, { name: fontSize } );
if ( fontSizeObj ) {
return fontSizeObj.size;
}
}

if ( customFontSize ) {
return customFontSize;
}
}

setFontSize( fontSizeValue ) {
const { setAttributes } = this.props;
const thresholdFontSize = find( FONT_SIZES, { size: fontSizeValue } );
if ( thresholdFontSize ) {
setAttributes( {
fontSize: thresholdFontSize.name,
customFontSize: undefined,
} );
return;
}
setAttributes( {
fontSize: undefined,
customFontSize: fontSizeValue,
} );
}

/**
* Split handler for RichText value, namely when content is pasted or the
* user presses the Enter key.
Expand Down Expand Up @@ -199,6 +146,8 @@ class ParagraphBlock extends Component {
fallbackBackgroundColor,
fallbackTextColor,
fallbackFontSize,
fontSize,
setFontSize,
} = this.props;

const {
Expand All @@ -208,8 +157,6 @@ class ParagraphBlock extends Component {
placeholder,
} = attributes;

const fontSize = this.getFontSize();

return (
<Fragment>
<BlockControls>
Expand All @@ -223,10 +170,9 @@ class ParagraphBlock extends Component {
<InspectorControls>
<PanelBody title={ __( 'Text Settings' ) } className="blocks-font-size">
<FontSizePicker
fontSizes={ FONT_SIZES }
fallbackFontSize={ fallbackFontSize }
value={ fontSize }
onChange={ this.setFontSize }
value={ fontSize.size }
onChange={ setFontSize }
/>
<ToggleControl
label={ __( 'Drop Cap' ) }
Expand All @@ -253,12 +199,12 @@ class ParagraphBlock extends Component {
>
<ContrastChecker
{ ...{
fontSize,
textColor: textColor.value,
backgroundColor: backgroundColor.value,
fallbackTextColor,
fallbackBackgroundColor,
} }
fontSize={ fontSize.size }
/>
</PanelColorSettings>
</InspectorControls>
Expand All @@ -269,11 +215,12 @@ class ParagraphBlock extends Component {
'has-drop-cap': dropCap,
[ backgroundColor.class ]: backgroundColor.class,
[ textColor.class ]: textColor.class,
[ fontSize.class ]: fontSize.class,
} ) }
style={ {
backgroundColor: backgroundColor.value,
color: textColor.value,
fontSize: fontSize ? fontSize + 'px' : undefined,
fontSize: fontSize.size ? fontSize.size + 'px' : undefined,
textAlign: align,
} }
value={ content }
Expand Down Expand Up @@ -494,6 +441,7 @@ export const settings = {

edit: compose( [
withColors( 'backgroundColor', { textColor: 'color' } ),
withFontSizes( 'fontSize' ),
FallbackStyles,
] )( ParagraphBlock ),

Expand All @@ -512,7 +460,7 @@ export const settings = {

const textClass = getColorClass( 'color', textColor );
const backgroundClass = getColorClass( 'background-color', backgroundColor );
const fontSizeClass = fontSize && `is-${ fontSize }-text`;
const fontSizeClass = getFontSizeClass( fontSize );

const className = classnames( {
'has-background': backgroundColor || customBackgroundColor,
Expand Down
16 changes: 16 additions & 0 deletions core-blocks/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,19 @@
.has-very-dark-gray-color {
color: #313131;
}

.has-small-font-size {
font-size: 14px;
}

.has-regular-font-size {
font-size: 16px;
}

.has-large-font-size {
font-size: 36px;
}

.has-larger-font-size {
font-size: 48px;
}
47 changes: 47 additions & 0 deletions docs/extensibility/theme-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,53 @@ Themes are responsible for creating the classes that apply the colors in differe

The class name is built appending 'has-', followed by the class name *using* kebab case and ending with the context name.

### Block Font Sizes:

Blocks may allow the user to configure the font sizes they use, e.g., the paragraph block. Gutenberg provides a default set of font sizes, but a theme can overwrite it and provide its own:


```php
add_theme_support( 'editor-font-sizes', array(
array(
'name' => __( 'small', 'themeLangDomain' ),
'shortName' => __( 'S', 'themeLangDomain' ),
'size' => 12,
'slug' => 'small'
),
array(
'name' => __( 'regular', 'themeLangDomain' ),
'shortName' => __( 'M', 'themeLangDomain' ),
'size' => 16,
'slug' => 'regular'
),
array(
'name' => __( 'large', 'themeLangDomain' ),
'shortName' => __( 'L', 'themeLangDomain' ),
'size' => 36,
'slug' => 'large'
),
array(
'name' => __( 'larger', 'themeLangDomain' ),
'shortName' => __( 'XL', 'themeLangDomain' ),
'size' => 50,
'slug' => 'larger'
)
) );
```

The font sizes are rendered on the font size picker in the order themes provide them.

Themes are responsible for creating the classes that apply the correct font size styles.
The class name is built appending 'has-', followed by the font size name *using* kebab case and ending with `-font-size`.

As an example for the regular font size, a theme may provide the following class.

```css
.has-regular-font-size {
font-size: 16px;
}
```

### Disabling custom colors in block Color Palettes

By default, the color palette offered to blocks, allows the user to select a custom color different from the editor or theme default colors.
Expand Down
7 changes: 7 additions & 0 deletions edit-post/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ export function initializeEditor( id, postType, postId, settings, overridePost )
const reboot = reinitializeEditor.bind( null, postType, postId, target, settings, overridePost );

// Global deprecations which cannot otherwise be injected into known usage.
deprecated( 'paragraphs block class set is-small-text, ..., is-large-text', {
version: '3.6',
alternative: 'has-small-font-size, ..., has-large-font-size class set',
plugin: 'Gutenberg',
hint: 'If paragraphs using this classes are opened in the editor new classes are automatically applied the post just needs to be saved. This is a global warning, shown regardless of whether the classes are used in the current post.',
} );

deprecated( 'block `id` prop in `edit` function', {
version: '3.4',
alternative: 'block `clientId` prop',
Expand Down
5 changes: 5 additions & 0 deletions lib/client-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -1207,6 +1207,7 @@ function gutenberg_editor_scripts_and_styles( $hook ) {
$gutenberg_theme_support = get_theme_support( 'gutenberg' );
$align_wide = get_theme_support( 'align-wide' );
$color_palette = (array) get_theme_support( 'editor-color-palette' );
$font_sizes = current( (array) get_theme_support( 'editor-font-sizes' ) );

// Backcompat for Color Palette set as multiple parameters.
if ( isset( $color_palette[0] ) && ( is_string( $color_palette[0] ) || isset( $color_palette[0]['color'] ) ) ) {
Expand Down Expand Up @@ -1282,6 +1283,10 @@ function gutenberg_editor_scripts_and_styles( $hook ) {
$editor_settings['colors'] = editor_color_palette_slugs( $color_palette );
}

if ( ! empty( $font_sizes ) ) {
$editor_settings['fontSizes'] = $font_sizes;
}

if ( ! empty( $post_type_object->template ) ) {
$editor_settings['template'] = $post_type_object->template;
$editor_settings['templateLock'] = ! empty( $post_type_object->template_lock ) ? $post_type_object->template_lock : false;
Expand Down
14 changes: 14 additions & 0 deletions packages/editor/src/components/font-sizes/font-size-picker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* WordPress dependencies
*/
import { FontSizePicker } from '@wordpress/components';
import { withSelect } from '@wordpress/data';

export default withSelect(
( select ) => {
const { fontSizes } = select( 'core/editor' ).getEditorSettings();
return {
fontSizes,
};
}
)( FontSizePicker );
3 changes: 3 additions & 0 deletions packages/editor/src/components/font-sizes/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { getFontSize, getFontSizeClass } from './utils';
export { default as FontSizePicker } from './font-size-picker';
export { default as withFontSizes } from './with-font-sizes';
43 changes: 43 additions & 0 deletions packages/editor/src/components/font-sizes/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* External dependencies
*/
import { find, kebabCase } from 'lodash';

/**
* Returns the font size object based on an array of named font sizes and the namedFontSize and customFontSize values.
* If namedFontSize is undefined or not found in fontSizes an object with just the size value based on customFontSize is returned.
*
* @param {Array} fontSizes Array of font size objects containing at least the "name" and "size" values as properties.
* @param {?string} fontSizeAttribute Content of the font size attribute (slug).
* @param {?number} customFontSizeAttribute Contents of the custom font size attribute (value).
*
* @return {?string} If fontSizeAttribute is set and an equal slug is found in fontSizes it returns the font size object for that slug.
* Otherwise, an object with just the size value based on customFontSize is returned.
*/
export const getFontSize = ( fontSizes, fontSizeAttribute, customFontSizeAttribute ) => {
if ( fontSizeAttribute ) {
const fontSizeObject = find( fontSizes, { slug: fontSizeAttribute } );
if ( fontSizeObject ) {
return fontSizeObject;
}
}
return {
size: customFontSizeAttribute,
};
};

/**
* Returns a class based on fontSizeName.
*
* @param {string} fontSizeSlug Slug of the fontSize.
*
* @return {string} String with the class corresponding to the fontSize passed.
* The class is generated by appending 'has-' followed by fontSizeSlug in kebabCase and ending with '-font-size'.
*/
export function getFontSizeClass( fontSizeSlug ) {
if ( ! fontSizeSlug ) {
return;
}

return `has-${ kebabCase( fontSizeSlug ) }-font-size`;
}
Loading

0 comments on commit a975273

Please sign in to comment.