diff --git a/packages/components/src/custom-select-control/index.js b/packages/components/src/custom-select-control/index.js index 4c8682f0c7cb3e..337c86e8422d45 100644 --- a/packages/components/src/custom-select-control/index.js +++ b/packages/components/src/custom-select-control/index.js @@ -79,6 +79,7 @@ export default function CustomSelectControl( props ) { value: _selectedItem, onMouseOver, onMouseOut, + __experimentalShowSelectedHint = false, } = props; const { @@ -194,6 +195,12 @@ export default function CustomSelectControl( props ) { } ) } > { itemToString( selectedItem ) } + { __experimentalShowSelectedHint && + selectedItem.__experimentalHint && ( + + { selectedItem.__experimentalHint } + + ) } { /* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */ } diff --git a/packages/components/src/custom-select-control/style.scss b/packages/components/src/custom-select-control/style.scss index e6ca7945abfe1e..b231218ef4b611 100644 --- a/packages/components/src/custom-select-control/style.scss +++ b/packages/components/src/custom-select-control/style.scss @@ -9,6 +9,11 @@ outline: 0; // focus ring is handled elsewhere } +.components-custom-select-control__hint { + color: $gray-600; + margin-left: 10px; +} + .components-custom-select-control__menu { // Hide when collapsed. &[aria-hidden="true"] { @@ -50,7 +55,7 @@ background: $gray-300; } .components-custom-select-control__item-hint { - color: $gray-700; + color: $gray-600; text-align: right; padding-right: $grid-unit-05; } diff --git a/packages/components/src/font-size-picker/constants.ts b/packages/components/src/font-size-picker/constants.ts new file mode 100644 index 00000000000000..1e321aa90b0dfb --- /dev/null +++ b/packages/components/src/font-size-picker/constants.ts @@ -0,0 +1,37 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * List of T-shirt abbreviations. + * + * When there are 5 font sizes or fewer, we assume that the font sizes are + * ordered by size and show T-shirt labels. + */ +export const T_SHIRT_ABBREVIATIONS = [ + /* translators: S stands for 'small' and is a size label. */ + __( 'S' ), + /* translators: M stands for 'medium' and is a size label. */ + __( 'M' ), + /* translators: L stands for 'large' and is a size label. */ + __( 'L' ), + /* translators: XL stands for 'extra large' and is a size label. */ + __( 'XL' ), + /* translators: XXL stands for 'extra extra large' and is a size label. */ + __( 'XXL' ), +]; + +/** + * List of T-shirt names. + * + * When there are 5 font sizes or fewer, we assume that the font sizes are + * ordered by size and show T-shirt labels. + */ +export const T_SHIRT_NAMES = [ + __( 'Small' ), + __( 'Medium' ), + __( 'Large' ), + __( 'Extra Large' ), + __( 'Extra Extra Large' ), +]; diff --git a/packages/components/src/font-size-picker/font-size-picker-select.tsx b/packages/components/src/font-size-picker/font-size-picker-select.tsx index 192a0f5632f715..d3fc2ffe4a61fd 100644 --- a/packages/components/src/font-size-picker/font-size-picker-select.tsx +++ b/packages/components/src/font-size-picker/font-size-picker-select.tsx @@ -12,6 +12,7 @@ import type { FontSizePickerSelectProps, FontSizePickerSelectOption, } from './types'; +import { getCommonSizeUnit, isSimpleCssValue } from './utils'; const DEFAULT_OPTION: FontSizePickerSelectOption = { key: 'default', @@ -34,18 +35,27 @@ const FontSizePickerSelect = ( props: FontSizePickerSelectProps ) => { onSelectCustom, } = props; + const areAllSizesSameUnit = !! getCommonSizeUnit( fontSizes ); + const options: FontSizePickerSelectOption[] = [ DEFAULT_OPTION, ...fontSizes.map( ( fontSize ) => { - const [ quantity ] = parseQuantityAndUnitFromRawValue( - fontSize.size - ); + let hint; + if ( areAllSizesSameUnit ) { + const [ quantity ] = parseQuantityAndUnitFromRawValue( + fontSize.size + ); + if ( quantity !== undefined ) { + hint = String( quantity ); + } + } else if ( isSimpleCssValue( fontSize.size ) ) { + hint = String( fontSize.size ); + } return { key: fontSize.slug, name: fontSize.name || fontSize.slug, value: fontSize.size, - __experimentalHint: - quantity !== undefined ? String( quantity ) : undefined, + __experimentalHint: hint, }; } ), ...( disableCustomFontSizes ? [] : [ CUSTOM_OPTION ] ), @@ -68,6 +78,7 @@ const FontSizePickerSelect = ( props: FontSizePickerSelectProps ) => { ) } options={ options } value={ selectedOption } + __experimentalShowSelectedHint onChange={ ( { selectedItem, }: { diff --git a/packages/components/src/font-size-picker/font-size-picker-toggle-group.tsx b/packages/components/src/font-size-picker/font-size-picker-toggle-group.tsx index a7aed96e76ae6f..697d9e11b67e47 100644 --- a/packages/components/src/font-size-picker/font-size-picker-toggle-group.tsx +++ b/packages/components/src/font-size-picker/font-size-picker-toggle-group.tsx @@ -10,26 +10,9 @@ import { ToggleGroupControl, ToggleGroupControlOption, } from '../toggle-group-control'; +import { T_SHIRT_ABBREVIATIONS, T_SHIRT_NAMES } from './constants'; import type { FontSizePickerToggleGroupProps } from './types'; -/** - * In case we have at most five font sizes, show a `T-shirt size` alias as a - * label of the font size. The label assumes that the font sizes are ordered - * accordingly - from smallest to largest. - */ -const FONT_SIZES_ALIASES = [ - /* translators: S stands for 'small' and is a size label. */ - __( 'S' ), - /* translators: M stands for 'medium' and is a size label. */ - __( 'M' ), - /* translators: L stands for 'large' and is a size label. */ - __( 'L' ), - /* translators: XL stands for 'extra large' and is a size label. */ - __( 'XL' ), - /* translators: XXL stands for 'extra extra large' and is a size label. */ - __( 'XXL' ), -]; - const FontSizePickerToggleGroup = ( props: FontSizePickerToggleGroupProps ) => { const { fontSizes, value, __nextHasNoMarginBottom, size, onChange } = props; return ( @@ -46,8 +29,8 @@ const FontSizePickerToggleGroup = ( props: FontSizePickerToggleGroupProps ) => { ) ) } diff --git a/packages/components/src/font-size-picker/index.tsx b/packages/components/src/font-size-picker/index.tsx index 8c4f1907fa218f..d4e630710e4180 100644 --- a/packages/components/src/font-size-picker/index.tsx +++ b/packages/components/src/font-size-picker/index.tsx @@ -23,7 +23,7 @@ import { useCustomUnits, } from '../unit-control'; import { VisuallyHidden } from '../visually-hidden'; -import { isSimpleCssValue } from './utils'; +import { getCommonSizeUnit } from './utils'; import { HStack } from '../h-stack'; import type { FontSizePickerProps } from './types'; import { @@ -36,6 +36,7 @@ import { import { Spacer } from '../spacer'; import FontSizePickerSelect from './font-size-picker-select'; import FontSizePickerToggleGroup from './font-size-picker-toggle-group'; +import { T_SHIRT_NAMES } from './constants'; const UnforwardedFontSizePicker = ( props: FontSizePickerProps, @@ -78,53 +79,29 @@ const UnforwardedFontSizePicker = ( const headerHint = useMemo( () => { if ( showCustomValueControl ) { - return `(${ __( 'Custom' ) })`; + return __( 'Custom' ); } - // If we have a custom value that is not available in the font sizes, - // show it as a hint as long as it's a simple CSS value. - if ( isCustomValue ) { - return ( - value !== undefined && - isSimpleCssValue( value ) && - `(${ value })` - ); + if ( ! shouldUseSelectControl ) { + if ( selectedFontSize ) { + return ( + selectedFontSize.name || + T_SHIRT_NAMES[ fontSizes.indexOf( selectedFontSize ) ] + ); + } + return ''; } - if ( shouldUseSelectControl ) { - return ( - selectedFontSize?.size !== undefined && - isSimpleCssValue( selectedFontSize?.size ) && - `(${ selectedFontSize?.size })` - ); + const commonUnit = getCommonSizeUnit( fontSizes ); + if ( commonUnit ) { + return `(${ commonUnit })`; } - if ( ! selectedFontSize ) { - return __( 'Default' ); - } - - // Calculate the `hint` for toggle group control. - let hint = selectedFontSize.name || selectedFontSize.slug; - const fontSizesContainComplexValues = fontSizes.some( - ( fontSize ) => ! isSimpleCssValue( fontSize.size ) - ); - if ( - ! fontSizesContainComplexValues && - typeof selectedFontSize.size === 'string' - ) { - const [ , unit ] = parseQuantityAndUnitFromRawValue( - selectedFontSize.size, - units - ); - hint += `(${ unit })`; - } - return hint; + return ''; }, [ showCustomValueControl, - isCustomValue, - selectedFontSize, - value, shouldUseSelectControl, + selectedFontSize, fontSizes, ] ); diff --git a/packages/components/src/font-size-picker/utils.ts b/packages/components/src/font-size-picker/utils.ts index 3f0c6019da8067..d7e426230329e0 100644 --- a/packages/components/src/font-size-picker/utils.ts +++ b/packages/components/src/font-size-picker/utils.ts @@ -6,7 +6,8 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import type { FontSizePickerProps } from './types'; +import type { FontSizePickerProps, FontSize } from './types'; +import { parseQuantityAndUnitFromRawValue } from '../unit-control'; /** * Some themes use css vars for their font sizes, so until we @@ -21,3 +22,25 @@ export function isSimpleCssValue( const sizeRegex = /^[\d\.]+(px|em|rem|vw|vh|%)?$/i; return sizeRegex.test( String( value ) ); } + +/** + * If all of the given font sizes have the same unit (e.g. 'px'), return that + * unit. Otherwise return null. + * + * @param fontSizes List of font sizes. + * @return The common unit, or null. + */ +export function getCommonSizeUnit( fontSizes: FontSize[] ) { + const [ firstFontSize, ...otherFontSizes ] = fontSizes; + if ( ! firstFontSize ) { + return null; + } + const [ , firstUnit ] = parseQuantityAndUnitFromRawValue( + firstFontSize.size + ); + const areAllSizesSameUnit = otherFontSizes.every( ( fontSize ) => { + const [ , unit ] = parseQuantityAndUnitFromRawValue( fontSize.size ); + return unit === firstUnit; + } ); + return areAllSizesSameUnit ? firstUnit : null; +}