From b8e83e358d90d330b29891cfba80259fc21734dd Mon Sep 17 00:00:00 2001 From: Matias Benedetto Date: Wed, 5 Jun 2024 12:25:17 +0200 Subject: [PATCH 01/38] move font size picker custom control to a new component --- packages/block-editor/README.md | 2 +- .../components/font-sizes/font-size-picker.js | 2 +- .../font-size-picker-custom-control.tsx | 114 ++++++++++++++++++ .../components/src/font-size-picker/index.tsx | 98 +++------------ .../components/src/font-size-picker/types.ts | 41 +++++++ 5 files changed, 172 insertions(+), 85 deletions(-) create mode 100644 packages/components/src/font-size-picker/font-size-picker-custom-control.tsx diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 7c70473430b31e..b153ffaa0c4086 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -388,7 +388,7 @@ Undocumented declaration. _Related_ -- +- ### getColorClassName diff --git a/packages/block-editor/src/components/font-sizes/font-size-picker.js b/packages/block-editor/src/components/font-sizes/font-size-picker.js index 959b2c23806ded..69de3b1a0437d2 100644 --- a/packages/block-editor/src/components/font-sizes/font-size-picker.js +++ b/packages/block-editor/src/components/font-sizes/font-size-picker.js @@ -24,6 +24,6 @@ function FontSizePicker( props ) { } /** - * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/font-sizes/README.md + * @see https://github.com/WordPress/gutenberg/tree/trunk/packages/block-editor/src/components/font-sizes#readme */ export default FontSizePicker; diff --git a/packages/components/src/font-size-picker/font-size-picker-custom-control.tsx b/packages/components/src/font-size-picker/font-size-picker-custom-control.tsx new file mode 100644 index 00000000000000..1dd53c1a51c213 --- /dev/null +++ b/packages/components/src/font-size-picker/font-size-picker-custom-control.tsx @@ -0,0 +1,114 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { Button } from '../button'; +import RangeControl from '../range-control'; +import { Flex, FlexItem } from '../flex'; +import { default as UnitControl } from '../unit-control'; +import type { FontSizePickerCustomControlProps } from './types'; + +import { Spacer } from '../spacer'; + +function FontSizePickerCustomControl( + props: FontSizePickerCustomControlProps +) { + const { + __next40pxDefaultSize, + value, + valueQuantity, + valueUnit, + isValueUnitRelative, + isDisabled, + size = 'default', + units, + withSlider = false, + withReset = true, + onChange, + hasUnits, + fallbackFontSize, + } = props; + + return ( + + + { + if ( newValue === undefined ) { + onChange?.( undefined ); + } else { + onChange?.( + hasUnits ? newValue : parseInt( newValue, 10 ) + ); + } + } } + size={ size } + units={ hasUnits ? units : [] } + min={ 0 } + /> + + { withSlider && ( + + + { + if ( newValue === undefined ) { + onChange?.( undefined ); + } else if ( hasUnits ) { + onChange?.( + newValue + ( valueUnit ?? 'px' ) + ); + } else { + onChange?.( newValue ); + } + } } + min={ 0 } + max={ isValueUnitRelative ? 10 : 100 } + step={ isValueUnitRelative ? 0.1 : 1 } + /> + + + ) } + { withReset && ( + + + + ) } + + ); +} + +export default FontSizePickerCustomControl; diff --git a/packages/components/src/font-size-picker/index.tsx b/packages/components/src/font-size-picker/index.tsx index cb17b7a16e3637..c6314fd039376e 100644 --- a/packages/components/src/font-size-picker/index.tsx +++ b/packages/components/src/font-size-picker/index.tsx @@ -13,11 +13,7 @@ import { useState, useMemo, forwardRef } from '@wordpress/element'; /** * Internal dependencies */ -import { Button } from '../button'; -import RangeControl from '../range-control'; -import { Flex, FlexItem } from '../flex'; import { - default as UnitControl, parseQuantityAndUnitFromRawValue, useCustomUnits, } from '../unit-control'; @@ -34,6 +30,7 @@ import { import { Spacer } from '../spacer'; import FontSizePickerSelect from './font-size-picker-select'; import FontSizePickerToggleGroup from './font-size-picker-toggle-group'; +import FontSizePickerCustomControl from './font-size-picker-custom-control'; import { T_SHIRT_NAMES } from './constants'; const DEFAULT_UNITS = [ 'px', 'em', 'rem', 'vw', 'vh' ]; @@ -201,85 +198,20 @@ const UnforwardedFontSizePicker = ( /> ) } { ! disableCustomFontSizes && showCustomValueControl && ( - - - { - if ( newValue === undefined ) { - onChange?.( undefined ); - } else { - onChange?.( - hasUnits - ? newValue - : parseInt( newValue, 10 ) - ); - } - } } - size={ size } - units={ hasUnits ? units : [] } - min={ 0 } - /> - - { withSlider && ( - - - { - if ( newValue === undefined ) { - onChange?.( undefined ); - } else if ( hasUnits ) { - onChange?.( - newValue + - ( valueUnit ?? 'px' ) - ); - } else { - onChange?.( newValue ); - } - } } - min={ 0 } - max={ isValueUnitRelative ? 10 : 100 } - step={ isValueUnitRelative ? 0.1 : 1 } - /> - - - ) } - { withReset && ( - - - - ) } - + ) } diff --git a/packages/components/src/font-size-picker/types.ts b/packages/components/src/font-size-picker/types.ts index 6b4ed4b7ee75a5..0cde521d4bf2bc 100644 --- a/packages/components/src/font-size-picker/types.ts +++ b/packages/components/src/font-size-picker/types.ts @@ -1,3 +1,8 @@ +/** + * Internal dependencies + */ +import type { WPUnitControlUnit } from '../unit-control/types'; + export type FontSizePickerProps = { /** * If `true`, it will not be possible to choose a custom fontSize. The user @@ -75,6 +80,42 @@ export type FontSizePickerProps = { size?: 'default' | '__unstable-large'; }; +export type FontSizePickerCustomControlProps = Pick< + FontSizePickerProps, + | '__next40pxDefaultSize' + | 'value' + | 'size' + | 'withSlider' + | 'withReset' + | 'onChange' + | 'fallbackFontSize' +> & { + /** + * The units available for selection. + */ + units: WPUnitControlUnit[]; + /** + * The numeric representation of the font size value. + */ + valueQuantity: number | undefined; + /** + * The unit of the font size value (e.g., "px", "em", "rem"). + */ + valueUnit: string | undefined; + /** + * Whether the valueUnit is relative to another element's size (e.g., "em", "rem"). + */ + isValueUnitRelative: boolean; + /** + * Disables interaction with the control. + */ + isDisabled?: boolean; + /** + * Whether the font size has units. + */ + hasUnits: boolean; +}; + export type FontSize = { /** * The property `size` contains a number with the font size value, in `px` or From 107ea70fd502c32351ab79f0e35c7a7fffbcc744 Mon Sep 17 00:00:00 2001 From: Matias Benedetto Date: Wed, 5 Jun 2024 14:37:42 +0200 Subject: [PATCH 02/38] move props to the inner component --- .../font-size-picker-custom-control.tsx | 25 +++++++++++++++---- .../components/src/font-size-picker/index.tsx | 25 +++---------------- .../components/src/font-size-picker/types.ts | 22 +--------------- packages/components/src/private-apis.ts | 2 ++ 4 files changed, 27 insertions(+), 47 deletions(-) diff --git a/packages/components/src/font-size-picker/font-size-picker-custom-control.tsx b/packages/components/src/font-size-picker/font-size-picker-custom-control.tsx index 1dd53c1a51c213..af32ce4429d43d 100644 --- a/packages/components/src/font-size-picker/font-size-picker-custom-control.tsx +++ b/packages/components/src/font-size-picker/font-size-picker-custom-control.tsx @@ -9,23 +9,26 @@ import { __ } from '@wordpress/i18n'; import { Button } from '../button'; import RangeControl from '../range-control'; import { Flex, FlexItem } from '../flex'; -import { default as UnitControl } from '../unit-control'; import type { FontSizePickerCustomControlProps } from './types'; +import { + default as UnitControl, + parseQuantityAndUnitFromRawValue, + useCustomUnits, +} from '../unit-control'; import { Spacer } from '../spacer'; +export const DEFAULT_UNITS = [ 'px', 'em', 'rem', 'vw', 'vh' ]; + function FontSizePickerCustomControl( props: FontSizePickerCustomControlProps ) { const { __next40pxDefaultSize, value, - valueQuantity, - valueUnit, - isValueUnitRelative, isDisabled, size = 'default', - units, + units: unitsProp = DEFAULT_UNITS, withSlider = false, withReset = true, onChange, @@ -33,6 +36,18 @@ function FontSizePickerCustomControl( fallbackFontSize, } = props; + const units = useCustomUnits( { + availableUnits: unitsProp, + } ); + + const [ valueQuantity, valueUnit ] = parseQuantityAndUnitFromRawValue( + value, + units + ); + + const isValueUnitRelative = + !! valueUnit && [ 'em', 'rem', 'vw', 'vh' ].includes( valueUnit ); + return ( diff --git a/packages/components/src/font-size-picker/index.tsx b/packages/components/src/font-size-picker/index.tsx index c6314fd039376e..6cd3cea65ef739 100644 --- a/packages/components/src/font-size-picker/index.tsx +++ b/packages/components/src/font-size-picker/index.tsx @@ -13,10 +13,6 @@ import { useState, useMemo, forwardRef } from '@wordpress/element'; /** * Internal dependencies */ -import { - parseQuantityAndUnitFromRawValue, - useCustomUnits, -} from '../unit-control'; import { VisuallyHidden } from '../visually-hidden'; import { getCommonSizeUnit } from './utils'; import type { FontSizePickerProps } from './types'; @@ -30,11 +26,11 @@ import { import { Spacer } from '../spacer'; import FontSizePickerSelect from './font-size-picker-select'; import FontSizePickerToggleGroup from './font-size-picker-toggle-group'; -import FontSizePickerCustomControl from './font-size-picker-custom-control'; +import FontSizePickerCustomControl, { + DEFAULT_UNITS, +} from './font-size-picker-custom-control'; import { T_SHIRT_NAMES } from './constants'; -const DEFAULT_UNITS = [ 'px', 'em', 'rem', 'vw', 'vh' ]; - const UnforwardedFontSizePicker = ( props: FontSizePickerProps, ref: ForwardedRef< any > @@ -46,16 +42,12 @@ const UnforwardedFontSizePicker = ( disableCustomFontSizes = false, onChange, size = 'default', - units: unitsProp = DEFAULT_UNITS, + units = DEFAULT_UNITS, value, withSlider = false, withReset = true, } = props; - const units = useCustomUnits( { - availableUnits: unitsProp, - } ); - const shouldUseSelectControl = fontSizes.length > 5; const selectedFontSize = fontSizes.find( ( fontSize ) => fontSize.size === value @@ -104,12 +96,6 @@ const UnforwardedFontSizePicker = ( const hasUnits = typeof value === 'string' || typeof fontSizes[ 0 ]?.size === 'string'; - const [ valueQuantity, valueUnit ] = parseQuantityAndUnitFromRawValue( - value, - units - ); - const isValueUnitRelative = - !! valueUnit && [ 'em', 'rem', 'vw', 'vh' ].includes( valueUnit ); const isDisabled = value === undefined; return ( @@ -201,9 +187,6 @@ const UnforwardedFontSizePicker = ( & { - /** - * The units available for selection. - */ - units: WPUnitControlUnit[]; - /** - * The numeric representation of the font size value. - */ - valueQuantity: number | undefined; - /** - * The unit of the font size value (e.g., "px", "em", "rem"). - */ - valueUnit: string | undefined; - /** - * Whether the valueUnit is relative to another element's size (e.g., "em", "rem"). - */ - isValueUnitRelative: boolean; /** * Disables interaction with the control. */ diff --git a/packages/components/src/private-apis.ts b/packages/components/src/private-apis.ts index f55373664efffa..62d09a3a54633c 100644 --- a/packages/components/src/private-apis.ts +++ b/packages/components/src/private-apis.ts @@ -26,6 +26,7 @@ import { DropdownMenuItemLabel as DropdownMenuItemLabelV2, DropdownMenuItemHelpText as DropdownMenuItemHelpTextV2, } from './dropdown-menu-v2'; +import FontSizePickerCustomControl from './font-size-picker/font-size-picker-custom-control'; import { ComponentsContext } from './context/context-system-provider'; import Theme from './theme'; import Tabs from './tabs'; @@ -53,5 +54,6 @@ lock( privateApis, { DropdownMenuSeparatorV2, DropdownMenuItemLabelV2, DropdownMenuItemHelpTextV2, + FontSizePickerCustomControl, kebabCase, } ); From 4d5577149ffa5e0d9e316e5a2e405781837ba599 Mon Sep 17 00:00:00 2001 From: Matias Benedetto Date: Fri, 7 Jun 2024 17:59:34 +0200 Subject: [PATCH 03/38] renaming and moving the custom size control to its own folder --- .../components/src/font-size-picker/index.tsx | 8 +- .../src/font-size-picker/test/index.tsx | 8 +- .../components/src/font-size-picker/types.ts | 110 ++---------------- .../components/src/font-size-picker/utils.ts | 5 +- packages/components/src/private-apis.ts | 4 +- .../index.tsx} | 12 +- packages/components/src/size-control/types.ts | 83 +++++++++++++ 7 files changed, 111 insertions(+), 119 deletions(-) rename packages/components/src/{font-size-picker/font-size-picker-custom-control.tsx => size-control/index.tsx} (91%) create mode 100644 packages/components/src/size-control/types.ts diff --git a/packages/components/src/font-size-picker/index.tsx b/packages/components/src/font-size-picker/index.tsx index 6cd3cea65ef739..9f6e0bf799fa88 100644 --- a/packages/components/src/font-size-picker/index.tsx +++ b/packages/components/src/font-size-picker/index.tsx @@ -26,9 +26,7 @@ import { import { Spacer } from '../spacer'; import FontSizePickerSelect from './font-size-picker-select'; import FontSizePickerToggleGroup from './font-size-picker-toggle-group'; -import FontSizePickerCustomControl, { - DEFAULT_UNITS, -} from './font-size-picker-custom-control'; +import SizeControl, { DEFAULT_UNITS } from '../size-control'; import { T_SHIRT_NAMES } from './constants'; const UnforwardedFontSizePicker = ( @@ -184,7 +182,7 @@ const UnforwardedFontSizePicker = ( /> ) } { ! disableCustomFontSizes && showCustomValueControl && ( - ) } diff --git a/packages/components/src/font-size-picker/test/index.tsx b/packages/components/src/font-size-picker/test/index.tsx index 9bb3b2d8677b69..a14c159e92d52b 100644 --- a/packages/components/src/font-size-picker/test/index.tsx +++ b/packages/components/src/font-size-picker/test/index.tsx @@ -8,7 +8,7 @@ import userEvent from '@testing-library/user-event'; * Internal dependencies */ import FontSizePicker from '../'; -import type { FontSize } from '../types'; +import type { Size } from '../../size-control/types'; describe( 'FontSizePicker', () => { test.each( [ @@ -474,7 +474,7 @@ describe( 'FontSizePicker', () => { commonTests( fontSizes ); } ); - function commonToggleGroupTests( fontSizes: FontSize[] ) { + function commonToggleGroupTests( fontSizes: Size[] ) { it( 'defaults to M when value is 16px', () => { render( { ); } - function commonSelectTests( fontSizes: FontSize[] ) { + function commonSelectTests( fontSizes: Size[] ) { it( 'shows custom input when Custom is selected', async () => { const user = userEvent.setup(); const onChange = jest.fn(); @@ -519,7 +519,7 @@ describe( 'FontSizePicker', () => { } ); } - function commonTests( fontSizes: FontSize[] ) { + function commonTests( fontSizes: Size[] ) { it( 'shows custom input when value is unknown', () => { render( ); expect( screen.getByLabelText( 'Custom' ) ).toBeInTheDocument(); diff --git a/packages/components/src/font-size-picker/types.ts b/packages/components/src/font-size-picker/types.ts index c2b701122a41c8..918631e7cd236c 100644 --- a/packages/components/src/font-size-picker/types.ts +++ b/packages/components/src/font-size-picker/types.ts @@ -1,4 +1,12 @@ -export type FontSizePickerProps = { +/** + * Internal dependencies + */ +import type { SizeControlBaseProps, Size } from '../size-control/types'; + +export type FontSizePickerProps = Omit< + SizeControlBaseProps, + 'fallbackValue' +> & { /** * 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. @@ -15,103 +23,7 @@ export type FontSizePickerProps = { * 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. - */ - onChange?: ( - value: number | string | undefined, - selectedItem?: FontSize - ) => void; - /** - * Available units for custom font size selection. - * - * @default `[ 'px', 'em', 'rem' ]` - */ - units?: string[]; - /** - * 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 - * @deprecated Default behavior since WP 6.5. Prop can be safely removed. - * @ignore - */ - __nextHasNoMarginBottom?: boolean; - /** - * Start opting into the larger default height that will become the default size in a future version. - * - * @default false - */ - __next40pxDefaultSize?: boolean; - /** - * Size of the control. - * - * @default 'default' - */ - size?: 'default' | '__unstable-large'; -}; - -export type FontSizePickerCustomControlProps = Pick< - FontSizePickerProps, - | '__next40pxDefaultSize' - | 'value' - | 'size' - | 'withSlider' - | 'withReset' - | 'onChange' - | 'fallbackFontSize' - | 'units' -> & { - /** - * Disables interaction with the control. - */ - isDisabled?: boolean; - /** - * Whether the font size has units. - */ - hasUnits: boolean; -}; - -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; + fontSizes?: Size[]; }; export type FontSizePickerSelectProps = Pick< @@ -130,7 +42,7 @@ export type FontSizePickerSelectProps = Pick< export type FontSizePickerSelectOption = { key: string; name: string; - value?: FontSize[ 'size' ]; + value?: Size[ 'size' ]; __experimentalHint?: string; }; diff --git a/packages/components/src/font-size-picker/utils.ts b/packages/components/src/font-size-picker/utils.ts index cf81c7ed27b182..249dc3620de25c 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, FontSize } from './types'; +import type { Size } from '../size-control/types'; +import type { FontSizePickerProps } from './types'; import { parseQuantityAndUnitFromRawValue } from '../unit-control'; /** @@ -31,7 +32,7 @@ export function isSimpleCssValue( * @param fontSizes List of font sizes. * @return The common unit, or null. */ -export function getCommonSizeUnit( fontSizes: FontSize[] ) { +export function getCommonSizeUnit( fontSizes: Size[] ) { const [ firstFontSize, ...otherFontSizes ] = fontSizes; if ( ! firstFontSize ) { return null; diff --git a/packages/components/src/private-apis.ts b/packages/components/src/private-apis.ts index 62d09a3a54633c..2be3a8793ec64d 100644 --- a/packages/components/src/private-apis.ts +++ b/packages/components/src/private-apis.ts @@ -26,7 +26,7 @@ import { DropdownMenuItemLabel as DropdownMenuItemLabelV2, DropdownMenuItemHelpText as DropdownMenuItemHelpTextV2, } from './dropdown-menu-v2'; -import FontSizePickerCustomControl from './font-size-picker/font-size-picker-custom-control'; +import SizeControl from './size-control'; import { ComponentsContext } from './context/context-system-provider'; import Theme from './theme'; import Tabs from './tabs'; @@ -54,6 +54,6 @@ lock( privateApis, { DropdownMenuSeparatorV2, DropdownMenuItemLabelV2, DropdownMenuItemHelpTextV2, - FontSizePickerCustomControl, + SizeControl, kebabCase, } ); diff --git a/packages/components/src/font-size-picker/font-size-picker-custom-control.tsx b/packages/components/src/size-control/index.tsx similarity index 91% rename from packages/components/src/font-size-picker/font-size-picker-custom-control.tsx rename to packages/components/src/size-control/index.tsx index af32ce4429d43d..185d8413155118 100644 --- a/packages/components/src/font-size-picker/font-size-picker-custom-control.tsx +++ b/packages/components/src/size-control/index.tsx @@ -9,7 +9,7 @@ import { __ } from '@wordpress/i18n'; import { Button } from '../button'; import RangeControl from '../range-control'; import { Flex, FlexItem } from '../flex'; -import type { FontSizePickerCustomControlProps } from './types'; +import type { SizeControlProps } from './types'; import { default as UnitControl, parseQuantityAndUnitFromRawValue, @@ -20,9 +20,7 @@ import { Spacer } from '../spacer'; export const DEFAULT_UNITS = [ 'px', 'em', 'rem', 'vw', 'vh' ]; -function FontSizePickerCustomControl( - props: FontSizePickerCustomControlProps -) { +function SizeControl( props: SizeControlProps ) { const { __next40pxDefaultSize, value, @@ -33,7 +31,7 @@ function FontSizePickerCustomControl( withReset = true, onChange, hasUnits, - fallbackFontSize, + fallbackValue, } = props; const units = useCustomUnits( { @@ -81,7 +79,7 @@ function FontSizePickerCustomControl( label={ __( 'Custom Size' ) } hideLabelFromVision value={ valueQuantity } - initialPosition={ fallbackFontSize } + initialPosition={ fallbackValue } withInputField={ false } onChange={ ( newValue ) => { if ( newValue === undefined ) { @@ -126,4 +124,4 @@ function FontSizePickerCustomControl( ); } -export default FontSizePickerCustomControl; +export default SizeControl; diff --git a/packages/components/src/size-control/types.ts b/packages/components/src/size-control/types.ts new file mode 100644 index 00000000000000..0e5b7e50155c5c --- /dev/null +++ b/packages/components/src/size-control/types.ts @@ -0,0 +1,83 @@ +export type Size = { + /** + * 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 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 SizeControlBaseProps = { + /** + * If no value exists, this prop defines the starting position for the font + * size picker slider. Only relevant if `withSlider` is `true`. + */ + fallbackValue?: number; + /** + * 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. + */ + onChange?: ( + value: number | string | undefined, + selectedItem?: Size + ) => void; + /** + * Available units for custom font size selection. + * + * @default `[ 'px', 'em', 'rem' ]` + */ + units?: string[]; + /** + * 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 larger default height that will become the default size in a future version. + * + * @default false + */ + __next40pxDefaultSize?: boolean; + /** + * Size of the control. + * + * @default 'default' + */ + size?: 'default' | '__unstable-large'; +}; + +export type SizeControlProps = SizeControlBaseProps & { + /** + * Disables interaction with the control. + */ + isDisabled?: boolean; + /** + * Whether the font size has units. + */ + hasUnits: boolean; +}; From 19307c0b0b93b04a58fc25b7d22d3bcf40fd1a94 Mon Sep 17 00:00:00 2001 From: Matias Benedetto Date: Mon, 10 Jun 2024 17:14:58 +0200 Subject: [PATCH 04/38] implement font size management UI --- .../src/components/global-styles/font-size.js | 257 ++++++++++++++++++ .../components/global-styles/font-sizes.js | 83 ++++++ .../global-styles/screen-typography.js | 2 + .../src/components/global-styles/ui.js | 14 +- 4 files changed, 354 insertions(+), 2 deletions(-) create mode 100644 packages/edit-site/src/components/global-styles/font-size.js create mode 100644 packages/edit-site/src/components/global-styles/font-sizes.js diff --git a/packages/edit-site/src/components/global-styles/font-size.js b/packages/edit-site/src/components/global-styles/font-size.js new file mode 100644 index 00000000000000..544af6af3d0c24 --- /dev/null +++ b/packages/edit-site/src/components/global-styles/font-size.js @@ -0,0 +1,257 @@ +/** + * WordPress dependencies + */ +import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; +import { __, sprintf } from '@wordpress/i18n'; +import { + __experimentalToggleGroupControl as ToggleGroupControl, + __experimentalToggleGroupControlOption as ToggleGroupControlOption, + __experimentalSpacer as Spacer, + __experimentalUseNavigator as useNavigator, + __experimentalInputControl as InputControl, + ToggleControl, + privateApis as componentsPrivateApis, + __experimentalHStack as HStack, + Button, + FlexItem, +} from '@wordpress/components'; +import { useRef } from '@wordpress/element'; +import { moreVertical } from '@wordpress/icons'; + +/** + * Internal dependencies + */ +import { unlock } from '../../lock-unlock'; +const { + SizeControl, + DropdownMenuV2: DropdownMenu, + DropdownMenuItemV2: DropdownMenuItem, + DropdownMenuItemLabelV2: DropdownMenuItemLabel, +} = unlock( componentsPrivateApis ); +const { useGlobalSetting, useGlobalStyle } = unlock( blockEditorPrivateApis ); +import ScreenHeader from './header'; + +function FontSizePreview( { fontSize } ) { + const [ font ] = useGlobalStyle( 'typography' ); + return ( +
+ { __( 'Aa' ) } +
+ ); +} + +function FontSize() { + const { + params: { slug }, + goBack, + } = useNavigator(); + const [ fontSizes, setFontSizes ] = useGlobalSetting( + 'typography.fontSizes' + ); + // Get the font sizes from the theme or use the default ones. + const sizes = fontSizes.theme ?? fontSizes.default; + + // Get the font size by slug. + const fontSize = sizes.find( ( size ) => size.slug === slug ); + + const hasUnits = typeof fontSize.size === 'string'; + + // Whether fluid is true or an object, set it to true, otherwise false. + const isFluid = !! fontSize.fluid ?? false; + + // Whether custom fluid values are used. + const isCustomFluid = typeof fontSize.fluid === 'object'; + + // Initialize the ref with the prop value on the first render + const initialFontSizeRef = useRef( fontSize.size ); + + // Memoized initial value of fontSize + const initialFontSize = initialFontSizeRef.current; + + const handleNameChange = ( value ) => { + updateFontSize( 'name', value ); + }; + + const handleFontSizeChange = ( value ) => { + // If the user is resetting the value, use the initial value. + const newValue = value ?? initialFontSize; + updateFontSize( 'size', newValue ); + }; + + const handleFluidChange = ( value ) => { + const newValue = value === 'false' ? false : true; + updateFontSize( 'fluid', newValue ); + }; + + const handleCustomFluidValues = ( value ) => { + if ( value ) { + // If custom values are use init the values with the current ones. + updateFontSize( 'fluid', { + min: fontSize.size, + max: fontSize.size, + } ); + } else { + // If custom fluid values are disabled, set fluid to true. + updateFontSize( 'fluid', true ); + } + }; + + const handleMinChange = ( value ) => { + // If the user is resetting the value, use the initial value. + const newValue = value ?? fontSize.size; + updateFontSize( 'fluid', { ...fontSize.fluid, min: newValue } ); + }; + + const handleMaxChange = ( value ) => { + // If the user is resetting the value, use the initial value. + const newValue = value ?? fontSize.size; + updateFontSize( 'fluid', { ...fontSize.fluid, max: newValue } ); + }; + + const updateFontSize = ( key, value ) => { + const newFontSizes = sizes.map( ( size ) => { + if ( size.slug === slug ) { + return { ...size, [ key ]: value }; // Create a new object with updated key + } + return size; + } ); + + setFontSizes( { + ...fontSizes, + theme: newFontSizes, + } ); + }; + + const handleRemoveFontSize = () => { + // Navigate to the font sizes list. + goBack(); + + const newFontSizes = sizes.filter( ( size ) => size.slug !== slug ); + setFontSizes( { + ...fontSizes, + theme: newFontSizes, + } ); + }; + + return ( + <> + + + + + + } + > + + + { __( 'Remove font size' ) } + + + + + + + + + + + + + + + + + + + + + + + + + + + + { isFluid && ( + + + + ) } + + { isCustomFluid && ( + <> + + + + + + + + + ) } + + + ); +} + +export default FontSize; diff --git a/packages/edit-site/src/components/global-styles/font-sizes.js b/packages/edit-site/src/components/global-styles/font-sizes.js new file mode 100644 index 00000000000000..e5addf9bf58c0b --- /dev/null +++ b/packages/edit-site/src/components/global-styles/font-sizes.js @@ -0,0 +1,83 @@ +/** + * WordPress dependencies + */ +import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; +import { __, sprintf } from '@wordpress/i18n'; +import { + __experimentalItemGroup as ItemGroup, + __experimentalVStack as VStack, + __experimentalHStack as HStack, + FlexItem, + Button, + Tooltip, +} from '@wordpress/components'; +import { plus } from '@wordpress/icons'; + +/** + * Internal dependencies + */ +import { unlock } from '../../lock-unlock'; +const { useGlobalSetting } = unlock( blockEditorPrivateApis ); +import Subtitle from './subtitle'; +import { NavigationButtonAsItem } from './navigation-button'; + +function getAvailableIndex( sizes ) { + // Filter the slug field that ends with custom-{number}. + const indexes = sizes.map( ( size ) => { + const match = size.slug.match( /custom-(\d+)$/ ); + return match ? parseInt( match[ 1 ], 10 ) : 0; + } ); + return Math.max( ...indexes ) + 1; +} + +function FontSizes() { + const [ fontSizes, setFontSizes ] = useGlobalSetting( + 'typography.fontSizes' + ); + + // Get the font sizes from the theme or use the default ones. + const sizes = fontSizes.theme ?? fontSizes.default; + + const handleAddFontSize = () => { + const index = getAvailableIndex( sizes ); + const newFontSize = { + /* translators: %d: font size index */ + name: sprintf( __( 'New Font Size %d' ), index ), + size: '16px', + slug: `custom-${ index }`, + }; + + setFontSizes( { ...fontSizes, theme: [ ...sizes, newFontSize ] } ); + }; + + return ( + + + { __( 'Font Sizes' ) } + + +
+ + + +
+ + + ); +} + +export default RenameFontSizeDialog; From c59899e048c79a6353fcc5b48bce59e0e83efcd0 Mon Sep 17 00:00:00 2001 From: Matias Benedetto Date: Mon, 24 Jun 2024 13:13:11 +0400 Subject: [PATCH 27/38] polish props definition --- .../components/src/font-size-picker/index.tsx | 3 +- .../components/src/size-control/index.tsx | 59 +++++++++---------- packages/components/src/size-control/types.ts | 30 +++------- 3 files changed, 37 insertions(+), 55 deletions(-) diff --git a/packages/components/src/font-size-picker/index.tsx b/packages/components/src/font-size-picker/index.tsx index 9f6e0bf799fa88..46866eabcd40ec 100644 --- a/packages/components/src/font-size-picker/index.tsx +++ b/packages/components/src/font-size-picker/index.tsx @@ -185,8 +185,7 @@ const UnforwardedFontSizePicker = ( , ref: ForwardedRef< HTMLInputElement > ) { const { id, - __next40pxDefaultSize, + __next40pxDefaultSize = true, + __nextHasNoMarginBottom = true, value, - isDisabled, + disabled, size = 'default', units: unitsProp = DEFAULT_UNITS, withSlider = false, withReset = true, onChange, - hasUnits, fallbackValue, } = props; @@ -59,26 +59,35 @@ function UnforwardedBaseSizeControl( const isValueUnitRelative = !! valueUnit && [ 'em', 'rem', 'vw', 'vh' ].includes( valueUnit ); + const handleRangeChange = ( newValue: number | undefined ) => { + if ( newValue === undefined ) { + onChange?.( undefined ); + return; + } + onChange?.( newValue + ( valueUnit ?? 'px' ) ); + }; + + const handleUnitChange = ( newValue: string | undefined ) => { + if ( newValue === undefined ) { + onChange?.( undefined ); + } else { + onChange?.( valueUnit ? newValue : parseInt( newValue, 10 ) ); + } + }; + return ( { - if ( newValue === undefined ) { - onChange?.( undefined ); - } else { - onChange?.( - hasUnits ? newValue : parseInt( newValue, 10 ) - ); - } - } } + onChange={ handleUnitChange } size={ size } - units={ hasUnits ? units : [] } + units={ units } min={ 0 } /> @@ -87,25 +96,16 @@ function UnforwardedBaseSizeControl( { - if ( newValue === undefined ) { - onChange?.( undefined ); - } else if ( hasUnits ) { - onChange?.( - newValue + ( valueUnit ?? 'px' ) - ); - } else { - onChange?.( newValue ); - } - } } + onChange={ handleRangeChange } min={ 0 } max={ isValueUnitRelative ? 10 : 100 } step={ isValueUnitRelative ? 0.1 : 1 } @@ -117,16 +117,15 @@ function UnforwardedBaseSizeControl( { withReset && ( + disabled={ disabled } + label={ __( 'Custom' ) } + labelPosition="top" + hideLabelFromVision + value={ value } + onChange={ handleUnitChange } + size={ size } + units={ units } + min={ 0 } + /> - ) } - - ); -} - -const BaseSizeControl = forwardRef( UnforwardedBaseSizeControl ); - -function SizeControl( - props: WordPressComponentProps< SizeControlProps, 'input', true >, - ref: ForwardedRef< HTMLInputElement > -) { - const { baseControlProps } = useBaseControlProps( props ); - const instanceId = useInstanceId( SizeControl ); - const id = `size-control-${ instanceId }`; - return ( - - + { withSlider && ( + + + + + + ) } + { withReset && ( + + + + ) } + ); } -export default forwardRef( SizeControl ); +export default forwardRef( UnforwardedBaseSizeControl ); From ec3b35a462b844494bc3226ac216ecf6b9181f31 Mon Sep 17 00:00:00 2001 From: Matias Benedetto Date: Mon, 24 Jun 2024 13:42:10 +0400 Subject: [PATCH 29/38] add story for the SizeControl component --- .../src/size-control/stories/index.story.tsx | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 packages/components/src/size-control/stories/index.story.tsx diff --git a/packages/components/src/size-control/stories/index.story.tsx b/packages/components/src/size-control/stories/index.story.tsx new file mode 100644 index 00000000000000..44f05c3c440d44 --- /dev/null +++ b/packages/components/src/size-control/stories/index.story.tsx @@ -0,0 +1,90 @@ +/** + * External dependencies + */ +import type { Meta, StoryFn } from '@storybook/react'; +import { action } from '@storybook/addon-actions'; + +/** + * WordPress dependencies + */ +import { useState } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import SizeControl from '..'; +import type { SizeControlProps } from '../types'; + +const meta: Meta< typeof SizeControl > = { + title: 'Components (Experimental)/SizeControl', + tags: [ 'status-private' ], + component: SizeControl, + argTypes: { + value: { control: { type: null } }, + }, + parameters: { + actions: { argTypesRegex: '^on.*' }, + controls: { expanded: true }, + docs: { canvas: { sourceState: 'shown' } }, + }, +}; + +export default meta; + +const Template: StoryFn< typeof SizeControl > = ( args: SizeControlProps ) => { + const [ value, setValue ] = useState( args.value ); + + return ( + { + // If it's resetting, use the fallbackValue + const newValue = val ?? '16px'; + setValue( newValue ); + action( 'onChange' )( newValue ); + } } + /> + ); +}; + +export const Default = Template.bind( {} ); +Default.args = { + value: '16px', + withSlider: true, + withReset: true, + size: 'default', + units: [ 'px', 'em', 'rem', 'vw', 'vh' ], + label: 'Size Control Label', +}; + +export const Disabled = Template.bind( {} ); +Disabled.args = { + value: '16px', + withSlider: true, + withReset: true, + size: 'default', + units: [ 'px', 'em', 'rem', 'vw', 'vh' ], + disabled: true, + label: 'Size Control Label', +}; + +export const WithoutSlider = Template.bind( {} ); +WithoutSlider.args = { + value: '16px', + withSlider: false, + withReset: true, + size: 'default', + units: [ 'px', 'em', 'rem', 'vw', 'vh' ], + label: 'Size Control Label', +}; + +export const CustomUnits = Template.bind( {} ); +CustomUnits.args = { + value: '16%', + withSlider: true, + withReset: true, + size: 'default', + units: [ '%', 'em' ], + label: 'Size Control Label', +}; From cf56e161746846d0e43664a8b7e91f1baba97a0d Mon Sep 17 00:00:00 2001 From: Matias Benedetto Date: Mon, 24 Jun 2024 13:43:59 +0400 Subject: [PATCH 30/38] name export --- packages/components/src/size-control/index.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/components/src/size-control/index.tsx b/packages/components/src/size-control/index.tsx index 39bc6ab6e18881..975b14761474de 100644 --- a/packages/components/src/size-control/index.tsx +++ b/packages/components/src/size-control/index.tsx @@ -147,4 +147,6 @@ function UnforwardedBaseSizeControl( ); } -export default forwardRef( UnforwardedBaseSizeControl ); +const SizeControl = forwardRef( UnforwardedBaseSizeControl ); + +export default SizeControl; From e2e3b87b26d0204bbf56629e51bc110bd679c87e Mon Sep 17 00:00:00 2001 From: Matias Benedetto Date: Mon, 24 Jun 2024 13:45:43 +0400 Subject: [PATCH 31/38] improve naming --- packages/components/src/size-control/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/components/src/size-control/index.tsx b/packages/components/src/size-control/index.tsx index 975b14761474de..06c8bc0be385f1 100644 --- a/packages/components/src/size-control/index.tsx +++ b/packages/components/src/size-control/index.tsx @@ -29,13 +29,13 @@ import { Spacer } from '../spacer'; export const DEFAULT_UNITS = [ 'px', 'em', 'rem', 'vw', 'vh' ]; -function UnforwardedBaseSizeControl( +function UnforwardedSizeControl( props: WordPressComponentProps< SizeControlProps, 'input', true >, ref: ForwardedRef< HTMLInputElement > ) { const { baseControlProps } = useBaseControlProps( props ); - const instanceId = useInstanceId( UnforwardedBaseSizeControl ); + const instanceId = useInstanceId( UnforwardedSizeControl ); const id = `size-control-${ instanceId }`; const { @@ -147,6 +147,6 @@ function UnforwardedBaseSizeControl( ); } -const SizeControl = forwardRef( UnforwardedBaseSizeControl ); +const SizeControl = forwardRef( UnforwardedSizeControl ); export default SizeControl; From 9b27d215993351a99f6323b4522f1b314f9c1d73 Mon Sep 17 00:00:00 2001 From: Matias Benedetto Date: Mon, 24 Jun 2024 13:50:19 +0400 Subject: [PATCH 32/38] fix defaults --- packages/components/src/size-control/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/components/src/size-control/index.tsx b/packages/components/src/size-control/index.tsx index 06c8bc0be385f1..7201c7100714f1 100644 --- a/packages/components/src/size-control/index.tsx +++ b/packages/components/src/size-control/index.tsx @@ -45,8 +45,8 @@ function UnforwardedSizeControl( disabled, size = 'default', units: unitsProp = DEFAULT_UNITS, - withSlider = false, - withReset = true, + withSlider = true, + withReset = false, onChange, fallbackValue, } = props; From 47d07630c8a6026c7e0e905c5222d5a708fa97d4 Mon Sep 17 00:00:00 2001 From: Matias Benedetto Date: Mon, 24 Jun 2024 14:25:15 +0400 Subject: [PATCH 33/38] improving storybook --- packages/components/src/size-control/index.tsx | 2 +- .../src/size-control/stories/index.story.tsx | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/components/src/size-control/index.tsx b/packages/components/src/size-control/index.tsx index 7201c7100714f1..45fe63d96310e4 100644 --- a/packages/components/src/size-control/index.tsx +++ b/packages/components/src/size-control/index.tsx @@ -147,6 +147,6 @@ function UnforwardedSizeControl( ); } -const SizeControl = forwardRef( UnforwardedSizeControl ); +export const SizeControl = forwardRef( UnforwardedSizeControl ); export default SizeControl; diff --git a/packages/components/src/size-control/stories/index.story.tsx b/packages/components/src/size-control/stories/index.story.tsx index 44f05c3c440d44..1c11825f95901e 100644 --- a/packages/components/src/size-control/stories/index.story.tsx +++ b/packages/components/src/size-control/stories/index.story.tsx @@ -51,8 +51,6 @@ const Template: StoryFn< typeof SizeControl > = ( args: SizeControlProps ) => { export const Default = Template.bind( {} ); Default.args = { value: '16px', - withSlider: true, - withReset: true, size: 'default', units: [ 'px', 'em', 'rem', 'vw', 'vh' ], label: 'Size Control Label', @@ -61,11 +59,18 @@ Default.args = { export const Disabled = Template.bind( {} ); Disabled.args = { value: '16px', - withSlider: true, - withReset: true, size: 'default', units: [ 'px', 'em', 'rem', 'vw', 'vh' ], + label: 'Size Control Label', disabled: true, +}; + +export const WithReset = Template.bind( {} ); +WithReset.args = { + value: '16px', + withReset: true, + size: 'default', + units: [ 'px', 'em', 'rem', 'vw', 'vh' ], label: 'Size Control Label', }; @@ -73,7 +78,6 @@ export const WithoutSlider = Template.bind( {} ); WithoutSlider.args = { value: '16px', withSlider: false, - withReset: true, size: 'default', units: [ 'px', 'em', 'rem', 'vw', 'vh' ], label: 'Size Control Label', @@ -82,8 +86,6 @@ WithoutSlider.args = { export const CustomUnits = Template.bind( {} ); CustomUnits.args = { value: '16%', - withSlider: true, - withReset: true, size: 'default', units: [ '%', 'em' ], label: 'Size Control Label', From cfd061917ce40ba99cd358820bfc04f150810eaa Mon Sep 17 00:00:00 2001 From: Matias Benedetto Date: Mon, 24 Jun 2024 16:22:16 +0400 Subject: [PATCH 34/38] removing unwanted prop --- packages/components/src/font-size-picker/index.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/components/src/font-size-picker/index.tsx b/packages/components/src/font-size-picker/index.tsx index 46866eabcd40ec..2574c1d84fd6dd 100644 --- a/packages/components/src/font-size-picker/index.tsx +++ b/packages/components/src/font-size-picker/index.tsx @@ -94,8 +94,6 @@ const UnforwardedFontSizePicker = ( const hasUnits = typeof value === 'string' || typeof fontSizes[ 0 ]?.size === 'string'; - const isDisabled = value === undefined; - return ( { __( 'Font size' ) } @@ -185,7 +183,6 @@ const UnforwardedFontSizePicker = ( Date: Wed, 26 Jun 2024 02:13:13 +0400 Subject: [PATCH 35/38] add the ability to pass hasUnit as a prop --- .../components/src/font-size-picker/index.tsx | 1 + .../components/src/font-size-picker/types.ts | 2 +- .../components/src/size-control/index.tsx | 32 ++++++++++++------- packages/components/src/size-control/types.ts | 6 ++++ 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/packages/components/src/font-size-picker/index.tsx b/packages/components/src/font-size-picker/index.tsx index 2574c1d84fd6dd..2a87bb497d3446 100644 --- a/packages/components/src/font-size-picker/index.tsx +++ b/packages/components/src/font-size-picker/index.tsx @@ -184,6 +184,7 @@ const UnforwardedFontSizePicker = ( __next40pxDefaultSize={ __next40pxDefaultSize } value={ value } units={ units } + hasUnit={ hasUnits } withSlider={ withSlider } withReset={ withReset } fallbackValue={ fallbackFontSize } diff --git a/packages/components/src/font-size-picker/types.ts b/packages/components/src/font-size-picker/types.ts index 918631e7cd236c..109b8af47f2a2e 100644 --- a/packages/components/src/font-size-picker/types.ts +++ b/packages/components/src/font-size-picker/types.ts @@ -5,7 +5,7 @@ import type { SizeControlBaseProps, Size } from '../size-control/types'; export type FontSizePickerProps = Omit< SizeControlBaseProps, - 'fallbackValue' + 'fallbackValue' | 'hasUnit' > & { /** * If `true`, it will not be possible to choose a custom fontSize. The user diff --git a/packages/components/src/size-control/index.tsx b/packages/components/src/size-control/index.tsx index 45fe63d96310e4..8380a8703afed9 100644 --- a/packages/components/src/size-control/index.tsx +++ b/packages/components/src/size-control/index.tsx @@ -41,6 +41,7 @@ function UnforwardedSizeControl( const { __next40pxDefaultSize = true, __nextHasNoMarginBottom = true, + hasUnit = true, value, disabled, size = 'default', @@ -59,24 +60,31 @@ function UnforwardedSizeControl( value, units ); - const isValueUnitRelative = !! valueUnit && [ 'em', 'rem', 'vw', 'vh' ].includes( valueUnit ); - const handleRangeChange = ( newValue: number | undefined ) => { + const handleValueChange = ( newValue: string | number | undefined ) => { + // On Reset if ( newValue === undefined ) { onChange?.( undefined ); return; } - onChange?.( newValue + ( valueUnit ?? 'px' ) ); - }; - const handleUnitChange = ( newValue: string | undefined ) => { - if ( newValue === undefined ) { - onChange?.( undefined ); - } else { - onChange?.( valueUnit ? newValue : parseInt( newValue, 10 ) ); + // If the component is initalized as a unitless value (for retrocompatibility) + if ( ! hasUnit ) { + onChange?.( parseInt( String( newValue ), 10 ) ); + return; } + + // Parse the new value and unit. + const [ newQuantity, newUnit ] = parseQuantityAndUnitFromRawValue( + newValue, + units + ); + onChange?.( + // If the new value is empty or couldn't be parsed, pass the raw value received. + newQuantity ? newQuantity + ( newUnit ?? 'px' ) : newValue + ); }; return ( @@ -91,7 +99,7 @@ function UnforwardedSizeControl( labelPosition="top" hideLabelFromVision value={ value } - onChange={ handleUnitChange } + onChange={ handleValueChange } size={ size } units={ units } min={ 0 } @@ -112,7 +120,7 @@ function UnforwardedSizeControl( value={ valueQuantity } initialPosition={ fallbackValue } withInputField={ false } - onChange={ handleRangeChange } + onChange={ handleValueChange } min={ 0 } max={ isValueUnitRelative ? 10 : 100 } step={ isValueUnitRelative ? 0.1 : 1 } @@ -124,7 +132,7 @@ function UnforwardedSizeControl( { withReset && (