Skip to content
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

Convert FontSizePicker to TypeScript #44449

Merged
merged 10 commits into from
Sep 28, 2022
4 changes: 4 additions & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Internal

- `FontSizePicker`: Convert to TypeScript ([#44449](https://github.com/WordPress/gutenberg/pull/44449)).

## 21.1.0 (2022-09-21)

### Deprecations
Expand Down
3 changes: 2 additions & 1 deletion packages/components/src/custom-select-control/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-nocheck
/**
* External dependencies
*/
Expand All @@ -15,7 +16,7 @@ import deprecated from '@wordpress/deprecated';
/**
* Internal dependencies
*/
import { VisuallyHidden } from '../';
import { VisuallyHidden } from '../visually-hidden';
import { Select as SelectControlSelect } from '../select-control/styles/select-control-styles';
import SelectControlChevronDown from '../select-control/chevron-down';
import { InputBaseWithBackCompatMinWidth } from './styles';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* External dependencies
*/
import classNames from 'classnames';
import type { ReactNode, ForwardedRef } from 'react';

/**
* WordPress dependencies
Expand Down Expand Up @@ -34,31 +35,42 @@ import {
} from './utils';
import { VStack } from '../v-stack';
import { HStack } from '../h-stack';
import type {
FontSizePickerProps,
FontSizeSelectOption,
FontSizeToggleGroupOption,
} from './types';

// This conditional is needed to maintain the spacing before the slider in the `withSlider` case.
const MaybeVStack = ( { __nextHasNoMarginBottom, children } ) =>
const MaybeVStack = ( {
__nextHasNoMarginBottom,
children,
}: {
__nextHasNoMarginBottom: boolean;
children: ReactNode;
} ) =>
! __nextHasNoMarginBottom ? (
children
<>{ children }</>
) : (
<VStack spacing={ 6 } children={ children } />
);

function FontSizePicker(
{
props: FontSizePickerProps,
ref: ForwardedRef< any >
) {
const {
/** Start opting into the new margin-free styles that will become the default in a future version. */
__nextHasNoMarginBottom = false,
fallbackFontSize,
fontSizes = [],
disableCustomFontSizes = false,
onChange,
/** @type {'default' | '__unstable-large'} */
onChange = () => {},
size = 'default',
value,
withSlider = false,
withReset = true,
},
ref
) {
} = props;
if ( ! __nextHasNoMarginBottom ) {
deprecated( 'Bottom margin styles for wp.components.FontSizePicker', {
since: '6.1',
Expand All @@ -70,7 +82,7 @@ function FontSizePicker(
const hasUnits = [ typeof value, typeof fontSizes?.[ 0 ]?.size ].includes(
'string'
);
const noUnitsValue = ! hasUnits ? value : parseInt( value );
const noUnitsValue = ! hasUnits ? value : parseInt( String( value ) );
const isPixelValue = typeof value === 'number' || value?.endsWith?.( 'px' );
const units = useCustomUnits( {
availableUnits: [ 'px', 'em', 'rem' ],
Expand Down Expand Up @@ -106,10 +118,15 @@ function FontSizePicker(
// 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 isSimpleCssValue( value ) && `(${ value })`;
return (
value !== undefined &&
isSimpleCssValue( value ) &&
`(${ value })`
);
}
if ( shouldUseSelectControl ) {
return (
selectedOption?.size !== undefined &&
isSimpleCssValue( selectedOption?.size ) &&
`(${ selectedOption?.size })`
);
Expand Down Expand Up @@ -192,12 +209,18 @@ function FontSizePicker(
label={ __( 'Font size' ) }
hideLabelFromVision
describedBy={ currentFontSizeSR }
options={ options }
value={ options.find(
options={ options as FontSizeSelectOption[] }
value={ (
options as FontSizeSelectOption[]
).find(
( option ) =>
option.key === selectedOption.slug
) }
onChange={ ( { selectedItem } ) => {
onChange={ ( {
selectedItem,
}: {
selectedItem: FontSizeSelectOption;
} ) => {
onChange(
hasUnits
? selectedItem.size
Expand Down Expand Up @@ -226,15 +249,17 @@ function FontSizePicker(
isBlock
size={ size }
>
{ options.map( ( option ) => (
<ToggleGroupControlOption
key={ option.key }
value={ option.value }
label={ option.label }
aria-label={ option.name }
showTooltip={ true }
/>
) ) }
{ ( options as FontSizeToggleGroupOption[] ).map(
( option ) => (
<ToggleGroupControlOption
key={ option.key }
value={ option.value }
label={ option.label }
aria-label={ option.name }
showTooltip={ true }
/>
)
) }
</ToggleGroupControl>
) }
{ ! withSlider &&
Expand All @@ -252,8 +277,8 @@ function FontSizePicker(
value={ value }
onChange={ ( nextSize ) => {
if (
0 === parseFloat( nextSize ) ||
! nextSize
! nextSize ||
0 === parseFloat( nextSize )
) {
onChange( undefined );
} else {
Expand Down Expand Up @@ -294,7 +319,11 @@ function FontSizePicker(
__nextHasNoMarginBottom={ __nextHasNoMarginBottom }
className={ `${ baseClassName }__custom-input` }
label={ __( 'Custom Size' ) }
value={ ( isPixelValue && noUnitsValue ) || '' }
value={
isPixelValue && noUnitsValue
? Number( noUnitsValue )
: undefined
}
initialPosition={ fallbackFontSize }
onChange={ ( newValue ) => {
onChange( hasUnits ? newValue + 'px' : newValue );
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* External dependencies
*/
import type { ComponentStory } from '@storybook/react';

/**
* WordPress dependencies
*/
Expand All @@ -13,8 +18,11 @@ export default {
component: FontSizePicker,
};

const FontSizePickerWithState = ( { initialValue, ...props } ) => {
const [ fontSize, setFontSize ] = useState( initialValue );
const FontSizePickerWithState: ComponentStory< typeof FontSizePicker > = ( {
value,
...props
} ) => {
const [ fontSize, setFontSize ] = useState( value );
return (
<FontSizePicker
{ ...props }
Expand All @@ -24,7 +32,8 @@ const FontSizePickerWithState = ( { initialValue, ...props } ) => {
);
};

export const Default = FontSizePickerWithState.bind( {} );
export const Default: ComponentStory< typeof FontSizePicker > =
FontSizePickerWithState.bind( {} );
Default.args = {
fontSizes: [
{
Expand All @@ -43,5 +52,5 @@ Default.args = {
size: 26,
},
],
initialValue: 16,
value: 16,
};
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* External dependencies
*/
import type { ComponentMeta, ComponentStory } from '@storybook/react';

/**
* WordPress dependencies
*/
Expand All @@ -8,11 +13,10 @@ import { useState } from '@wordpress/element';
*/
import FontSizePicker from '../';

export default {
const meta: ComponentMeta< typeof FontSizePicker > = {
title: 'Components/FontSizePicker',
component: FontSizePicker,
argTypes: {
initialValue: { table: { disable: true } }, // hide prop because it's not actually part of FontSizePicker
fallbackFontSize: {
description:
'If no value exists, this prop defines the starting position for the font size picker slider. Only relevant if `withSlider` is `true`.',
Expand All @@ -36,9 +40,13 @@ export default {
docs: { source: { state: 'open' } },
},
};
export default meta;

const FontSizePickerWithState = ( { initialValue, ...props } ) => {
const [ fontSize, setFontSize ] = useState( initialValue );
const FontSizePickerWithState: ComponentStory< typeof FontSizePicker > = ( {
value,
...props
} ) => {
const [ fontSize, setFontSize ] = useState( value );
return (
<FontSizePicker
{ ...props }
Expand All @@ -48,13 +56,16 @@ const FontSizePickerWithState = ( { initialValue, ...props } ) => {
);
};

const TwoFontSizePickersWithState = ( { fontSizes, ...props } ) => {
const TwoFontSizePickersWithState: ComponentStory< typeof FontSizePicker > = ( {
fontSizes,
...props
} ) => {
return (
<>
<h2>Fewer font sizes</h2>
<FontSizePickerWithState
{ ...props }
fontSizes={ fontSizes.slice( 0, 4 ) }
fontSizes={ fontSizes?.slice( 0, 4 ) }
/>

<h2>More font sizes</h2>
Expand All @@ -63,7 +74,8 @@ const TwoFontSizePickersWithState = ( { fontSizes, ...props } ) => {
);
};

export const Default = FontSizePickerWithState.bind( {} );
export const Default: ComponentStory< typeof FontSizePicker > =
FontSizePickerWithState.bind( {} );
Default.args = {
__nextHasNoMarginBottom: true,
disableCustomFontSizes: false,
Expand All @@ -84,23 +96,25 @@ Default.args = {
size: 26,
},
],
initialValue: 16,
value: 16,
withSlider: false,
};

export const WithSlider = FontSizePickerWithState.bind( {} );
export const WithSlider: ComponentStory< typeof FontSizePicker > =
FontSizePickerWithState.bind( {} );
WithSlider.args = {
...Default.args,
fallbackFontSize: 16,
initialValue: undefined,
value: undefined,
withSlider: true,
};

/**
* With custom font sizes disabled via the `disableCustomFontSizes` prop, the user will
* only be able to pick one of the predefined sizes passed in `fontSizes`.
*/
export const WithCustomSizesDisabled = FontSizePickerWithState.bind( {} );
export const WithCustomSizesDisabled: ComponentStory< typeof FontSizePicker > =
FontSizePickerWithState.bind( {} );
WithCustomSizesDisabled.args = {
...Default.args,
disableCustomFontSizes: true,
Expand All @@ -109,7 +123,8 @@ WithCustomSizesDisabled.args = {
/**
* When there are more than 5 font size options, the UI is no longer a toggle group.
*/
export const WithMoreFontSizes = FontSizePickerWithState.bind( {} );
export const WithMoreFontSizes: ComponentStory< typeof FontSizePicker > =
FontSizePickerWithState.bind( {} );
WithMoreFontSizes.args = {
...Default.args,
fontSizes: [
Expand Down Expand Up @@ -144,27 +159,29 @@ WithMoreFontSizes.args = {
size: 36,
},
],
initialValue: 8,
value: 8,
};

/**
* When units like `px` are specified explicitly, it will be shown as a label hint.
*/
export const WithUnits = TwoFontSizePickersWithState.bind( {} );
export const WithUnits: ComponentStory< typeof FontSizePicker > =
TwoFontSizePickersWithState.bind( {} );
WithUnits.args = {
...WithMoreFontSizes.args,
fontSizes: WithMoreFontSizes.args.fontSizes.map( ( option ) => ( {
fontSizes: WithMoreFontSizes.args.fontSizes?.map( ( option ) => ( {
...option,
size: `${ option.size }px`,
} ) ),
initialValue: '8px',
value: '8px',
};

/**
* The label hint will not be shown if it is a complex CSS value. Some examples of complex CSS values
* in this context are CSS functions like `calc()`, `clamp()`, and `var()`.
*/
export const WithComplexCSSValues = TwoFontSizePickersWithState.bind( {} );
export const WithComplexCSSValues: ComponentStory< typeof FontSizePicker > =
TwoFontSizePickersWithState.bind( {} );
WithComplexCSSValues.args = {
...Default.args,
fontSizes: [
Expand Down Expand Up @@ -200,5 +217,5 @@ WithComplexCSSValues.args = {
size: '2.8rem',
},
],
initialValue: '1.125rem',
value: '1.125rem',
};
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const getUnitSelect = () =>
const getUnitLabel = () =>
document.body.querySelector( '.components-unit-control__unit-label' );

const toggleCustomInput = ( showCustomInput ) => {
const toggleCustomInput = ( showCustomInput: boolean ) => {
const label = showCustomInput ? 'Set custom size' : 'Use size preset';
const toggleCustom = screen.getByLabelText( label, { selector: 'button' } );
fireEvent.click( toggleCustom );
Expand Down
Loading