Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upfeature: Add ability for themes to configure font sizes; Extract fontSize logic from paragraph #6628
Conversation
e849f06
to
0b7ad83
3660c0e
to
44fa0c4
44fa0c4
to
d188bd6
d188bd6
to
d50f581
de53519
to
4a4dddb
|
This has merge conflicts which need to be resolved. I'll review what's here in the meantime. |
| @@ -251,7 +197,7 @@ class ParagraphBlock extends Component { | |||
| fallbackBackgroundColor, | |||
| fallbackTextColor, | |||
| } } | |||
| isLargeText={ fontSize >= 18 } | |||
| isLargeText={ fontSize.size >= 18 } | |||
This comment has been minimized.
This comment has been minimized.
aduth
Jul 19, 2018
Member
Should this be built-in to the abstraction if "large" text (for accessibility compliancy) is a standard condition?
This comment has been minimized.
This comment has been minimized.
jorgefilipecosta
Jul 19, 2018
Author
Member
Yes maybe we can add a property of fontSize to contrast checker where we only pass the fontSize and it decides if it is large or not, but as it is not directly related to changes here I will do that in a different PR.
This comment has been minimized.
This comment has been minimized.
aduth
Jul 19, 2018
Member
but as it is not directly related to changes here I will do that in a different PR.
Can you create a (ideally self-assigned) issue tracking this?
This comment has been minimized.
This comment has been minimized.
jorgefilipecosta
Jul 19, 2018
•
Author
Member
For this cases where I feel a PR would be very small, I prefer to create a PR directly instead of writing an issue. The PR is available at #8059.
It ended up being a little bigger than what I was expecting initally because I needed to add additional test cases.
| @@ -261,11 +207,12 @@ class ParagraphBlock extends Component { | |||
| 'has-drop-cap': dropCap, | |||
| [ backgroundColor.class ]: backgroundColor.class, | |||
| [ textColor.class ]: textColor.class, | |||
| [ fontSize.class ]: fontSize.class, | |||
This comment has been minimized.
This comment has been minimized.
aduth
Jul 19, 2018
Member
My initial reaction without looking through to see the implementation: Why do we have both fontSize.class and getFontSizeClass?
This comment has been minimized.
This comment has been minimized.
jorgefilipecosta
Jul 19, 2018
Author
Member
We use fontSize.class on the edit method because there it was already computed by the HOC. On the save function we don't use the HOC so we use the getFontSizeClass.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
jorgefilipecosta
Jul 19, 2018
•
Author
Member
The alternatives are:
- not passing class in the HOC and use getFontSizeClass in the edit method (when editing we know class is going to be required so not passing it already is just adding more work to the developers).
- -try to use the HOC in the save (it seems unnecessary as most of its functionality is not used).- Edited: I think this is not an option because the HOC requires context and setAttributes which we don't have on save.
It seems the current version is better than the alternative we have it is also the same that we are doing in the colors logic so a change in this mechanism will require an update to the existing color mechanism so we keep the consistency.
| @@ -501,7 +449,7 @@ export const settings = { | |||
|
|
|||
| const textClass = getColorClass( 'color', textColor ); | |||
| const backgroundClass = getColorClass( 'background-color', backgroundColor ); | |||
| const fontSizeClass = fontSize && `is-${ fontSize }-text`; | |||
| const fontSizeClass = getFontSizeClass( 'font-size', fontSize ); | |||
This comment has been minimized.
This comment has been minimized.
aduth
Jul 19, 2018
Member
For what reason are we changing the class syntax now?
- Do we need to update
deprecatedreference to the old syntax? - There are still references to
is-small-text, etc. incore-blocks/paragraph/style.scss
This comment has been minimized.
This comment has been minimized.
jorgefilipecosta
Jul 19, 2018
•
Author
Member
I feel using has-large-font-size is more inline with the classes we use for colors, and I would like to change theme.
Block with the old syntax are automatically migrated as classes differences are ignored during validation.
We are keeping the old classes, to not break the existing paragraphs on the front end. I think the solution here is adding a global deprecation notice and keep the classes for two versions and I updated the code to include the notice.
| * Returns a class based on fontSizeName. | ||
| * | ||
| * @param {string} fontSizeContext Context/place where the font size is being used, is used during class generation. | ||
| * Normally the value is "font-size". |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
jorgefilipecosta
Jul 19, 2018
Author
Member
I would like to keep doors open, and maybe in the future we have a different kind of classes that need a different context e.g: relative-font-size. But its a fact that right now we don't use context at all so I will remove it for now in the future we can add it if needed.
| * @return {Function} Higher-order component. | ||
| */ | ||
| export default ( ...args ) => { | ||
| const fontSizeMap = reduce( args, ( fontSizeAccumulator, arg ) => { |
This comment has been minimized.
This comment has been minimized.
|
|
9f3dc30
to
661c5bd
|
Hi @aduth thank you a lot for your review. I think I addressed most points. The remaining is the usage of getFontSizeClass in save vs fontSize.class in edit. The only solution I see is removing the class from fontSize and using getFontSizeClass in edit too. As it takes more effort from the developer I personally prefer the current approach, but the difference is not huge and if you prefer to use getFontSizeClass in both places I will gladly change the code. Hi @chrisvanpatten the code and its documentation already used an array for fontSizes I missed the update on the PR description it is now corrected. |
|
@jorgefilipecosta Awesome, looks great :) Excited for this! |
661c5bd
to
6da7fe0
|
I left a few comments. I have some concerns regarding the current implementation of |
| 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 in -font-size. |
This comment has been minimized.
This comment has been minimized.
| @@ -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( 'class set is-small-text, ..., is-large-text', { | |||
| version: '3.5', | |||
This comment has been minimized.
This comment has been minimized.
| name: __( 'larger' ), | ||
| shortName: __( 'XL' ), | ||
| size: 48, | ||
| slug: 'larger', |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| withSelect( ( select ) => { | ||
| const settings = select( 'core/editor' ).getEditorSettings(); | ||
| return { | ||
| fontSizes: get( settings, [ 'fontSizes' ], DEFAULT_FONT_SIZES ), |
This comment has been minimized.
This comment has been minimized.
gziolo
Jul 23, 2018
Member
We have fontSizes provided in settings. Do we really need this default value?
https://github.com/WordPress/gutenberg/pull/6628/files#diff-6e3d39c654369a46e3c418427b3dbddbR9 - here we don't provide the default value. We should pick one approach.
| } | ||
|
|
||
| static getDerivedStateFromProps( { attributes, fontSizes }, previousState ) { | ||
| return reduce( fontSizeNames, ( newState, fontSizeAttributeName ) => { |
This comment has been minimized.
This comment has been minimized.
gziolo
Jul 23, 2018
Member
This method will be called every time any prop changes which means every time any attribute will change. Is there any way to opimize it to avoid doing all those computations where values change for attributes that have nothing to do with fonts?
This comment has been minimized.
This comment has been minimized.
jorgefilipecosta
Jul 23, 2018
Author
Member
Hi @gziolo, I optimized the performance of this function. And now in the most common case where props unrelated to font size change we just compare the font size props with the previous version. Of course, the code is now a little bit more complex because of this optimization.
a5fd9f5
to
d0a4747
| }; | ||
|
|
||
| if ( ! some( fontSizeAttributeNames, didAttributesChange ) ) { | ||
| return previousState; |
This comment has been minimized.
This comment has been minimized.
gziolo
Jul 24, 2018
Member
It should return null when no changes happened. See: https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#new-lifecycle-getderivedstatefromprops.
This comment has been minimized.
This comment has been minimized.
gziolo
Jul 24, 2018
Member
The new static
getDerivedStateFromPropslifecycle is invoked after a component is instantiated as well as before it is re-rendered. It can return an object to update state, ornullto indicate that the new props do not require any state updates.
This comment has been minimized.
This comment has been minimized.
jorgefilipecosta
Jul 24, 2018
Author
Member
Corrected, I'm still mind programmed to return the same value when changes did not happen.
| if ( ! some( fontSizeAttributeNames, didAttributesChange ) ) { | ||
| return previousState; | ||
| } | ||
|
|
This comment has been minimized.
This comment has been minimized.
gziolo
Jul 24, 2018
•
Member
It seems like you could further simplify this code using filter method;
const changedAttributes = filter( fontSizeAttributeNames, didAttributesChange );
if ( changedAttributes.length === 0 ) {
return null;
}
const newState = reduce( fontSizeAttributeNames, ( newStateAccumulator, customFontSizeAttributeName, fontSizeAttributeName ) => {
// the same logic but without if statement
}, {} );
return {
...previousState,
...newState,
};
This comment has been minimized.
This comment has been minimized.
jorgefilipecosta
Jul 24, 2018
Author
Member
I did some code improvements following the logic you proposed. I was not able to use filter because filters always return an array but I used pickBy (is equivalent for the object case).
I kept the "some" verification, because creating a new object is still a non-trivial operation and doing the check allows us to on the most common case (font attributes did not change) do only comparisons.
6a35a9f
to
28b0e29
|
I tested it locally and everything works great. I ensured that there are no unnecessary rerenders when changing non-font attributes. Awesome job with this one. Feel free to merge as soon as you address my last comment. |
| /** | ||
| * WordPress dependencies | ||
| */ | ||
| import { createHigherOrderComponent, Component, compose } from '@wordpress/element'; |
This comment has been minimized.
This comment has been minimized.
gziolo
Jul 26, 2018
Member
compose and createHigherOrderComponent should be imported from @wordpress/compose - I see deprecation warning on the JS console.
63c2bf6
to
bd46fcd
…Size logic from paragraph
bd46fcd
to
42f25af
jorgefilipecosta commentedMay 7, 2018
•
edited
This PR depends on #6618.
It extracts the logic to manage font sizes in a similar way to what we used to abstract the color logic.
We refactored 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.
Color sizes are now read from editor settings instead of being a constant in the paragraph block.
Themes can now configure the font sizes show in the editor.
Fixes: #5714
How has this been tested?
Verify changing font sizes in the paragraph still works as before, no noticeable changes are expected.
Verify we are back compatible with blocks using the old class names by pasting the following text in the code view:
Add the follwing code to a theme functions.php and verify that the size picker correctly reflects it:
add_theme_support( 'editor-font-sizes', array( array( 'name' => __( 'extra small', 'themeLangDomain' ), 'shortName' => __( 'XS', 'themeLangDomain' ), 'size' => 8, 'slug' => 'extra-small' ), 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' ) ) );Use Highlight Updates dev tools feature to verify no unnecessary re-renders happen when comparing to master.