Skip to content

Commit

Permalink
Move HeadinglevelDropdown to its own component (#46003)
Browse files Browse the repository at this point in the history
* Add a tag selection component for the block toolbar (replaces HeadingLevelDropdown)

* Update index.php

* update fixtures

* Update CSS class, replace sprintf in the label with the tag name

* Add visible tag name to the drop down, add placeholder icon

* Update README.md

* Try to fix issue with the deprecation

* Update CHANGELOG.md

* Simplify and rename component

* Try reverting fixture changes

* And again...

* Update Query title to use the new component

* Update Comments title

* Update Site title with paragraph exception

* Update Heading block

* Update rich-text.test.js

* Block Heading Dropdown - Add support for mobile (#47967)

* Text changes for a native file and e2e test spec

* Use the updated headingLevel icons

* Update prop names

* Add 'options' property to type definiton

---------

Co-authored-by: Gerardo Pacheco <[email protected]>
Co-authored-by: George Mamadashvili <[email protected]>
  • Loading branch information
3 people authored Jun 20, 2023
1 parent 4bde6ab commit 2875c37
Show file tree
Hide file tree
Showing 18 changed files with 157 additions and 105 deletions.
6 changes: 6 additions & 0 deletions packages/block-editor/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

## Unreleased

### Enhancements

- Add `HeadingLevelDropdown` component for selecting H1-H6 and paragraph HTML tags from the block toolbar.

### Bug Fix

- Fluid typography: custom font-sizes should use max viewport width ([#51516](https://github.com/WordPress/gutenberg/pull/51516)).


## 12.3.0 (2023-06-07)

## 12.2.0 (2023-05-24)
Expand All @@ -22,6 +27,7 @@

## 11.8.0 (2023-04-12)


## 11.7.0 (2023-03-29)

- `ImageSizeControl`: Update image size label ([#49112](https://github.com/WordPress/gutenberg/pull/49112)).
Expand Down
12 changes: 12 additions & 0 deletions packages/block-editor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,18 @@ _Returns_

- `Object`: Typography block support derived CSS classes & styles.

### HeadingLevelDropdown

Dropdown for selecting a heading level (1 through 6) or paragraph (0).

_Parameters_

- _props_ `WPHeadingLevelDropdownProps`: Component props.

_Returns_

- `WPComponent`: The toolbar.

### HeightControl

HeightControl renders a linked unit control and range control for adjusting the height of a block.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Heading Level Dropdown

`<HeadingLevelDropdown>` Adds a dropdown for selecting H1-H6 and paragraph HTML tags from the block toolbar.
Uses `<ToolbarDropdownMenu>`.

## Usage

```jsx

import { BlockControls, HeadingLevelDropdown } from '@wordpress/block-editor';

const HEADING_LEVELS = [ 0, 1, 2, 3, 4, 5, 6 ];

const MyHeadingLevelToolbar = () => (
<BlockControls group="block">
<HeadingLevelDropdown
options={ HEADING_LEVELS }
value={ tag }
onChange={ ( newTag ) =>
setAttributes( { tag: newTag } )
}
/>
</BlockControls>
);
```

### Props

#### options

The list of available HTML tags, passed from the block.

- Type: `Object`
- Required: no

#### value

The chosen HTML tag.

- Type: `string`
- Required: no

#### onChange

Callback to run when toolbar value is changed.

- Type: `string`
- Required: yes

## Related components

Block Editor components are components that can be used to compose the UI of your block editor. Thus, they can only be used under a [`BlockEditorProvider`](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/provider/README.md) in the components tree.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* WordPress dependencies
*/
import {
headingLevel1,
headingLevel2,
headingLevel3,
headingLevel4,
headingLevel5,
headingLevel6,
paragraph,
} from '@wordpress/icons';

/** @typedef {import('@wordpress/element').WPComponent} WPComponent */

/**
* HeadingLevelIcon props.
*
* @typedef WPHeadingLevelIconProps
*
* @property {number} level The heading level to show an icon for.
*/

const LEVEL_TO_PATH = {
0: paragraph,
1: headingLevel1,
2: headingLevel2,
3: headingLevel3,
4: headingLevel4,
5: headingLevel5,
6: headingLevel6,
};

/**
* Heading level icon.
*
* @param {WPHeadingLevelIconProps} props Component props.
*
* @return {?WPComponent} The icon.
*/
export default function HeadingLevelIcon( { level } ) {
return LEVEL_TO_PATH[ level ] ?? null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,32 @@ const POPOVER_PROPS = {
*
* @typedef WPHeadingLevelDropdownProps
*
* @property {number} selectedLevel The chosen heading level.
* @property {(newValue:number)=>any} onChange Callback to run when
* toolbar value is changed.
* @property {number} value The chosen heading level.
* @property {number[]} options An array of supported heading levels.
* @property {(newValue:number)=>any} onChange Callback to run when
* toolbar value is changed.
*/

/**
* Dropdown for selecting a heading level (1 through 6).
* Dropdown for selecting a heading level (1 through 6) or paragraph (0).
*
* @param {WPHeadingLevelDropdownProps} props Component props.
*
* @return {WPComponent} The toolbar.
*/
export default function HeadingLevelDropdown( { selectedLevel, onChange } ) {
export default function HeadingLevelDropdown( {
options = HEADING_LEVELS,
value,
onChange,
} ) {
return (
<ToolbarDropdownMenu
popoverProps={ POPOVER_PROPS }
icon={ <HeadingLevelIcon level={ selectedLevel } /> }
label={ __( 'Change heading level' ) }
controls={ HEADING_LEVELS.map( ( targetLevel ) => {
icon={ <HeadingLevelIcon level={ value } /> }
label={ __( 'Change level' ) }
controls={ options.map( ( targetLevel ) => {
{
const isActive = targetLevel === selectedLevel;
const isActive = targetLevel === value;

return {
icon: (
Expand All @@ -51,11 +56,14 @@ export default function HeadingLevelDropdown( { selectedLevel, onChange } ) {
isPressed={ isActive }
/>
),
label: sprintf(
// translators: %s: heading level e.g: "1", "2", "3"
__( 'Heading %d' ),
targetLevel
),
label:
targetLevel === 0
? __( 'Paragraph' )
: sprintf(
// translators: %s: heading level e.g: "1", "2", "3"
__( 'Heading %d' ),
targetLevel
),
isActive,
onClick() {
onChange( targetLevel );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export default function HeadingLevelDropdown( { selectedLevel, onChange } ) {
controls={ HEADING_LEVELS.map( ( index ) =>
createLevelControl( index, selectedLevel, onChange )
) }
label={ __( 'Change heading level' ) }
label={ __( 'Change level' ) }
/>
);
}
1 change: 1 addition & 0 deletions packages/block-editor/src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export { default as BlockEdit, useBlockEditContext } from './block-edit';
export { default as BlockIcon } from './block-icon';
export { default as BlockNavigationDropdown } from './block-navigation/dropdown';
export { default as BlockStyles } from './block-styles';
export { default as HeadingLevelDropdown } from './block-heading-level-dropdown';
export { default as __experimentalBlockVariationPicker } from './block-variation-picker';
export { default as __experimentalBlockPatternSetup } from './block-pattern-setup';
export { default as __experimentalBlockVariationTransforms } from './block-variation-transforms';
Expand Down
1 change: 1 addition & 0 deletions packages/block-editor/src/components/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export {
JustifyContentControl,
} from './justify-content-control';
export { default as LineHeightControl } from './line-height-control';
export { default as HeadingLevelDropdown } from './block-heading-level-dropdown';
export { default as PlainText } from './plain-text';
export {
default as RichText,
Expand Down
8 changes: 2 additions & 6 deletions packages/block-library/src/comments-title/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
useBlockProps,
InspectorControls,
store as blockEditorStore,
HeadingLevelDropdown,
} from '@wordpress/block-editor';
import { __, _n, sprintf } from '@wordpress/i18n';
import { useEntityProp } from '@wordpress/core-data';
Expand All @@ -21,11 +22,6 @@ import { useSelect } from '@wordpress/data';
import apiFetch from '@wordpress/api-fetch';
import { addQueryArgs } from '@wordpress/url';

/**
* Internal dependencies
*/
import HeadingLevelDropdown from '../heading/heading-level-dropdown';

export default function Edit( {
attributes: { textAlign, showPostTitle, showCommentsCount, level },
setAttributes,
Expand Down Expand Up @@ -98,7 +94,7 @@ export default function Edit( {
}
/>
<HeadingLevelDropdown
selectedLevel={ level }
value={ level }
onChange={ ( newLevel ) =>
setAttributes( { level: newLevel } )
}
Expand Down
4 changes: 2 additions & 2 deletions packages/block-library/src/heading/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ import {
RichText,
useBlockProps,
store as blockEditorStore,
HeadingLevelDropdown,
} from '@wordpress/block-editor';

/**
* Internal dependencies
*/
import HeadingLevelDropdown from './heading-level-dropdown';
import { generateAnchor, setAnchor } from './autogenerate-anchors';

function HeadingEdit( {
Expand Down Expand Up @@ -92,7 +92,7 @@ function HeadingEdit( {
<>
<BlockControls group="block">
<HeadingLevelDropdown
selectedLevel={ level }
value={ level }
onChange={ ( newLevel ) =>
setAttributes( { level: newLevel } )
}
Expand Down
6 changes: 3 additions & 3 deletions packages/block-library/src/post-title/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
InspectorControls,
useBlockProps,
PlainText,
HeadingLevelDropdown,
privateApis as blockEditorPrivateApis,
} from '@wordpress/block-editor';
import { ToggleControl, TextControl, PanelBody } from '@wordpress/components';
Expand All @@ -22,7 +23,6 @@ import { useEntityProp } from '@wordpress/core-data';
/**
* Internal dependencies
*/
import HeadingLevelDropdown from '../heading/heading-level-dropdown';
import { useCanEditEntity } from '../utils/hooks';
import { unlock } from '../lock-unlock';

Expand All @@ -34,7 +34,7 @@ export default function PostTitleEdit( {
context: { postType, postId, queryId },
insertBlocksAfter,
} ) {
const TagName = 0 === level ? 'p' : 'h' + level;
const TagName = 'h' + level;
const isDescendentOfQueryLoop = Number.isFinite( queryId );
/**
* Hack: useCanEditEntity may trigger an OPTIONS request to the REST API via the canUser resolver.
Expand Down Expand Up @@ -120,7 +120,7 @@ export default function PostTitleEdit( {
{ blockEditingMode === 'default' && (
<BlockControls group="block">
<HeadingLevelDropdown
selectedLevel={ level }
value={ level }
onChange={ ( newLevel ) =>
setAttributes( { level: newLevel } )
}
Expand Down
2 changes: 1 addition & 1 deletion packages/block-library/src/post-title/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function render_block_core_post_title( $attributes, $content, $block ) {

$tag_name = 'h2';
if ( isset( $attributes['level'] ) ) {
$tag_name = 0 === $attributes['level'] ? 'p' : 'h' . $attributes['level'];
$tag_name = 'h' . $attributes['level'];
}

if ( isset( $attributes['isLink'] ) && $attributes['isLink'] ) {
Expand Down
8 changes: 2 additions & 6 deletions packages/block-library/src/query-title/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,11 @@ import {
InspectorControls,
useBlockProps,
Warning,
HeadingLevelDropdown,
} from '@wordpress/block-editor';
import { ToggleControl, PanelBody } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import HeadingLevelDropdown from '../heading/heading-level-dropdown';

const SUPPORTED_TYPES = [ 'archive', 'search' ];

export default function QueryTitleEdit( {
Expand Down Expand Up @@ -98,7 +94,7 @@ export default function QueryTitleEdit( {
<>
<BlockControls group="block">
<HeadingLevelDropdown
selectedLevel={ level }
value={ level }
onChange={ ( newLevel ) =>
setAttributes( { level: newLevel } )
}
Expand Down
11 changes: 5 additions & 6 deletions packages/block-library/src/site-title/edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,13 @@ import {
InspectorControls,
BlockControls,
useBlockProps,
HeadingLevelDropdown,
} from '@wordpress/block-editor';
import { ToggleControl, PanelBody } from '@wordpress/components';
import { createBlock, getDefaultBlockName } from '@wordpress/blocks';
import { decodeEntities } from '@wordpress/html-entities';

/**
* Internal dependencies
*/
import LevelControl from './level-toolbar';
const HEADING_LEVELS = [ 0, 1, 2, 3, 4, 5, 6 ];

export default function SiteTitleEdit( {
attributes,
Expand Down Expand Up @@ -95,8 +93,9 @@ export default function SiteTitleEdit( {
return (
<>
<BlockControls group="block">
<LevelControl
level={ level }
<HeadingLevelDropdown
options={ HEADING_LEVELS }
value={ level }
onChange={ ( newLevel ) =>
setAttributes( { level: newLevel } )
}
Expand Down
Loading

1 comment on commit 2875c37

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flaky tests detected in 2875c37.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/5321926187
📝 Reported issues:

Please sign in to comment.