From acc16de3d9ced8a0eb38c1d0c093d25e1e000555 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Mon, 26 Sep 2022 16:24:16 +1000 Subject: [PATCH 1/8] Add types to FontSizePicker --- .../src/custom-select-control/index.js | 3 +- .../font-size-picker/{index.js => index.tsx} | 80 +++++++++----- .../stories/e2e/{index.js => index.tsx} | 17 ++- .../stories/{index.js => index.tsx} | 53 ++++++---- .../test/{index.js => index.tsx} | 2 +- .../test/{utils.js => utils.ts} | 8 +- .../components/src/font-size-picker/types.ts | 100 ++++++++++++++++++ .../font-size-picker/{utils.js => utils.ts} | 73 ++++++++----- packages/components/tsconfig.json | 2 - 9 files changed, 258 insertions(+), 80 deletions(-) rename packages/components/src/font-size-picker/{index.js => index.tsx} (84%) rename packages/components/src/font-size-picker/stories/e2e/{index.js => index.tsx} (60%) rename packages/components/src/font-size-picker/stories/{index.js => index.tsx} (71%) rename packages/components/src/font-size-picker/test/{index.js => index.tsx} (99%) rename packages/components/src/font-size-picker/test/{utils.js => utils.ts} (95%) create mode 100644 packages/components/src/font-size-picker/types.ts rename packages/components/src/font-size-picker/{utils.js => utils.ts} (59%) diff --git a/packages/components/src/custom-select-control/index.js b/packages/components/src/custom-select-control/index.js index f5916849d77fe9..73aebda5d257b2 100644 --- a/packages/components/src/custom-select-control/index.js +++ b/packages/components/src/custom-select-control/index.js @@ -1,3 +1,4 @@ +// @ts-nocheck /** * External dependencies */ @@ -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'; diff --git a/packages/components/src/font-size-picker/index.js b/packages/components/src/font-size-picker/index.tsx similarity index 84% rename from packages/components/src/font-size-picker/index.js rename to packages/components/src/font-size-picker/index.tsx index 1fb266bba02b2b..4a3cd27b584182 100644 --- a/packages/components/src/font-size-picker/index.js +++ b/packages/components/src/font-size-picker/index.tsx @@ -2,6 +2,7 @@ * External dependencies */ import classNames from 'classnames'; +import type { ReactNode, ForwardedRef } from 'react'; /** * WordPress dependencies @@ -34,31 +35,43 @@ import { } from './utils'; import { VStack } from '../v-stack'; import { HStack } from '../h-stack'; +import type { + FontSizePickerProps, + FontSizeSelectOption, + FontSizeToggleGroupOption, +} from './types'; +import type { WordPressComponentProps } from '../ui/context'; // 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 } ) : ( ); function FontSizePicker( - { + props: WordPressComponentProps< FontSizePickerProps, 'fieldset', false >, + 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', @@ -70,7 +83,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' ], @@ -106,10 +119,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 })` ); @@ -192,12 +210,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 @@ -226,15 +250,17 @@ function FontSizePicker( isBlock size={ size } > - { options.map( ( option ) => ( - - ) ) } + { ( options as FontSizeToggleGroupOption[] ).map( + ( option ) => ( + + ) + ) } ) } { ! withSlider && @@ -252,8 +278,8 @@ function FontSizePicker( value={ value } onChange={ ( nextSize ) => { if ( - 0 === parseFloat( nextSize ) || - ! nextSize + ! nextSize || + 0 === parseFloat( nextSize ) ) { onChange( undefined ); } else { @@ -294,7 +320,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 ); diff --git a/packages/components/src/font-size-picker/stories/e2e/index.js b/packages/components/src/font-size-picker/stories/e2e/index.tsx similarity index 60% rename from packages/components/src/font-size-picker/stories/e2e/index.js rename to packages/components/src/font-size-picker/stories/e2e/index.tsx index 30c0140bcefbbd..c2a038e656b55e 100644 --- a/packages/components/src/font-size-picker/stories/e2e/index.js +++ b/packages/components/src/font-size-picker/stories/e2e/index.tsx @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import type { ComponentStory } from '@storybook/react'; + /** * WordPress dependencies */ @@ -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 ( { ); }; -export const Default = FontSizePickerWithState.bind( {} ); +export const Default: ComponentStory< typeof FontSizePicker > = + FontSizePickerWithState.bind( {} ); Default.args = { fontSizes: [ { @@ -43,5 +52,5 @@ Default.args = { size: 26, }, ], - initialValue: 16, + value: 16, }; diff --git a/packages/components/src/font-size-picker/stories/index.js b/packages/components/src/font-size-picker/stories/index.tsx similarity index 71% rename from packages/components/src/font-size-picker/stories/index.js rename to packages/components/src/font-size-picker/stories/index.tsx index 6a2e63eb8ad71b..5d938075748200 100644 --- a/packages/components/src/font-size-picker/stories/index.js +++ b/packages/components/src/font-size-picker/stories/index.tsx @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import type { ComponentMeta, ComponentStory } from '@storybook/react'; + /** * WordPress dependencies */ @@ -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`.', @@ -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 ( { ); }; -const TwoFontSizePickersWithState = ( { fontSizes, ...props } ) => { +const TwoFontSizePickersWithState: ComponentStory< typeof FontSizePicker > = ( { + fontSizes, + ...props +} ) => { return ( <>

Fewer font sizes

More font sizes

@@ -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, @@ -84,15 +96,16 @@ 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, }; @@ -100,7 +113,8 @@ WithSlider.args = { * 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, @@ -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: [ @@ -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: [ @@ -200,5 +217,5 @@ WithComplexCSSValues.args = { size: '2.8rem', }, ], - initialValue: '1.125rem', + value: '1.125rem', }; diff --git a/packages/components/src/font-size-picker/test/index.js b/packages/components/src/font-size-picker/test/index.tsx similarity index 99% rename from packages/components/src/font-size-picker/test/index.js rename to packages/components/src/font-size-picker/test/index.tsx index ca6a8e1a873308..808122852e2273 100644 --- a/packages/components/src/font-size-picker/test/index.js +++ b/packages/components/src/font-size-picker/test/index.tsx @@ -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 ); diff --git a/packages/components/src/font-size-picker/test/utils.js b/packages/components/src/font-size-picker/test/utils.ts similarity index 95% rename from packages/components/src/font-size-picker/test/utils.js rename to packages/components/src/font-size-picker/test/utils.ts index fc074514925ccb..656c6473cd8615 100644 --- a/packages/components/src/font-size-picker/test/utils.js +++ b/packages/components/src/font-size-picker/test/utils.ts @@ -7,7 +7,7 @@ import { getToggleGroupOptions, } from '../utils'; -const simpleCSSCases = [ +const simpleCSSCases: [ number | string, boolean ][] = [ // Test integers and non-integers. [ 1, true ], [ 1.25, true ], @@ -41,7 +41,11 @@ describe( 'isSimpleCssValue', () => { ); } ); -const splitValuesCases = [ +const splitValuesCases: [ + number | string, + string | undefined, + string | undefined +][] = [ // Test integers and non-integers. [ 1, '1', undefined ], [ 1.25, '1.25', undefined ], diff --git a/packages/components/src/font-size-picker/types.ts b/packages/components/src/font-size-picker/types.ts new file mode 100644 index 00000000000000..7934ebc8675d92 --- /dev/null +++ b/packages/components/src/font-size-picker/types.ts @@ -0,0 +1,100 @@ +/** + * External dependencies + */ +import type { ReactNode } from 'react'; + +export type FontSizePickerProps = { + /** + * If `true`, it will not be possible to choose a custom fontSize. The user + * will be forced to pick one of the pre-defined sizes passed in fontSizes. + * + * @default false + */ + disableCustomFontSizes?: boolean; + /** + * If no value exists, this prop defines the starting position for the font + * size picker slider. Only relevant if `withSlider` is `true`. + */ + fallbackFontSize?: number; + /** + * An array of font size objects. The object should contain properties size, + * name, and slug. + */ + fontSizes?: FontSize[]; + /** + * A function that receives the new font size value. + * If onChange is called without any parameter, it should reset the value, + * attending to what reset means in that context, e.g., set the font size to + * undefined or set the font size a starting value. + * + * @default () => {} + */ + onChange?: ( value: number | string | undefined ) => void; + /** + * The current font size value. + */ + value?: number | string; + /** + * If `true`, the UI will contain a slider, instead of a numeric text input + * field. If `false`, no slider will be present. + * + * @default false + */ + withSlider?: boolean; + /** + * If `true`, a reset button will be displayed alongside the input field + * when a custom font size is active. Has no effect when + * `disableCustomFontSizes` or `withSlider` is `true`. + * + * @default true + */ + withReset?: boolean; + /** + * Start opting into the new margin-free styles that will become the default + * in a future version, currently scheduled to be WordPress 6.4. (The prop + * can be safely removed once this happens.) + * + * @default false + */ + __nextHasNoMarginBottom?: boolean; + /** + * Size of the control. + * + * @default 'default' + */ + size?: 'default' | '__unstable-large'; +}; + +export type FontSize = { + /** + * The property `size` contains a number with the font size value, in `px` or + * a string specifying the font size CSS property that should be used eg: + * "13px", "1em", or "clamp(12px, 5vw, 100px)". + */ + size: number | string; + /** + * The `name` property includes a label for that font size e.g.: `Small`. + */ + name?: string; + /** + * The `slug` property is a string with a unique identifier for the font + * size. Used for the class generation process. + */ + slug: string; +}; + +export type FontSizeOption = Omit< FontSize, 'size' > & + Partial< Pick< FontSize, 'size' > >; + +export type FontSizeSelectOption = Pick< FontSizeOption, 'size' > & { + key: string; + name?: string; + __experimentalHint: ReactNode; +}; + +export type FontSizeToggleGroupOption = { + key: string; + value: number | string; + label: string; + name: string; +}; diff --git a/packages/components/src/font-size-picker/utils.js b/packages/components/src/font-size-picker/utils.ts similarity index 59% rename from packages/components/src/font-size-picker/utils.js rename to packages/components/src/font-size-picker/utils.ts index fff3d087cf3e64..eaf42b60ee8737 100644 --- a/packages/components/src/font-size-picker/utils.js +++ b/packages/components/src/font-size-picker/utils.ts @@ -3,6 +3,16 @@ */ import { __ } from '@wordpress/i18n'; +/** + * Internal dependencies + */ +import type { + FontSize, + FontSizeOption, + FontSizeSelectOption, + FontSizeToggleGroupOption, +} from './types'; + const DEFAULT_FONT_SIZE = 'default'; const DEFAULT_FONT_SIZE_OPTION = { slug: DEFAULT_FONT_SIZE, @@ -36,13 +46,16 @@ const FONT_SIZES_ALIASES = [ * Helper util to split a font size to its numeric value * and its `unit`, if exists. * - * @param {string|number} size Font size. - * @return {[number, string]} An array with the numeric value and the unit if exists. + * @param size Font size. + * @return An array with the numeric value and the unit if exists. */ -export function splitValueAndUnitFromSize( size ) { - const [ numericValue, unit ] = `${ size }`.match( /[\d\.]+|\D+/g ); +export function splitValueAndUnitFromSize( size: number | string ) { + const [ numericValue, unit ] = `${ size }`.match( /[\d\.]+|\D+/g ) ?? []; - if ( ! isNaN( parseFloat( numericValue ) ) && isFinite( numericValue ) ) { + if ( + ! isNaN( parseFloat( numericValue ) ) && + isFinite( Number( numericValue ) ) + ) { return [ numericValue, unit ]; } @@ -53,28 +66,28 @@ export function splitValueAndUnitFromSize( size ) { * Some themes use css vars for their font sizes, so until we * have the way of calculating them don't display them. * - * @param {string|number} value The value that is checked. - * @return {boolean} Whether the value is a simple css value. + * @param value The value that is checked. + * @return Whether the value is a simple css value. */ -export function isSimpleCssValue( value ) { +export function isSimpleCssValue( value: number | string ) { const sizeRegex = /^[\d\.]+(px|em|rem|vw|vh|%)?$/i; - return sizeRegex.test( value ); + return sizeRegex.test( String( value ) ); } /** * Return font size options in the proper format depending * on the currently used control (select, toggle group). * - * @param {boolean} useSelectControl Whether to use a select control. - * @param {Object[]} optionsArray Array of available font sizes objects. - * @param {boolean} disableCustomFontSizes Flag that indicates if custom font sizes are disabled. - * @return {Object[]|null} Array of font sizes in proper format for the used control. + * @param useSelectControl Whether to use a select control. + * @param optionsArray Array of available font sizes objects. + * @param disableCustomFontSizes Flag that indicates if custom font sizes are disabled. + * @return Array of font sizes in proper format for the used control. */ export function getFontSizeOptions( - useSelectControl, - optionsArray, - disableCustomFontSizes -) { + useSelectControl: boolean, + optionsArray: FontSize[], + disableCustomFontSizes: boolean +): FontSizeSelectOption[] | FontSizeToggleGroupOption[] | null { if ( disableCustomFontSizes && ! optionsArray.length ) { return null; } @@ -83,8 +96,11 @@ export function getFontSizeOptions( : getToggleGroupOptions( optionsArray ); } -function getSelectOptions( optionsArray, disableCustomFontSizes ) { - const options = [ +function getSelectOptions( + optionsArray: FontSize[], + disableCustomFontSizes: boolean +): FontSizeSelectOption[] { + const options: FontSizeOption[] = [ DEFAULT_FONT_SIZE_OPTION, ...optionsArray, ...( disableCustomFontSizes ? [] : [ CUSTOM_FONT_SIZE_OPTION ] ), @@ -94,21 +110,21 @@ function getSelectOptions( optionsArray, disableCustomFontSizes ) { name, size, __experimentalHint: - size && isSimpleCssValue( size ) && parseFloat( size ), + size && isSimpleCssValue( size ) && parseFloat( String( size ) ), } ) ); } /** * Build options for the toggle group options. * - * @param {Array} optionsArray An array of font size options. - * @param {string[]} labelAliases An array of alternative labels. - * @return {Array} Remapped optionsArray. + * @param optionsArray An array of font size options. + * @param labelAliases An array of alternative labels. + * @return Remapped optionsArray. */ export function getToggleGroupOptions( - optionsArray, - labelAliases = FONT_SIZES_ALIASES -) { + optionsArray: FontSize[], + labelAliases: string[] = FONT_SIZES_ALIASES +): FontSizeToggleGroupOption[] { return optionsArray.map( ( { slug, size, name }, index ) => { return { key: slug, @@ -119,7 +135,10 @@ export function getToggleGroupOptions( } ); } -export function getSelectedOption( fontSizes, value ) { +export function getSelectedOption( + fontSizes: FontSize[], + value: number | string | undefined +): FontSizeOption { if ( ! value ) { return DEFAULT_FONT_SIZE_OPTION; } diff --git a/packages/components/tsconfig.json b/packages/components/tsconfig.json index 67c51cc136afa3..5c103f27ead053 100644 --- a/packages/components/tsconfig.json +++ b/packages/components/tsconfig.json @@ -47,10 +47,8 @@ "src/color-list-picker", "src/combobox-control", "src/custom-gradient-picker", - "src/custom-select-control", "src/dimension-control", "src/duotone-picker", - "src/font-size-picker", "src/gradient-picker", "src/guide", "src/higher-order/navigate-regions", From a384494b804b8f73c29f631eb74f6ef621dab43e Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Mon, 26 Sep 2022 16:46:19 +1000 Subject: [PATCH 2/8] We don't forward props along, so don't use WordPressComponentProps --- packages/components/src/font-size-picker/index.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/components/src/font-size-picker/index.tsx b/packages/components/src/font-size-picker/index.tsx index 4a3cd27b584182..049b3653ead5bd 100644 --- a/packages/components/src/font-size-picker/index.tsx +++ b/packages/components/src/font-size-picker/index.tsx @@ -40,7 +40,6 @@ import type { FontSizeSelectOption, FontSizeToggleGroupOption, } from './types'; -import type { WordPressComponentProps } from '../ui/context'; // This conditional is needed to maintain the spacing before the slider in the `withSlider` case. const MaybeVStack = ( { @@ -57,7 +56,7 @@ const MaybeVStack = ( { ); function FontSizePicker( - props: WordPressComponentProps< FontSizePickerProps, 'fieldset', false >, + props: FontSizePickerProps, ref: ForwardedRef< any > ) { const { From b3f0881f5902dc9a2a7b5469ce8c901ae059baee Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Mon, 26 Sep 2022 16:52:14 +1000 Subject: [PATCH 3/8] Update CHANGELOG.md --- packages/components/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index bfb0e141c69402..b5f104606bc930 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -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 From 3e755bd2bdd3fb54fa30a9cbe0329867b5447814 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Tue, 27 Sep 2022 09:59:34 +1000 Subject: [PATCH 4/8] Don't call onChange if undefined --- packages/components/src/font-size-picker/index.tsx | 14 +++++++------- packages/components/src/font-size-picker/types.ts | 2 -- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/components/src/font-size-picker/index.tsx b/packages/components/src/font-size-picker/index.tsx index 049b3653ead5bd..ba6a408a22b985 100644 --- a/packages/components/src/font-size-picker/index.tsx +++ b/packages/components/src/font-size-picker/index.tsx @@ -65,7 +65,7 @@ function FontSizePicker( fallbackFontSize, fontSizes = [], disableCustomFontSizes = false, - onChange = () => {}, + onChange, size = 'default', value, withSlider = false, @@ -221,7 +221,7 @@ function FontSizePicker( }: { selectedItem: FontSizeSelectOption; } ) => { - onChange( + onChange?.( hasUnits ? selectedItem.size : Number( selectedItem.size ) @@ -242,7 +242,7 @@ function FontSizePicker( hideLabelFromVision value={ value } onChange={ ( newValue ) => { - onChange( + onChange?.( hasUnits ? newValue : Number( newValue ) ); } } @@ -280,9 +280,9 @@ function FontSizePicker( ! nextSize || 0 === parseFloat( nextSize ) ) { - onChange( undefined ); + onChange?.( undefined ); } else { - onChange( + onChange?.( hasUnits ? nextSize : parseInt( @@ -302,7 +302,7 @@ function FontSizePicker( className="components-color-palette__clear" disabled={ value === undefined } onClick={ () => { - onChange( undefined ); + onChange?.( undefined ); } } isSmall variant="secondary" @@ -326,7 +326,7 @@ function FontSizePicker( } initialPosition={ fallbackFontSize } onChange={ ( newValue ) => { - onChange( hasUnits ? newValue + 'px' : newValue ); + onChange?.( hasUnits ? newValue + 'px' : newValue ); } } min={ 12 } max={ 100 } diff --git a/packages/components/src/font-size-picker/types.ts b/packages/components/src/font-size-picker/types.ts index 7934ebc8675d92..e61988b6d4fbfc 100644 --- a/packages/components/src/font-size-picker/types.ts +++ b/packages/components/src/font-size-picker/types.ts @@ -26,8 +26,6 @@ export type FontSizePickerProps = { * If onChange is called without any parameter, it should reset the value, * attending to what reset means in that context, e.g., set the font size to * undefined or set the font size a starting value. - * - * @default () => {} */ onChange?: ( value: number | string | undefined ) => void; /** From 7a883615a235c762821f4d87da919971bf99dce4 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Tue, 27 Sep 2022 10:02:55 +1000 Subject: [PATCH 5/8] Use FontSizePickerProps['value'] --- packages/components/src/font-size-picker/utils.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/components/src/font-size-picker/utils.ts b/packages/components/src/font-size-picker/utils.ts index eaf42b60ee8737..bb3dd42d4e238f 100644 --- a/packages/components/src/font-size-picker/utils.ts +++ b/packages/components/src/font-size-picker/utils.ts @@ -11,6 +11,7 @@ import type { FontSizeOption, FontSizeSelectOption, FontSizeToggleGroupOption, + FontSizePickerProps, } from './types'; const DEFAULT_FONT_SIZE = 'default'; @@ -49,7 +50,9 @@ const FONT_SIZES_ALIASES = [ * @param size Font size. * @return An array with the numeric value and the unit if exists. */ -export function splitValueAndUnitFromSize( size: number | string ) { +export function splitValueAndUnitFromSize( + size: NonNullable< FontSizePickerProps[ 'value' ] > +) { const [ numericValue, unit ] = `${ size }`.match( /[\d\.]+|\D+/g ) ?? []; if ( @@ -69,7 +72,9 @@ export function splitValueAndUnitFromSize( size: number | string ) { * @param value The value that is checked. * @return Whether the value is a simple css value. */ -export function isSimpleCssValue( value: number | string ) { +export function isSimpleCssValue( + value: NonNullable< FontSizePickerProps[ 'value' ] > +) { const sizeRegex = /^[\d\.]+(px|em|rem|vw|vh|%)?$/i; return sizeRegex.test( String( value ) ); } @@ -137,7 +142,7 @@ export function getToggleGroupOptions( export function getSelectedOption( fontSizes: FontSize[], - value: number | string | undefined + value: FontSizePickerProps[ 'value' ] ): FontSizeOption { if ( ! value ) { return DEFAULT_FONT_SIZE_OPTION; From 72a77de2b17258446d9e3401042c96e2b049dc1a Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Tue, 27 Sep 2022 10:21:59 +1000 Subject: [PATCH 6/8] Remove argTypes - these can be inferred --- .../components/src/font-size-picker/index.tsx | 10 ++++++---- .../src/font-size-picker/stories/index.tsx | 20 +------------------ .../components/src/font-size-picker/types.ts | 2 +- 3 files changed, 8 insertions(+), 24 deletions(-) diff --git a/packages/components/src/font-size-picker/index.tsx b/packages/components/src/font-size-picker/index.tsx index ba6a408a22b985..190ca6e1517e0d 100644 --- a/packages/components/src/font-size-picker/index.tsx +++ b/packages/components/src/font-size-picker/index.tsx @@ -55,10 +55,10 @@ const MaybeVStack = ( { ); -function FontSizePicker( +const UnforwardedFontSizePicker = ( 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, @@ -335,6 +335,8 @@ function FontSizePicker( ); -} +}; -export default forwardRef( FontSizePicker ); +export const FontSizePicker = forwardRef( UnforwardedFontSizePicker ); + +export default FontSizePicker; diff --git a/packages/components/src/font-size-picker/stories/index.tsx b/packages/components/src/font-size-picker/stories/index.tsx index 5d938075748200..4937214fca4dbe 100644 --- a/packages/components/src/font-size-picker/stories/index.tsx +++ b/packages/components/src/font-size-picker/stories/index.tsx @@ -16,25 +16,7 @@ import FontSizePicker from '../'; const meta: ComponentMeta< typeof FontSizePicker > = { title: 'Components/FontSizePicker', component: FontSizePicker, - argTypes: { - fallbackFontSize: { - description: - 'If no value exists, this prop defines the starting position for the font size picker slider. Only relevant if `withSlider` is `true`.', - }, - size: { - control: { type: 'radio' }, - options: [ 'default', '__unstable-large' ], - }, - withReset: { - description: - 'If `true`, a reset button will be displayed alongside the input field when a custom font size is active. Has no effect when `disableCustomFontSizes` or `withSlider` is `true`.', - control: { type: 'boolean' }, - table: { - type: 'boolean', - defaultValue: { summary: true }, - }, - }, - }, + argTypes: {}, parameters: { controls: { expanded: true }, docs: { source: { state: 'open' } }, diff --git a/packages/components/src/font-size-picker/types.ts b/packages/components/src/font-size-picker/types.ts index e61988b6d4fbfc..2c824125bb7e1c 100644 --- a/packages/components/src/font-size-picker/types.ts +++ b/packages/components/src/font-size-picker/types.ts @@ -58,7 +58,7 @@ export type FontSizePickerProps = { /** * Size of the control. * - * @default 'default' + * @default default */ size?: 'default' | '__unstable-large'; }; From c5c9acfef5ad9423d45ca6e38d0404e13b51ce36 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Wed, 28 Sep 2022 15:28:15 +1000 Subject: [PATCH 7/8] Hide control for the 'value' prop --- packages/components/src/font-size-picker/stories/index.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/components/src/font-size-picker/stories/index.tsx b/packages/components/src/font-size-picker/stories/index.tsx index 4937214fca4dbe..c3993d72b30142 100644 --- a/packages/components/src/font-size-picker/stories/index.tsx +++ b/packages/components/src/font-size-picker/stories/index.tsx @@ -16,7 +16,9 @@ import FontSizePicker from '../'; const meta: ComponentMeta< typeof FontSizePicker > = { title: 'Components/FontSizePicker', component: FontSizePicker, - argTypes: {}, + argTypes: { + value: { control: { type: null } }, + }, parameters: { controls: { expanded: true }, docs: { source: { state: 'open' } }, From 7f7930ef157c59694d9dac4586eaa039d545efdd Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Wed, 28 Sep 2022 15:30:23 +1000 Subject: [PATCH 8/8] Use storybook actions --- packages/components/src/font-size-picker/stories/index.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/components/src/font-size-picker/stories/index.tsx b/packages/components/src/font-size-picker/stories/index.tsx index c3993d72b30142..894a619e036868 100644 --- a/packages/components/src/font-size-picker/stories/index.tsx +++ b/packages/components/src/font-size-picker/stories/index.tsx @@ -20,6 +20,7 @@ const meta: ComponentMeta< typeof FontSizePicker > = { value: { control: { type: null } }, }, parameters: { + actions: { argTypesRegex: '^on.*' }, controls: { expanded: true }, docs: { source: { state: 'open' } }, }, @@ -28,6 +29,7 @@ export default meta; const FontSizePickerWithState: ComponentStory< typeof FontSizePicker > = ( { value, + onChange, ...props } ) => { const [ fontSize, setFontSize ] = useState( value ); @@ -35,7 +37,10 @@ const FontSizePickerWithState: ComponentStory< typeof FontSizePicker > = ( { { + setFontSize( nextValue ); + onChange?.( nextValue ); + } } /> ); };