Skip to content

Commit

Permalink
Add FontSizePicker component and refactor paragraph block to use it.
Browse files Browse the repository at this point in the history
This change makes font size UI generic and allows other blocks to take advantage of the same UI used in the paragraph.
Other changes will follow that will abstract other font size logic from paragraph (not just the UI).
Themes will also be able to configure the font sizes. The future changes will use this work.
  • Loading branch information
jorgefilipecosta committed May 9, 2018
1 parent 4dc4c7b commit 57a5512
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 54 deletions.
61 changes: 61 additions & 0 deletions components/font-size-picker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
FontSizePicker
========

FontSizePicker is a React component that renders a UI that allows users to select a font size.
The component renders a series of buttons that allow the user to select predefined (common) font sizes and contains a range slider that enables the user to select custom font sizes (by choosing the value.

## Usage


```jsx
import { Dropdown } from '@wordpress/components';

function MyFontSizePicker() {
return (
<FontSizePicker
fontSizes={ [
{ shortName: 'S', size: 12 }
{ shortName: 'M', size: 16 }
] }
fallbackFontSize={ fallbackFontSize }
value={ fontSize }
onChange={ this.setFontSize }
/>
);
}
```

## Props

The component accepts the following props:

### fontSizes

An array of font size objects. The object should contain properties size, name, shortName.
The property "size" contains a number with the font size value. The "shortName" property includes a small label used in the buttons. Property "name" is used as the label when shortName is not provided.

- Type: `Array`
- Required: No

### fallbackFontSize

In no value exists this prop contains the font size picker slider starting position.

- Type: `Number`
- Required: No

### value

The current font size value. If a button value matches the font size value that button is pressed. RangeControl is rendered with this value.

- Type: `Number`
- Required: No

## onChange

A function that receives the new font size value.
If onChange is called without any parameter, it should reset the value, attending to what reset means in that context, e.g., set the font size to undefined or set the font size a starting value.

- Type: `function`
- Required: Yes

57 changes: 57 additions & 0 deletions components/font-size-picker/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* External dependencies
*/
import { map } from 'lodash';

/**
* WordPress dependencies
*/
import { Fragment } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import './style.scss';
import Button from '../button';
import ButtonGroup from '../button-group';
import RangeControl from '../range-control';

export default function FontSizePicker( { fontSizes = [], fallbackFontSize, value, onChange } ) {
return (
<Fragment>
<div className="components-font-size-picker__buttons">
<ButtonGroup aria-label={ __( 'Font Size' ) }>
{ map( fontSizes, ( { name, size, shortName } ) => (
<Button
key={ size }
isLarge
isPrimary={ value === size }
aria-pressed={ value === size }
onClick={ () => onChange( size ) }
>
{ shortName || name }
</Button>
) ) }
</ButtonGroup>
<Button
isLarge
onClick={ () => onChange( undefined ) }
>
{ __( 'Reset' ) }
</Button>
</div>
<RangeControl
className="components-font-size-picker__custom-input"
label={ __( 'Custom Size' ) }
value={ value || '' }
initialPosition={ fallbackFontSize }
onChange={ onChange }
min={ 12 }
max={ 100 }
beforeIcon="editor-textcolor"
afterIcon="editor-textcolor"
/>
</Fragment>
);
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
.blocks-font-size__main {
.components-font-size-picker__buttons {
display: flex;
justify-content: space-between;
margin-bottom: 1em;
}

.blocks-paragraph__custom-size-slider {
.components-font-size-picker__custom-input {
.components-range-control__slider + .dashicon {
width: 30px;
height: 30px;
Expand Down
1 change: 1 addition & 0 deletions components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export { default as Dropdown } from './dropdown';
export { default as DropdownMenu } from './dropdown-menu';
export { default as ExternalLink } from './external-link';
export { default as FocusableIframe } from './focusable-iframe';
export { default as FontSizePicker } from './font-size-picker';
export { default as FormFileUpload } from './form-file-upload';
export { default as FormToggle } from './form-toggle';
export { default as FormTokenField } from './form-token-field';
Expand Down
89 changes: 37 additions & 52 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 { findKey, isFinite, map, omit } from 'lodash';
import { isFinite, find, omit } from 'lodash';

/**
* WordPress dependencies
Expand All @@ -16,11 +16,9 @@ import {
RawHTML,
} from '@wordpress/element';
import {
FontSizePicker,
PanelBody,
RangeControl,
ToggleControl,
Button,
ButtonGroup,
withFallbackStyles,
} from '@wordpress/components';
import {
Expand All @@ -38,7 +36,6 @@ import { createBlock, getPhrasingContentSchema } from '@wordpress/blocks';
/**
* Internal dependencies
*/
import './editor.scss';
import './style.scss';

const { getComputedStyle } = window;
Expand All @@ -55,12 +52,28 @@ const FallbackStyles = withFallbackStyles( ( node, ownProps ) => {
};
} );

const FONT_SIZES = {
small: 14,
regular: 16,
large: 36,
larger: 48,
};
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() {
Expand Down Expand Up @@ -97,7 +110,10 @@ class ParagraphBlock extends Component {
getFontSize() {
const { customFontSize, fontSize } = this.props.attributes;
if ( fontSize ) {
return FONT_SIZES[ fontSize ];
const fontSizeObj = find( FONT_SIZES, { name: fontSize } );
if ( fontSizeObj ) {
return fontSizeObj.size;
}
}

if ( customFontSize ) {
Expand All @@ -107,10 +123,10 @@ class ParagraphBlock extends Component {

setFontSize( fontSizeValue ) {
const { setAttributes } = this.props;
const thresholdFontSize = findKey( FONT_SIZES, ( size ) => size === fontSizeValue );
const thresholdFontSize = find( FONT_SIZES, { size: fontSizeValue } );
if ( thresholdFontSize ) {
setAttributes( {
fontSize: thresholdFontSize,
fontSize: thresholdFontSize.name,
customFontSize: undefined,
} );
return;
Expand Down Expand Up @@ -159,42 +175,11 @@ class ParagraphBlock extends Component {
</BlockControls>
<InspectorControls>
<PanelBody title={ __( 'Text Settings' ) } className="blocks-font-size">
<div className="blocks-font-size__main">
<ButtonGroup aria-label={ __( 'Font Size' ) }>
{ map( {
S: 'small',
M: 'regular',
L: 'large',
XL: 'larger',
}, ( size, label ) => (
<Button
key={ label }
isLarge
isPrimary={ fontSize === FONT_SIZES[ size ] }
aria-pressed={ fontSize === FONT_SIZES[ size ] }
onClick={ () => this.setFontSize( FONT_SIZES[ size ] ) }
>
{ label }
</Button>
) ) }
</ButtonGroup>
<Button
isLarge
onClick={ () => this.setFontSize( undefined ) }
>
{ __( 'Reset' ) }
</Button>
</div>
<RangeControl
className="blocks-paragraph__custom-size-slider"
label={ __( 'Custom Size' ) }
value={ fontSize || '' }
initialPosition={ fallbackFontSize }
onChange={ ( value ) => this.setFontSize( value ) }
min={ 12 }
max={ 100 }
beforeIcon="editor-textcolor"
afterIcon="editor-textcolor"
<FontSizePicker
fontSizes={ FONT_SIZES }
fallbackFontSize={ fallbackFontSize }
value={ fontSize }
onChange={ this.setFontSize }
/>
<ToggleControl
label={ __( 'Drop Cap' ) }
Expand Down Expand Up @@ -366,7 +351,7 @@ export const settings = {

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

const className = classnames( {
[ `align${ width }` ]: width,
Expand Down Expand Up @@ -490,7 +475,7 @@ export const settings = {

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

const className = classnames( {
'has-background': backgroundColor || customBackgroundColor,
Expand Down

0 comments on commit 57a5512

Please sign in to comment.