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

Font size presets UI #62328

Closed
wants to merge 41 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
b8e83e3
move font size picker custom control to a new component
matiasbenedetto Jun 5, 2024
107ea70
move props to the inner component
matiasbenedetto Jun 5, 2024
4d55771
renaming and moving the custom size control to its own folder
matiasbenedetto Jun 7, 2024
19307c0
implement font size management UI
matiasbenedetto Jun 10, 2024
8465ece
re-use getNewIndexFromPresets
matiasbenedetto Jun 13, 2024
a3a97d9
tooltip text
matiasbenedetto Jun 17, 2024
0b6c490
update wording
matiasbenedetto Jun 17, 2024
239b781
replace Spacer components by VStack
matiasbenedetto Jun 17, 2024
647ff41
remove reset buttons
matiasbenedetto Jun 17, 2024
82223d9
add base control to size control
matiasbenedetto Jun 18, 2024
9e05bac
use useBaseControlProps
matiasbenedetto Jun 18, 2024
429fbec
use toggle control
matiasbenedetto Jun 18, 2024
45de557
update class names
matiasbenedetto Jun 18, 2024
fb2f13c
update wording
matiasbenedetto Jun 18, 2024
3144e78
normalize and order font sizes. Add styles to avoid multi-line
matiasbenedetto Jun 19, 2024
1601b57
Merge branch 'trunk' into add/font-size-presets-ui
matiasbenedetto Jun 19, 2024
060826f
remove tooltip
matiasbenedetto Jun 20, 2024
9a68e97
fix comment
matiasbenedetto Jun 20, 2024
73617a8
remove style accidentally added with merging trunk branch
matiasbenedetto Jun 20, 2024
0c8ecde
fix mispelled words in labels
matiasbenedetto Jun 20, 2024
55d4b40
add control style props
matiasbenedetto Jun 20, 2024
1b021cc
Merge branch 'trunk' into add/font-size-presets-ui
matiasbenedetto Jun 20, 2024
f07b87e
undo readme link change
matiasbenedetto Jun 20, 2024
92d9264
empty array as fallback value
matiasbenedetto Jun 20, 2024
cc582db
removes the reset related logic
matiasbenedetto Jun 20, 2024
c42f120
adding __nextHasNoMarginBottom to ToggleControl components
matiasbenedetto Jun 21, 2024
b8c4dfa
adding confirm dialog to remove font size
matiasbenedetto Jun 21, 2024
a9b0d2c
add rename modal
matiasbenedetto Jun 21, 2024
c59899e
polish props definition
matiasbenedetto Jun 24, 2024
e82cee4
simplify the component and fix the use of id prop
matiasbenedetto Jun 24, 2024
ec3b35a
add story for the SizeControl component
matiasbenedetto Jun 24, 2024
cf56e16
name export
matiasbenedetto Jun 24, 2024
e2e3b87
improve naming
matiasbenedetto Jun 24, 2024
9b27d21
fix defaults
matiasbenedetto Jun 24, 2024
47d0763
improving storybook
matiasbenedetto Jun 24, 2024
cfd0619
removing unwanted prop
matiasbenedetto Jun 24, 2024
7bbfeac
add the ability to pass hasUnit as a prop
matiasbenedetto Jun 25, 2024
62f2f20
withReset default true
matiasbenedetto Jun 25, 2024
6ce12d7
tweak the defaults
matiasbenedetto Jun 25, 2024
499a6e4
adding unit tests for SizeControl
matiasbenedetto Jun 25, 2024
86df1e2
Merge branch 'trunk' into add/font-size-presets-ui
matiasbenedetto Jun 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 12 additions & 102 deletions packages/components/src/font-size-picker/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,6 @@ 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';
import { VisuallyHidden } from '../visually-hidden';
import { getCommonSizeUnit } from './utils';
import type { FontSizePickerProps } from './types';
Expand All @@ -34,10 +26,9 @@ import {
import { Spacer } from '../spacer';
import FontSizePickerSelect from './font-size-picker-select';
import FontSizePickerToggleGroup from './font-size-picker-toggle-group';
import SizeControl, { DEFAULT_UNITS } from '../size-control';
import { T_SHIRT_NAMES } from './constants';

const DEFAULT_UNITS = [ 'px', 'em', 'rem', 'vw', 'vh' ];

const UnforwardedFontSizePicker = (
props: FontSizePickerProps,
ref: ForwardedRef< any >
Expand All @@ -49,16 +40,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
Expand Down Expand Up @@ -107,14 +94,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 (
<Container ref={ ref } className="components-font-size-picker">
<VisuallyHidden as="legend">{ __( 'Font size' ) }</VisuallyHidden>
Expand Down Expand Up @@ -201,85 +180,16 @@ const UnforwardedFontSizePicker = (
/>
) }
{ ! disableCustomFontSizes && showCustomValueControl && (
<Flex className="components-font-size-picker__custom-size-control">
<FlexItem isBlock>
<UnitControl
__next40pxDefaultSize={ __next40pxDefaultSize }
label={ __( 'Custom' ) }
labelPosition="top"
hideLabelFromVision
value={ value }
onChange={ ( newValue ) => {
if ( newValue === undefined ) {
onChange?.( undefined );
} else {
onChange?.(
hasUnits
? newValue
: parseInt( newValue, 10 )
);
}
} }
size={ size }
units={ hasUnits ? units : [] }
min={ 0 }
/>
</FlexItem>
{ withSlider && (
<FlexItem isBlock>
<Spacer marginX={ 2 } marginBottom={ 0 }>
<RangeControl
__nextHasNoMarginBottom
__next40pxDefaultSize={
__next40pxDefaultSize
}
className="components-font-size-picker__custom-input"
label={ __( 'Custom Size' ) }
hideLabelFromVision
value={ valueQuantity }
initialPosition={ fallbackFontSize }
withInputField={ false }
onChange={ ( newValue ) => {
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 }
/>
</Spacer>
</FlexItem>
) }
{ withReset && (
<FlexItem>
<Button
disabled={ isDisabled }
__experimentalIsFocusable
onClick={ () => {
onChange?.( undefined );
} }
variant="secondary"
__next40pxDefaultSize
size={
size === '__unstable-large' ||
props.__next40pxDefaultSize
? 'default'
: 'small'
}
>
{ __( 'Reset' ) }
</Button>
</FlexItem>
) }
</Flex>
<SizeControl
__next40pxDefaultSize={ __next40pxDefaultSize }
value={ value }
units={ units }
hasUnit={ hasUnits }
withSlider={ withSlider }
withReset={ withReset }
fallbackValue={ fallbackFontSize }
onChange={ onChange }
/>
) }
</div>
</Container>
Expand Down
8 changes: 4 additions & 4 deletions packages/components/src/font-size-picker/test/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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( [
Expand Down Expand Up @@ -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(
<FontSizePicker
Expand All @@ -501,7 +501,7 @@ describe( 'FontSizePicker', () => {
);
}

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();
Expand All @@ -519,7 +519,7 @@ describe( 'FontSizePicker', () => {
} );
}

function commonTests( fontSizes: FontSize[] ) {
function commonTests( fontSizes: Size[] ) {
it( 'shows custom input when value is unknown', () => {
render( <FontSizePicker fontSizes={ fontSizes } value="3px" /> );
expect( screen.getByLabelText( 'Custom' ) ).toBeInTheDocument();
Expand Down
89 changes: 11 additions & 78 deletions packages/components/src/font-size-picker/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
export type FontSizePickerProps = {
/**
* Internal dependencies
*/
import type { SizeControlBaseProps, Size } from '../size-control/types';

export type FontSizePickerProps = Omit<
SizeControlBaseProps,
'fallbackValue' | 'hasUnit'
> & {
/**
* 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.
Expand All @@ -15,82 +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 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<
Expand All @@ -109,7 +42,7 @@ export type FontSizePickerSelectProps = Pick<
export type FontSizePickerSelectOption = {
key: string;
name: string;
value?: FontSize[ 'size' ];
value?: Size[ 'size' ];
__experimentalHint?: string;
};

Expand Down
5 changes: 3 additions & 2 deletions packages/components/src/font-size-picker/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand All @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions packages/components/src/private-apis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
DropdownMenuItemLabel as DropdownMenuItemLabelV2,
DropdownMenuItemHelpText as DropdownMenuItemHelpTextV2,
} from './dropdown-menu-v2';
import SizeControl from './size-control';
import { ComponentsContext } from './context/context-system-provider';
import Theme from './theme';
import Tabs from './tabs';
Expand Down Expand Up @@ -53,5 +54,6 @@ lock( privateApis, {
DropdownMenuSeparatorV2,
DropdownMenuItemLabelV2,
DropdownMenuItemHelpTextV2,
SizeControl,
kebabCase,
} );
Loading
Loading