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

Add Details/summary block #45055

Merged
merged 53 commits into from
Apr 6, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
be21b7f
Add "details" block
carolinan Oct 18, 2022
9686338
Add variation, fix stylesheet loading on front, change font size
carolinan Oct 18, 2022
ed02fa7
Remove the link option from the summary heading, update aria label
carolinan Oct 18, 2022
340fe0e
Update edit.js
carolinan Oct 18, 2022
7468272
Keep the details open in the editor
carolinan Oct 20, 2022
04b8f85
Add toolbar control for collapsing and expanding the details, remove …
carolinan Oct 21, 2022
80375c0
Update fixtures
carolinan Oct 21, 2022
84ede00
Update style.scss
carolinan Oct 21, 2022
843ab63
re-add the font size for the heading
carolinan Oct 21, 2022
3c2397f
Remove font size limitations
carolinan Oct 27, 2022
8810fb0
Update cursor to pointer.
carolinan Oct 27, 2022
82ce6b0
Add aria label that announces the expanded or collapsed state
carolinan Oct 27, 2022
b56a2a7
Remove transcript variation, add keywords
carolinan Oct 31, 2022
26b07c4
Open the details when the block is selected
carolinan Nov 4, 2022
14d6974
Update edit.js
carolinan Nov 4, 2022
125b246
Add a basic unwrap
carolinan Nov 4, 2022
82643c4
Update edit.js
carolinan Nov 5, 2022
10ffe31
Merge branch 'trunk' into add/details-summary-block
carolinan Nov 7, 2022
c75a4aa
Try using separate blocks
carolinan Nov 8, 2022
bc421cc
Update summary text, descriptions and fixtures
carolinan Nov 8, 2022
bd3474a
Update edit.js
carolinan Nov 9, 2022
19cf689
remove transform and editor style.
carolinan Nov 9, 2022
a7c05f2
update icons.
carolinan Nov 9, 2022
c31508c
Limit the inner blocks to one inside the Details block
carolinan Nov 10, 2022
4aef03e
Remove the alignments from the inner blocks, and prevent them from be…
carolinan Nov 10, 2022
0297f7d
Update index.js
carolinan Nov 11, 2022
a1698ee
Merge branch 'trunk' into add/details-summary-block
carolinan Dec 16, 2022
98ee1ee
Merge branch 'trunk' into add/details-summary-block
carolinan Dec 30, 2022
b740036
Merge branch 'trunk' into add/details-summary-block
carolinan Feb 8, 2023
d72a333
Add the icon
carolinan Feb 13, 2023
95482f0
Try to apply font size to the heading inside summary
carolinan Feb 13, 2023
3e2cd78
Update fixtures
carolinan Feb 13, 2023
d4b3923
Remove the allowed formatting from the RichText
carolinan Feb 17, 2023
767c4a2
Merge branch 'trunk' into add/details-summary-block
carolinan Feb 17, 2023
8146396
Merge branch 'trunk' into add/details-summary-block
carolinan Feb 21, 2023
89a07cf
Merge branch 'trunk' into add/details-summary-block
carolinan Feb 28, 2023
cb2a3d8
Try the experimentalSelector and skipSerialization again
carolinan Feb 28, 2023
7dc6665
Merge branch 'trunk' into add/details-summary-block
carolinan Mar 1, 2023
460041a
Remove heading from Summary
carolinan Mar 1, 2023
c923448
Merge branch 'trunk' into add/details-summary-block
carolinan Mar 2, 2023
ff578c2
Rename the block, update CSS.
carolinan Mar 3, 2023
52a404c
Update style.scss
carolinan Mar 3, 2023
c9382af
Change the category to text
carolinan Mar 3, 2023
64be240
Merge branch 'trunk' into add/details-summary-block
carolinan Mar 13, 2023
492ad92
Remove unsupported marker CSS
carolinan Mar 13, 2023
90f5249
fix background clipping and update description
carolinan Mar 13, 2023
731a8e8
Replace inner div with View primitive
carolinan Mar 13, 2023
eb47efc
Merge branch 'trunk' into add/details-summary-block
carolinan Mar 30, 2023
597f6b6
Remove View from save.js
carolinan Mar 31, 2023
772a334
Remove translation from save.js
carolinan Mar 31, 2023
2a3b19b
Make the block opt-in, available from the Experiments page.
carolinan Mar 31, 2023
995102f
Merge branch 'trunk' into add/details-summary-block
carolinan Apr 4, 2023
9edd68e
remove fixtures
carolinan Apr 4, 2023
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
9 changes: 9 additions & 0 deletions docs/reference-guides/core-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,15 @@ Add an image or video with a text overlay — great for headers. ([Source](https
- **Supports:** align, anchor, color (~~background~~, ~~text~~), spacing (margin, padding), typography (fontSize, lineHeight), ~~html~~
- **Attributes:** allowedBlocks, alt, backgroundType, contentPosition, customGradient, customOverlayColor, dimRatio, focalPoint, gradient, hasParallax, id, isDark, isRepeated, minHeight, minHeightUnit, overlayColor, templateLock, url, useFeaturedImage

## Details

An advanced block that allows displaying a summary and hiding and displaying detailed content. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/details))

- **Name:** core/details
- **Category:** theme
- **Supports:** align, color (background, gradients, link, text), spacing (margin, padding), typography (fontSize, lineHeight), ~~html~~
- **Attributes:** level, showContent, summary

## Embed

Add a block that displays content pulled from other sites, like Twitter or YouTube. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/embed))
Expand Down
1 change: 1 addition & 0 deletions lib/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ function gutenberg_reregister_core_block_types() {
'column',
'columns',
'comments',
'details',
'group',
'heading',
'html',
Expand Down
63 changes: 63 additions & 0 deletions packages/block-library/src/details/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"__experimental": true,
"name": "core/details",
"title": "Details",
"category": "theme",
"description": "An advanced block that allows displaying a summary and hiding and displaying detailed content.",
carolinan marked this conversation as resolved.
Show resolved Hide resolved
"textdomain": "default",
"attributes": {
"level": {
"type": "number",
"default": 2
},
"summary": {
"type": "string",
"source": "html",
"selector": "h1,h2,h3,h4,h5,h6"
},
"showContent": {
"type": "boolean",
"default": true
}
},
"supports": {
"align": true,
"color": {
"gradients": true,
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true,
"link": true
}
},
"__experimentalBorder": {
"radius": true,
"color": true,
"width": true,
"style": true
},
Comment on lines +28 to +33
Copy link
Contributor

Choose a reason for hiding this comment

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

There's a small disparity between the editor and frontend when using border radius:

Editor

Screen Shot 2023-04-05 at 4 47 49 pm

Frontend

Screen Shot 2023-04-05 at 4 47 41 pm

It's something that can be fixed in a follow-up and shouldn't block merging.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am trying to reproduce this.
I am using Twenty Twenty-Three.

  • I added a border with border-radius on the Details.
  • Padding, preset 1 , on the summary and content.
  • A background color on the summary.

I do not see the clipping on macOS, in Firefox, Safari, or Chrome

Copy link
Contributor

@talldan talldan Apr 11, 2023

Choose a reason for hiding this comment

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

This seems to work now too:
Screen Shot 2023-04-11 at 11 14 21 am

Very strange. I tried switching between a few different themes and couldn't reproduce.

Maybe it was an issue with my local environment. Both this and the previous issue could have been due to styles not loading properly on the frontend.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that is a relief, thank you for double checking

"html": false,
"spacing": {
"margin": true,
"padding": true
},
"typography": {
"fontSize": true,
"lineHeight": true,
"__experimentalFontFamily": true,
"__experimentalFontWeight": true,
"__experimentalFontStyle": true,
"__experimentalTextTransform": true,
"__experimentalTextDecoration": true,
"__experimentalLetterSpacing": true,
"__experimentalDefaultControls": {
"fontSize": true
}
}
},
"editorStyle": "wp-block-details",
"style": "wp-block-details"
}
98 changes: 98 additions & 0 deletions packages/block-library/src/details/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import {
RichText,
useBlockProps,
useInnerBlocksProps,
BlockControls,
} from '@wordpress/block-editor';
import { ToolbarButton } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

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

const DETAILS = [
[
'core/paragraph',
{
placeholder: __(
'Add text or blocks that will display when the details block is opened.'
),
},
],
];

function DetailsBlock( { attributes, setAttributes } ) {
const { level, summary, showContent } = attributes;
const tagName = 'h' + level;
Copy link
Member

Choose a reason for hiding this comment

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

Is there a case where headings wouldn't make semantic sense? That is, should we also allow body text (<span />) or something?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@joedolson what do you think? Could the content in <summary> use other tags than headings?
It is valid HTML but do we want to allow it?

Copy link
Contributor

Choose a reason for hiding this comment

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

Pretty much any inline tag can be used in summary, though some of the allowed tags would be a bit strange, like audio.

Restricting the content to a heading is what makes the most sense to me. Even if other tags are allowed, they could be attached within the heading (e.g., a heading containing span, strong, mark, etc.)

I can imagine cases where the heading is not super helpful (e.g., if somebody uses the block to reveal single images with no alt text, then there's effectively no contained content, and the heading structure has no meaning); but I think that's more a misuse of the UI than a problem with the structure of the UI.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that nesting the rich text inside a heading inside the summary would be unnecessary complex, especially if we want to be able to select the HTML tag for both the heading and the inner element.

Copy link
Member

Choose a reason for hiding this comment

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

There's a big problem here: a summary element breaks the semantics of headings.

https://daverupert.com/2019/12/why-details-is-not-an-accordion/

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I only tested with VoiceOver which did include the heading inside the summary when navigating via headings.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Though I would rather have the block with a plain <summary> without inner element, than not have it available at all.

Copy link
Contributor

Choose a reason for hiding this comment

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

@ZebulanStanphill Note that article is 3 years old; given the rate of change in the accessibility API stack, it shouldn't be considered a strong reference. There are mixed opinions about whether headings are good or bad inside a summary element, so it's a decision that we would need to make. In my opinion, we should include a heading inside the summary.

Here is some testing data: https://a11ysupport.io/tests/tech__html__details-summary#assertion-html-h1-6_elements-convey_role_and_name-

Note that 'fail' means "heading semantics were ignored by the screen reader", which is not the same as "this is not accessible". The open question is whether or not a summary should have both control and heading semantics, and not all API trees/AT agrees on this point. However, it does mean that the relationship between what a simple testing tool (like HeadingsMap) will tell you about the heading hierarchy on your page and the real experience that an AT user will have is broken.

One argument in favor of allowing element choice inside the summary is that it allows a user to make their own decision about that.

Copy link
Member

Choose a reason for hiding this comment

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

@joedolson Good point.

@carolinan I agree that a <details> block is desirable regardless of whether or not headings are ultimately allowed in its <summary>.

const blockProps = useBlockProps();
const innerBlocksProps = useInnerBlocksProps(
{
className: 'wp-block-details__content',
},
{
template: DETAILS,
Copy link
Member

Choose a reason for hiding this comment

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

Thinking about allowedBlocks here (context)... I've been testing with the latest posts blocks, image, group and a bunch of others, but I think it might be useful to restrict such blocks as cover and media text etc.

Maybe even restricting container blocks such as group and column to avoid any layout weirdness.

What do you reckon about allowing all text blocks, image block, audio, and video?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, it is easier to start with a limitation, than trying to add one later.
Text and image blocks, yes.
I am not as sure about the audio and video. If the block is used as a transcript for video it probably would be a bad idea for the block to include another video.

Copy link
Contributor

Choose a reason for hiding this comment

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

But if it was used as a disclosure for an FAQ or a series of instructions, enclosing videos could make sense. I think that's reasonable.

It would be good to ensure that any headings inside the content are below the level of the details headings.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wonder if there is a way to have a disallow list rather than allowed list.

Copy link
Member

Choose a reason for hiding this comment

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

I wonder if there is a way to have a disallow list rather than allowed list.

I was wondering the same thing when looking at this! I'll make a note. It might be a useful feature.

Copy link
Member

Choose a reason for hiding this comment

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

Some related discussion about allowed/disallowed on the original issue #5540 (comment)

}
);
return (
<>
<BlockControls group="block">
<ToolbarButton
title={ __( 'Show content' ) }
// Add icon once an icon has been created icon={ }
onClick={ () => {
setAttributes( {
showContent: ! showContent,
carolinan marked this conversation as resolved.
Show resolved Hide resolved
} );
} }
className={ showContent ? 'is-pressed' : undefined }
>
{ __( 'Show content' ) }
</ToolbarButton>
<HeadingLevelDropdown
selectedLevel={ level }
onChange={ ( newLevel ) =>
setAttributes( { level: newLevel } )
}
/>
</BlockControls>
<details
{ ...blockProps }
open={ showContent }
aria-label={
showContent
? __( 'Block: Details. Expanded.' )
: __( 'Block: Details. Collapsed.' )
}
>
<summary
className={ classnames( 'wp-block-details__summary' ) }
onClick={ ( event ) => event.preventDefault() }
>
<RichText
tagName={ tagName }
aria-label={ __( 'Add summary' ) }
placeholder={ __( 'Add summary' ) }
withoutInteractiveFormatting
value={ summary }
onChange={ ( newSummary ) =>
setAttributes( { summary: newSummary } )
}
/>
</summary>
<div { ...innerBlocksProps } />
</details>
</>
);
}

export default DetailsBlock;
69 changes: 69 additions & 0 deletions packages/block-library/src/details/heading-level-dropdown.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* WordPress dependencies
*/
import { ToolbarDropdownMenu } from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import HeadingLevelIcon from './heading-level-icon';

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

const POPOVER_PROPS = {
className: 'block-library-heading-level-dropdown',
};

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

/**
* HeadingLevelDropdown props.
*
* @typedef WPHeadingLevelDropdownProps
*
* @property {number} selectedLevel The chosen heading level.
* @property {(newValue:number)=>any} onChange Callback to run when
* toolbar value is changed.
*/

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

return {
icon: (
<HeadingLevelIcon
level={ targetLevel }
isPressed={ isActive }
/>
),
label: sprintf(
// translators: %s: heading level e.g: "1", "2", "3"
__( 'Heading %d' ),
targetLevel
),
isActive,
onClick() {
onChange( targetLevel );
},
role: 'menuitemradio',
};
}
} ) }
/>
);
}
48 changes: 48 additions & 0 deletions packages/block-library/src/details/heading-level-icon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* WordPress dependencies
*/
import { Path, SVG } from '@wordpress/components';

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

/**
* HeadingLevelIcon props.
*
* @typedef WPHeadingLevelIconProps
*
* @property {number} level The heading level to show an icon for.
* @property {?boolean} isPressed Whether or not the icon should appear pressed; default: false.
*/

/**
* Heading level icon.
*
* @param {WPHeadingLevelIconProps} props Component props.
*
* @return {?WPComponent} The icon.
*/
export default function HeadingLevelIcon( { level, isPressed = false } ) {
const levelToPath = {
1: 'M9 5h2v10H9v-4H5v4H3V5h2v4h4V5zm6.6 0c-.6.9-1.5 1.7-2.6 2v1h2v7h2V5h-1.4z',
2: 'M7 5h2v10H7v-4H3v4H1V5h2v4h4V5zm8 8c.5-.4.6-.6 1.1-1.1.4-.4.8-.8 1.2-1.3.3-.4.6-.8.9-1.3.2-.4.3-.8.3-1.3 0-.4-.1-.9-.3-1.3-.2-.4-.4-.7-.8-1-.3-.3-.7-.5-1.2-.6-.5-.2-1-.2-1.5-.2-.4 0-.7 0-1.1.1-.3.1-.7.2-1 .3-.3.1-.6.3-.9.5-.3.2-.6.4-.8.7l1.2 1.2c.3-.3.6-.5 1-.7.4-.2.7-.3 1.2-.3s.9.1 1.3.4c.3.3.5.7.5 1.1 0 .4-.1.8-.4 1.1-.3.5-.6.9-1 1.2-.4.4-1 .9-1.6 1.4-.6.5-1.4 1.1-2.2 1.6V15h8v-2H15z',
3: 'M12.1 12.2c.4.3.8.5 1.2.7.4.2.9.3 1.4.3.5 0 1-.1 1.4-.3.3-.1.5-.5.5-.8 0-.2 0-.4-.1-.6-.1-.2-.3-.3-.5-.4-.3-.1-.7-.2-1-.3-.5-.1-1-.1-1.5-.1V9.1c.7.1 1.5-.1 2.2-.4.4-.2.6-.5.6-.9 0-.3-.1-.6-.4-.8-.3-.2-.7-.3-1.1-.3-.4 0-.8.1-1.1.3-.4.2-.7.4-1.1.6l-1.2-1.4c.5-.4 1.1-.7 1.6-.9.5-.2 1.2-.3 1.8-.3.5 0 1 .1 1.6.2.4.1.8.3 1.2.5.3.2.6.5.8.8.2.3.3.7.3 1.1 0 .5-.2.9-.5 1.3-.4.4-.9.7-1.5.9v.1c.6.1 1.2.4 1.6.8.4.4.7.9.7 1.5 0 .4-.1.8-.3 1.2-.2.4-.5.7-.9.9-.4.3-.9.4-1.3.5-.5.1-1 .2-1.6.2-.8 0-1.6-.1-2.3-.4-.6-.2-1.1-.6-1.6-1l1.1-1.4zM7 9H3V5H1v10h2v-4h4v4h2V5H7v4z',
4: 'M9 15H7v-4H3v4H1V5h2v4h4V5h2v10zm10-2h-1v2h-2v-2h-5v-2l4-6h3v6h1v2zm-3-2V7l-2.8 4H16z',
5: 'M12.1 12.2c.4.3.7.5 1.1.7.4.2.9.3 1.3.3.5 0 1-.1 1.4-.4.4-.3.6-.7.6-1.1 0-.4-.2-.9-.6-1.1-.4-.3-.9-.4-1.4-.4H14c-.1 0-.3 0-.4.1l-.4.1-.5.2-1-.6.3-5h6.4v1.9h-4.3L14 8.8c.2-.1.5-.1.7-.2.2 0 .5-.1.7-.1.5 0 .9.1 1.4.2.4.1.8.3 1.1.6.3.2.6.6.8.9.2.4.3.9.3 1.4 0 .5-.1 1-.3 1.4-.2.4-.5.8-.9 1.1-.4.3-.8.5-1.3.7-.5.2-1 .3-1.5.3-.8 0-1.6-.1-2.3-.4-.6-.2-1.1-.6-1.6-1-.1-.1 1-1.5 1-1.5zM9 15H7v-4H3v4H1V5h2v4h4V5h2v10z',
6: 'M9 15H7v-4H3v4H1V5h2v4h4V5h2v10zm8.6-7.5c-.2-.2-.5-.4-.8-.5-.6-.2-1.3-.2-1.9 0-.3.1-.6.3-.8.5l-.6.9c-.2.5-.2.9-.2 1.4.4-.3.8-.6 1.2-.8.4-.2.8-.3 1.3-.3.4 0 .8 0 1.2.2.4.1.7.3 1 .6.3.3.5.6.7.9.2.4.3.8.3 1.3s-.1.9-.3 1.4c-.2.4-.5.7-.8 1-.4.3-.8.5-1.2.6-1 .3-2 .3-3 0-.5-.2-1-.5-1.4-.9-.4-.4-.8-.9-1-1.5-.2-.6-.3-1.3-.3-2.1s.1-1.6.4-2.3c.2-.6.6-1.2 1-1.6.4-.4.9-.7 1.4-.9.6-.3 1.1-.4 1.7-.4.7 0 1.4.1 2 .3.5.2 1 .5 1.4.8 0 .1-1.3 1.4-1.3 1.4zm-2.4 5.8c.2 0 .4 0 .6-.1.2 0 .4-.1.5-.2.1-.1.3-.3.4-.5.1-.2.1-.5.1-.7 0-.4-.1-.8-.4-1.1-.3-.2-.7-.3-1.1-.3-.3 0-.7.1-1 .2-.4.2-.7.4-1 .7 0 .3.1.7.3 1 .1.2.3.4.4.6.2.1.3.3.5.3.2.1.5.2.7.1z',
};
if ( ! levelToPath.hasOwnProperty( level ) ) {
return null;
}

return (
<SVG
Copy link
Member

Choose a reason for hiding this comment

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

Does <BlockIcon /> not work in this context? Just asking out of curiosity.

width="24"
height="24"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
isPressed={ isPressed }
>
<Path d={ levelToPath[ level ] } />
</SVG>
);
}
25 changes: 25 additions & 0 deletions packages/block-library/src/details/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* WordPress dependencies
*/
import { chevronDown as icon } from '@wordpress/icons';

/**
* Internal dependencies
*/
import initBlock from '../utils/init-block';
import metadata from './block.json';
import edit from './edit';
import save from './save';
import variations from './variations';

const { name } = metadata;
export { metadata, name };

export const settings = {
icon,
save,
edit,
variations,
};

export const init = () => initBlock( { name, metadata, settings } );
34 changes: 34 additions & 0 deletions packages/block-library/src/details/save.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import {
RichText,
useBlockProps,
useInnerBlocksProps,
} from '@wordpress/block-editor';

export default function save( { attributes } ) {
const { level, summary, showContent } = attributes;
const TagName = 'h' + level;
const blockProps = useBlockProps.save();

return (
<details { ...blockProps } open={ showContent }>
<summary className={ classnames( 'wp-block-details__summary' ) }>
<TagName>
<RichText.Content value={ summary } />
</TagName>
</summary>
<div
{ ...useInnerBlocksProps.save( {
className: 'wp-block-details__content',
} ) }
/>
</details>
);
}
9 changes: 9 additions & 0 deletions packages/block-library/src/details/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.wp-block-details {
.wp-block-details__summary {
> * {
display: inline;
margin-left: 0.5rem;
cursor: pointer;
}
}
}
Loading