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
  • Loading branch information
jorgefilipecosta committed Jul 23, 2018
1 parent 09db904 commit d0a4747
Show file tree
Hide file tree
Showing 11 changed files with 302 additions and 65 deletions.
78 changes: 13 additions & 65 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,
PanelColor,
RichText,
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 @@ -251,10 +197,10 @@ class ParagraphBlock extends Component {
textColor={ textColor.value }
backgroundColor={ backgroundColor.value }
{ ...{
fontSize,
fallbackBackgroundColor,
fallbackTextColor,
} }
fontSize={ fontSize.size }
/>
</InspectorControls>
<RichText
Expand All @@ -264,11 +210,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 @@ -489,6 +436,7 @@ export const settings = {

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

Expand All @@ -507,7 +455,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 @@ -55,6 +55,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
14 changes: 14 additions & 0 deletions editor/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 editor/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 editor/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 d0a4747

Please sign in to comment.