Skip to content

Commit

Permalink
FontSizePicker: Use components instead of helper functions (#44891)
Browse files Browse the repository at this point in the history
  • Loading branch information
noisysocks authored Nov 2, 2022
1 parent 3865dbe commit 3081460
Show file tree
Hide file tree
Showing 8 changed files with 280 additions and 294 deletions.
1 change: 1 addition & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
- `Autocomplete`: use Popover's new `placement` prop instead of legacy `position` prop ([#44396](https://github.com/WordPress/gutenberg/pull/44396/)).
- `SelectControl`: Add `onChange`, `onBlur` and `onFocus` to storybook actions ([#45432](https://github.com/WordPress/gutenberg/pull/45432/)).
- `FontSizePicker`: Add more comprehensive tests ([#45298](https://github.com/WordPress/gutenberg/pull/45298)).
- `FontSizePicker`: Refactor to use components instead of helper functions ([#44891](https://github.com/WordPress/gutenberg/pull/44891)).

### Experimental

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* WordPress dependencies
*/
import { __, sprintf } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import CustomSelectControl from '../custom-select-control';
import { parseQuantityAndUnitFromRawValue } from '../unit-control';
import type {
FontSizePickerSelectProps,
FontSizePickerSelectOption,
} from './types';

const DEFAULT_OPTION: FontSizePickerSelectOption = {
key: 'default',
name: __( 'Default' ),
value: undefined,
};

const CUSTOM_OPTION: FontSizePickerSelectOption = {
key: 'custom',
name: __( 'Custom' ),
};

const FontSizePickerSelect = ( props: FontSizePickerSelectProps ) => {
const {
fontSizes,
value,
disableCustomFontSizes,
size,
onChange,
onSelectCustom,
} = props;

const options: FontSizePickerSelectOption[] = [
DEFAULT_OPTION,
...fontSizes.map( ( fontSize ) => {
const [ quantity ] = parseQuantityAndUnitFromRawValue(
fontSize.size
);
return {
key: fontSize.slug,
name: fontSize.name || fontSize.slug,
value: fontSize.size,
__experimentalHint:
quantity !== undefined ? String( quantity ) : undefined,
};
} ),
...( disableCustomFontSizes ? [] : [ CUSTOM_OPTION ] ),
];

const selectedOption = value
? options.find( ( option ) => option.value === value ) ?? CUSTOM_OPTION
: DEFAULT_OPTION;

return (
<CustomSelectControl
__nextUnconstrainedWidth
className="components-font-size-picker__select"
label={ __( 'Font size' ) }
hideLabelFromVision
describedBy={ sprintf(
// translators: %s: Currently selected font size.
__( 'Currently selected font size: %s' ),
selectedOption.name
) }
options={ options }
value={ selectedOption }
onChange={ ( {
selectedItem,
}: {
selectedItem: FontSizePickerSelectOption;
} ) => {
if ( selectedItem === CUSTOM_OPTION ) {
onSelectCustom();
} else {
onChange( selectedItem.value );
}
} }
size={ size }
/>
);
};

export default FontSizePickerSelect;
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import {
ToggleGroupControl,
ToggleGroupControlOption,
} from '../toggle-group-control';
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 (
<ToggleGroupControl
__nextHasNoMarginBottom={ __nextHasNoMarginBottom }
label={ __( 'Font size' ) }
hideLabelFromVision
value={ value }
onChange={ onChange }
isBlock
size={ size }
>
{ fontSizes.map( ( fontSize, index ) => (
<ToggleGroupControlOption
key={ fontSize.slug }
value={ fontSize.size }
label={ FONT_SIZES_ALIASES[ index ] }
aria-label={ fontSize.name || FONT_SIZES_ALIASES[ index ] }
showTooltip
/>
) ) }
</ToggleGroupControl>
);
};

export default FontSizePickerToggleGroup;
140 changes: 45 additions & 95 deletions packages/components/src/font-size-picker/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { ForwardedRef } from 'react';
* WordPress dependencies
*/
import deprecated from '@wordpress/deprecated';
import { __, sprintf } from '@wordpress/i18n';
import { __ } from '@wordpress/i18n';
import { settings } from '@wordpress/icons';
import { useState, useMemo, forwardRef } from '@wordpress/element';

Expand All @@ -22,24 +22,10 @@ import {
parseQuantityAndUnitFromRawValue,
useCustomUnits,
} from '../unit-control';
import CustomSelectControl from '../custom-select-control';
import { VisuallyHidden } from '../visually-hidden';
import {
ToggleGroupControl,
ToggleGroupControlOption,
} from '../toggle-group-control';
import {
getFontSizeOptions,
getSelectedOption,
isSimpleCssValue,
CUSTOM_FONT_SIZE,
} from './utils';
import { isSimpleCssValue } from './utils';
import { HStack } from '../h-stack';
import type {
FontSizePickerProps,
FontSizeSelectOption,
FontSizeToggleGroupOption,
} from './types';
import type { FontSizePickerProps } from './types';
import {
Container,
HeaderHint,
Expand All @@ -48,6 +34,8 @@ import {
ResetButton,
} from './styles';
import { Spacer } from '../spacer';
import FontSizePickerSelect from './font-size-picker-select';
import FontSizePickerToggleGroup from './font-size-picker-toggle-group';

const UnforwardedFontSizePicker = (
props: FontSizePickerProps,
Expand All @@ -65,6 +53,7 @@ const UnforwardedFontSizePicker = (
withSlider = false,
withReset = true,
} = props;

if ( ! __nextHasNoMarginBottom ) {
deprecated( 'Bottom margin styles for wp.components.FontSizePicker', {
since: '6.1',
Expand All @@ -77,28 +66,16 @@ const UnforwardedFontSizePicker = (
availableUnits: [ 'px', 'em', 'rem' ],
} );

/**
* The main font size UI displays a toggle group when the presets are less
* than six and a select control when they are more.
*/
const fontSizesContainComplexValues = fontSizes.some(
( { size: sizeArg } ) => ! isSimpleCssValue( sizeArg )
);
const shouldUseSelectControl = fontSizes.length > 5;
const options = useMemo(
() =>
getFontSizeOptions(
shouldUseSelectControl,
fontSizes,
disableCustomFontSizes
),
[ shouldUseSelectControl, fontSizes, disableCustomFontSizes ]
const selectedFontSize = fontSizes.find(
( fontSize ) => fontSize.size === value
);
const selectedOption = getSelectedOption( fontSizes, value );
const isCustomValue = selectedOption.slug === CUSTOM_FONT_SIZE;
const isCustomValue = !! value && ! selectedFontSize;

const [ showCustomValueControl, setShowCustomValueControl ] = useState(
! disableCustomFontSizes && isCustomValue
);

const headerHint = useMemo( () => {
if ( showCustomValueControl ) {
return `(${ __( 'Custom' ) })`;
Expand All @@ -113,49 +90,48 @@ const UnforwardedFontSizePicker = (
`(${ value })`
);
}

if ( shouldUseSelectControl ) {
return (
selectedOption?.size !== undefined &&
isSimpleCssValue( selectedOption?.size ) &&
`(${ selectedOption?.size })`
selectedFontSize?.size !== undefined &&
isSimpleCssValue( selectedFontSize?.size ) &&
`(${ selectedFontSize?.size })`
);
}

if ( ! selectedFontSize ) {
return __( 'Default' );
}

// Calculate the `hint` for toggle group control.
let hint = selectedOption?.name || selectedOption.slug;
let hint = selectedFontSize.name || selectedFontSize.slug;
const fontSizesContainComplexValues = fontSizes.some(
( fontSize ) => ! isSimpleCssValue( fontSize.size )
);
if (
! fontSizesContainComplexValues &&
typeof selectedOption.size === 'string'
typeof selectedFontSize.size === 'string'
) {
const [ , unit ] = parseQuantityAndUnitFromRawValue(
selectedOption.size,
selectedFontSize.size,
units
);
hint += `(${ unit })`;
}
return hint;
}, [
showCustomValueControl,
selectedOption?.name,
selectedOption?.size,
value,
isCustomValue,
selectedFontSize,
value,
shouldUseSelectControl,
fontSizesContainComplexValues,
fontSizes,
] );

if ( ! options ) {
if ( fontSizes.length === 0 && disableCustomFontSizes ) {
return null;
}

// This is used for select control only. We need to add support
// for ToggleGroupControl.
const currentFontSizeSR = sprintf(
// translators: %s: Currently selected font size.
__( 'Currently selected font size: %s' ),
selectedOption.name
);

// If neither the value or first font size is a string, then FontSizePicker
// operates in a legacy "unitless" mode where UnitControl can only be used
// to select px values and onChange() is always called with number values.
Expand Down Expand Up @@ -210,43 +186,31 @@ const UnforwardedFontSizePicker = (
{ !! fontSizes.length &&
shouldUseSelectControl &&
! showCustomValueControl && (
<CustomSelectControl
__nextUnconstrainedWidth
className="components-font-size-picker__select"
label={ __( 'Font size' ) }
hideLabelFromVision
describedBy={ currentFontSizeSR }
options={ options as FontSizeSelectOption[] }
value={ ( options as FontSizeSelectOption[] ).find(
( option ) => option.key === selectedOption.slug
) }
onChange={ ( {
selectedItem,
}: {
selectedItem: FontSizeSelectOption;
} ) => {
if ( selectedItem.size === undefined ) {
<FontSizePickerSelect
fontSizes={ fontSizes }
value={ value }
disableCustomFontSizes={ disableCustomFontSizes }
size={ size }
onChange={ ( newValue ) => {
if ( newValue === undefined ) {
onChange?.( undefined );
} else {
onChange?.(
hasUnits
? selectedItem.size
: Number( selectedItem.size )
hasUnits ? newValue : Number( newValue )
);
}
if ( selectedItem.key === CUSTOM_FONT_SIZE ) {
setShowCustomValueControl( true );
}
} }
size={ size }
onSelectCustom={ () =>
setShowCustomValueControl( true )
}
/>
) }
{ ! shouldUseSelectControl && ! showCustomValueControl && (
<ToggleGroupControl
__nextHasNoMarginBottom={ __nextHasNoMarginBottom }
label={ __( 'Font size' ) }
hideLabelFromVision
<FontSizePickerToggleGroup
fontSizes={ fontSizes }
value={ value }
__nextHasNoMarginBottom={ __nextHasNoMarginBottom }
size={ size }
onChange={ ( newValue ) => {
if ( newValue === undefined ) {
onChange?.( undefined );
Expand All @@ -256,21 +220,7 @@ const UnforwardedFontSizePicker = (
);
}
} }
isBlock
size={ size }
>
{ ( options as FontSizeToggleGroupOption[] ).map(
( option ) => (
<ToggleGroupControlOption
key={ option.key }
value={ option.value }
label={ option.label }
aria-label={ option.name }
showTooltip={ true }
/>
)
) }
</ToggleGroupControl>
/>
) }
{ ! disableCustomFontSizes && showCustomValueControl && (
<Flex className="components-font-size-picker__custom-size-control">
Expand Down
Loading

0 comments on commit 3081460

Please sign in to comment.