-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Block Support: Add font style and weight options with combined UI #26444
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -161,6 +161,54 @@ | |
"size": 42 | ||
} | ||
], | ||
"fontStyles": [ | ||
{ | ||
"name": "Regular", | ||
"slug": "normal" | ||
}, | ||
{ | ||
"name": "Italic", | ||
"slug": "italic" | ||
} | ||
], | ||
"fontWeights": [ | ||
{ | ||
"name": "Ultralight", | ||
"slug": "100" | ||
}, | ||
{ | ||
"name": "Thin", | ||
"slug": "200" | ||
}, | ||
{ | ||
"name": "Light", | ||
"slug": "300" | ||
}, | ||
{ | ||
"name": "Regular", | ||
"slug": "400" | ||
}, | ||
{ | ||
"name": "Medium", | ||
"slug": "500" | ||
}, | ||
{ | ||
"name": "Semibold", | ||
"slug": "600" | ||
}, | ||
{ | ||
"name": "Bold", | ||
"slug": "700" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the other presets we use different keys for slug and value. This approach is using the same keys for both. The idea of presets is we can change the value and the places using a given slug will automatically all use the new value. If we use the slug for the value the main objective of the preset is not accomplished as one can not change the value without changing the slug. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I can definitely update the presets to use both slug and value. It just seemed odd to me having both the slug and the value the same for the most part.
The benefit I saw in using the presets that could be defined via the theme.json was that it also provided a means to customize the available styles or weights. |
||
}, | ||
{ | ||
"name": "Heavy", | ||
"slug": "800" | ||
}, | ||
{ | ||
"name": "Black", | ||
"slug": "900" | ||
} | ||
], | ||
"textTransforms": [ | ||
{ | ||
"name": "AB", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { CustomSelectControl } from '@wordpress/components'; | ||
import { useMemo } from '@wordpress/element'; | ||
import { __ } from '@wordpress/i18n'; | ||
|
||
/** | ||
* Control to display unified font style and weight options. | ||
* | ||
* @param {Object} props Component props. | ||
* @param {Object} props.value Currently selected combination of font style and weight. | ||
* @param {Object} props.options Object containing weight and style options. | ||
* @param {Function} props.onChange Handles selection change. | ||
* @return {WPElement} Font appearance control. | ||
*/ | ||
export default function FontAppearanceControl( { value, options, onChange } ) { | ||
const { fontStyle, fontWeight } = value; | ||
const { fontStyles = [], fontWeights = [] } = options; | ||
const hasStylesOrWeights = fontStyles.length > 0 || fontWeights.length > 0; | ||
|
||
// Map font styles and weights to select options. | ||
const selectOptions = useMemo( () => { | ||
const defaultCombo = { fontStyle: undefined, fontWeight: undefined }; | ||
const combinedOptions = [ | ||
{ | ||
key: 'default', | ||
name: __( 'Default' ), | ||
style: defaultCombo, | ||
presetStyle: defaultCombo, | ||
}, | ||
]; | ||
|
||
fontStyles.forEach( ( { name: styleName, slug: styleSlug } ) => { | ||
fontWeights.forEach( ( { name: weightName, slug: weightSlug } ) => { | ||
combinedOptions.push( { | ||
key: `${ weightSlug }-${ styleSlug }`, | ||
name: | ||
styleSlug === 'normal' | ||
? weightName | ||
: `${ weightName } ${ styleName }`, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess it may make sense to use sprintf and our translated function __ for i18n, depending on the locale it may make sense to change the order of weightName and styleName. |
||
// style applies font appearance to the individual select option. | ||
style: { fontStyle: styleSlug, fontWeight: weightSlug }, | ||
// presetStyle are the actual typography styles that should be given to onChange. | ||
presetStyle: { | ||
fontStyle: `var:preset|font-style|${ styleSlug }`, | ||
fontWeight: `var:preset|font-weight|${ weightSlug }`, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The other control components with presets that we have: Don't handle the different ways a value should be stored, if a preset is used or not. They just receive a value, and a set of possible values (for UI purposes) and allow them to change the value. They are not aware of CSS vars etc.. |
||
}, | ||
} ); | ||
} ); | ||
} ); | ||
|
||
return combinedOptions; | ||
}, [ options ] ); | ||
|
||
const currentSelection = selectOptions.find( | ||
( option ) => | ||
option.presetStyle.fontStyle === fontStyle && | ||
option.presetStyle.fontWeight === fontWeight | ||
); | ||
|
||
return ( | ||
<fieldset className="components-font-appearance-control"> | ||
{ hasStylesOrWeights && ( | ||
<CustomSelectControl | ||
className="components-font-appearance-control__select" | ||
label={ __( 'Appearance' ) } | ||
options={ selectOptions } | ||
value={ currentSelection } | ||
onChange={ ( { selectedItem } ) => | ||
onChange( selectedItem.presetStyle ) | ||
} | ||
/> | ||
) } | ||
</fieldset> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
.components-font-appearance-control__select { | ||
margin-bottom: 24px; | ||
|
||
ul { | ||
li { | ||
color: $gray-900; | ||
text-transform: capitalize; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously @mtias referred to the intention of not having more presets for now, besides the one for the font family. Would you be able to confirm if that's still the case @mtias?
In the fontStyles and fontWeights I'm not sure if presets bring much value. I guess it may make sense that the themes define for a given font family the weights and styles that are available because depending on the font family one font-weight may be loaded or not, but that may be discussed as part of font loading API.
I guess for font-weight and style we can use normal inline styles without presets e.g: "font-weight: 900;".