From f4cc3bfb4fd751dbd7e711868088ef33f710ff11 Mon Sep 17 00:00:00 2001
From: Matias Ventura
Date: Tue, 20 Mar 2018 16:12:03 +0100
Subject: [PATCH] Predefined set of font sizes (#5269)
* Add ButtonGroup UI component.
This component renders a row of button controls.
* Add predefined sets of font size values paired with classes.
When font size control is used and the value matches one of the
predefined values, the editor would output a special class instead
of an inline fontSize number.
* Load default font-sizes in the front.
* Use button-group for font-size buttons.
* Use a more sensible max value for the slider.
* Group reset button with predefined sizes.
* Add aria-pressed attr and display afterIcon in range slider.
* Refactored to the two attributes approach customFontSize and fontSize.
* Implemented deprecation logic to convert existing paragraph blocks.
---
blocks/library/paragraph/editor.scss | 10 ++
blocks/library/paragraph/index.js | 141 ++++++++++++++++++++++++---
blocks/library/paragraph/style.scss | 38 ++++++--
components/button-group/index.js | 19 ++++
components/button-group/style.scss | 19 ++++
components/index.js | 1 +
6 files changed, 205 insertions(+), 23 deletions(-)
create mode 100644 components/button-group/index.js
create mode 100644 components/button-group/style.scss
diff --git a/blocks/library/paragraph/editor.scss b/blocks/library/paragraph/editor.scss
index a50c04177658f..e5fe10296b7f1 100644
--- a/blocks/library/paragraph/editor.scss
+++ b/blocks/library/paragraph/editor.scss
@@ -1,3 +1,13 @@
.editor-block-list__block:not( .is-multi-selected ) .wp-block-paragraph {
background: white;
}
+
+.blocks-font-size__main {
+ display: flex;
+ justify-content: space-between;
+}
+
+.blocks-font-size .blocks-range-control__slider + .dashicon {
+ width: 30px;
+ height: 30px;
+}
diff --git a/blocks/library/paragraph/index.js b/blocks/library/paragraph/index.js
index 93ab1c019c68b..d7cefb196a329 100644
--- a/blocks/library/paragraph/index.js
+++ b/blocks/library/paragraph/index.js
@@ -2,6 +2,7 @@
* External dependencies
*/
import classnames from 'classnames';
+import { findKey, isFinite, map, omit } from 'lodash';
/**
* WordPress dependencies
@@ -14,6 +15,8 @@ import {
PanelColor,
RangeControl,
ToggleControl,
+ Button,
+ ButtonGroup,
withFallbackStyles,
} from '@wordpress/components';
@@ -46,6 +49,13 @@ const ContrastCheckerWithFallbackStyles = withFallbackStyles( ( node, ownProps )
};
} )( ContrastChecker );
+const FONT_SIZES = {
+ small: 14,
+ regular: 16,
+ large: 36,
+ larger: 48,
+};
+
class ParagraphBlock extends Component {
constructor() {
super( ...arguments );
@@ -53,6 +63,8 @@ class ParagraphBlock extends Component {
this.bindRef = this.bindRef.bind( this );
this.onReplace = this.onReplace.bind( this );
this.toggleDropCap = this.toggleDropCap.bind( this );
+ this.getFontSize = this.getFontSize.bind( this );
+ this.setFontSize = this.setFontSize.bind( this );
}
onReplace( blocks ) {
@@ -81,6 +93,33 @@ class ParagraphBlock extends Component {
this.nodeRef = node;
}
+ getFontSize() {
+ const { customFontSize, fontSize } = this.props.attributes;
+ if ( fontSize ) {
+ return FONT_SIZES[ fontSize ];
+ }
+
+ if ( customFontSize ) {
+ return customFontSize;
+ }
+ }
+
+ setFontSize( fontSizeValue ) {
+ const { setAttributes } = this.props;
+ const thresholdFontSize = findKey( FONT_SIZES, ( size ) => size === fontSizeValue );
+ if ( thresholdFontSize ) {
+ setAttributes( {
+ fontSize: thresholdFontSize,
+ customFontSize: undefined,
+ } );
+ return;
+ }
+ setAttributes( {
+ fontSize: undefined,
+ customFontSize: fontSizeValue,
+ } );
+ }
+
render() {
const {
attributes,
@@ -97,12 +136,13 @@ class ParagraphBlock extends Component {
content,
dropCap,
placeholder,
- fontSize,
backgroundColor,
textColor,
width,
} = attributes;
+ const fontSize = this.getFontSize();
+
return [
isSelected && (
@@ -116,21 +156,47 @@ class ParagraphBlock extends Component {
),
isSelected && (
-
+
+
+
+ { map( {
+ S: 'small',
+ M: 'regular',
+ L: 'large',
+ XL: 'larger',
+ }, ( size, label ) => (
+
+ ) ) }
+
+
+
+ this.setFontSize( value ) }
+ min={ 12 }
+ max={ 100 }
+ beforeIcon="editor-textcolor"
+ afterIcon="editor-textcolor"
+ />
- setAttributes( { fontSize: value } ) }
- min={ 10 }
- max={ 200 }
- beforeIcon="editor-textcolor"
- allowReset
- />
{ content }
;
+ },
+ migrate( attributes ) {
+ if ( isFinite( attributes.fontSize ) ) {
+ return omit( {
+ ...attributes,
+ customFontSize: attributes.fontSize,
+ }, 'fontSize' );
+ }
+ return attributes;
+ },
+ },
{
supports,
attributes: {
@@ -314,16 +417,28 @@ export const settings = {
edit: ParagraphBlock,
save( { attributes } ) {
- const { width, align, content, dropCap, backgroundColor, textColor, fontSize } = attributes;
+ const {
+ width,
+ align,
+ content,
+ dropCap,
+ backgroundColor,
+ textColor,
+ fontSize,
+ customFontSize,
+ } = attributes;
+
const className = classnames( {
[ `align${ width }` ]: width,
'has-background': backgroundColor,
'has-drop-cap': dropCap,
+ [ `is-${ fontSize }-text` ]: fontSize && FONT_SIZES[ fontSize ],
} );
+
const styles = {
backgroundColor: backgroundColor,
color: textColor,
- fontSize: fontSize,
+ fontSize: ! fontSize && customFontSize ? customFontSize : undefined,
textAlign: align,
};
diff --git a/blocks/library/paragraph/style.scss b/blocks/library/paragraph/style.scss
index ba590421b23b9..7d8da4883876f 100644
--- a/blocks/library/paragraph/style.scss
+++ b/blocks/library/paragraph/style.scss
@@ -1,13 +1,31 @@
-p.has-drop-cap {
- &:first-letter {
- float: left;
- font-size: 4.1em;
- line-height: 0.7;
- font-family: serif;
- font-weight: bold;
- margin: .07em .23em 0 0;
- text-transform: uppercase;
- font-style: normal;
+p {
+ &.is-small-text {
+ font-size: 14px;
+ }
+
+ &.is-regular-text {
+ font-size: 16px;
+ }
+
+ &.is-large-text {
+ font-size: 36px;
+ }
+
+ &.is-larger-text {
+ font-size: 48px;
+ }
+
+ &.has-drop-cap {
+ &:first-letter {
+ float: left;
+ font-size: 4.1em;
+ line-height: 0.7;
+ font-family: serif;
+ font-weight: bold;
+ margin: .07em .23em 0 0;
+ text-transform: uppercase;
+ font-style: normal;
+ }
}
}
diff --git a/components/button-group/index.js b/components/button-group/index.js
new file mode 100644
index 0000000000000..df65e99cb8068
--- /dev/null
+++ b/components/button-group/index.js
@@ -0,0 +1,19 @@
+/**
+ * External dependencies
+ */
+import classnames from 'classnames';
+
+/**
+ * Internal dependencies
+ */
+import './style.scss';
+
+function ButtonGroup( { className, ...props } ) {
+ const classes = classnames( 'components-button-group', className );
+
+ return (
+
+ );
+}
+
+export default ButtonGroup;
diff --git a/components/button-group/style.scss b/components/button-group/style.scss
new file mode 100644
index 0000000000000..5be7e700ac197
--- /dev/null
+++ b/components/button-group/style.scss
@@ -0,0 +1,19 @@
+.components-button-group {
+ display: inline-block;
+ margin-bottom: 20px;
+
+ .components-button {
+ border-radius: 0;
+ & + .components-button {
+ margin-left: -1px;
+ }
+
+ &:first-child {
+ border-radius: 3px 0 0 3px;
+ }
+
+ &:last-child {
+ border-radius: 0 3px 3px 0;
+ }
+ }
+}
diff --git a/components/index.js b/components/index.js
index 512e2b8babb18..f720220639972 100644
--- a/components/index.js
+++ b/components/index.js
@@ -3,6 +3,7 @@ export { default as APIProvider } from './higher-order/with-api-data/provider';
export { default as Autocomplete } from './autocomplete';
export { default as BaseControl } from './base-control';
export { default as Button } from './button';
+export { default as ButtonGroup } from './button-group';
export { default as CheckboxControl } from './checkbox-control';
export { default as ClipboardButton } from './clipboard-button';
export { default as CodeEditor } from './code-editor';