Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions blocks/details/editor.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* Editor styles */
.wp-block-a8c-details {
summary .rich-text {
display: inline;
}
}
9 changes: 9 additions & 0 deletions blocks/details/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

add_action( 'init', function() {
register_block_type( 'a8c/details', [
'editor_script' => 'block-experiments',
'style' => 'block-experiments',
'editor_style' => 'block-experiments-editor',
] );
} );
13 changes: 13 additions & 0 deletions blocks/details/src/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "a8c/details",
"category": "layout",
"attributes": {
"initialOpen": {
"type": "boolean",
"default": false
},
"summaryContent": {
"type": "string"
}
}
}
94 changes: 94 additions & 0 deletions blocks/details/src/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**
* WordPress dependencies
*/
import {
InnerBlocks,
RichText,
InspectorControls,
} from '@wordpress/block-editor';
import { __ } from '@wordpress/i18n';
import { useSelect } from '@wordpress/data';
import {
ToggleControl,
Panel,
PanelBody,
PanelRow,
} from '@wordpress/components';
import { useEffect, useRef } from '@wordpress/element';
import { SPACE } from '@wordpress/keycodes';

export default function DetalsEdit( {
attributes,
className,
clientId,
isSelected,
setAttributes,
} ) {
const summaryRef = useRef( null );

const keyUpListener = ( e ) => {
if ( e.keyCode === SPACE ) {
e.preventDefault();
}
};

const clickListener = ( e ) => e.preventDefault();

useEffect( () => {
if ( ! summaryRef.current ) {
return;
}

summaryRef.current.addEventListener( 'keyup', keyUpListener );
summaryRef.current.addEventListener( 'click', clickListener );
return () => {
summaryRef.current.removeEventListener( 'keyup', keyUpListener );
summaryRef.current.removeEventListener( 'click', clickListener );
};
}, [ summaryRef.current ] );

const isInnerBlockSelected = useSelect(
( select ) =>
select( 'core/block-editor' ).hasSelectedInnerBlock( clientId ),
[ clientId ]
);

const showInnerBlocks =
attributes.initialOpen || isSelected || isInnerBlockSelected;

return (
<>
<InspectorControls>
<Panel>
<PanelBody>
<PanelRow>
<ToggleControl
label={ __( 'Open by default' ) }
onChange={ ( initialOpen ) =>
setAttributes( { initialOpen } )
}
checked={ attributes.initialOpen }
/>
</PanelRow>
</PanelBody>
</Panel>
</InspectorControls>
<details className={ className } open={ showInnerBlocks }>
<RichText
tagName="summary"
value={ attributes.summaryContent }
onChange={ ( summaryContent ) =>
setAttributes( { summaryContent } )
}
ref={ summaryRef }
placeholder={ __( 'Write a summary…' ) }
keepPlaceholderOnFocus
aria-label={ __( 'Summary text' ) }
/>
<div className="wp-block-a8c-details__content">
<InnerBlocks />
</div>
</details>
</>
);
}
12 changes: 12 additions & 0 deletions blocks/details/src/icon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* WordPress dependencies
*/
import { SVG, Path } from '@wordpress/primitives';

const details = (
<SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<Path d="M4 20h9v-1.5H4V20zm0-5.5V16h16v-1.5H4zM4 4v8l7-4-7-4z" />
</SVG>
);

export default details;
44 changes: 44 additions & 0 deletions blocks/details/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* WordPress dependencies
*/
import { registerBlockType } from '@wordpress/blocks';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import edit from './edit';
import metadata from './block.json';
import save from './save';
import icon from './icon';

const { name, category, attributes } = metadata;

export { metadata, name };

export const settings = {
title: __( 'Details' ),
description: __( 'Create a toggle to show and hide content.' ),
icon,
category,
edit,
save,
// details and summary are not translated because they are the HTML tags
keywords: [ 'details', 'summary', __( 'faq' ), __( 'spoiler' ) ],
attributes,
styles: [
{
name: 'disclosure',
label: __( 'Open / Close' ),
isDefault: true,
},
{
name: 'flipcard',
label: __( 'Flip Card' ),
},
],
};

export function registerBlock() {
registerBlockType( name, settings );
}
18 changes: 18 additions & 0 deletions blocks/details/src/save.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* WordPress dependencies
*/
import { InnerBlocks, RichText } from '@wordpress/block-editor';

export default ( { attributes } ) => {
return (
<details open={ attributes.initialOpen }>
<RichText.Content
tagName="summary"
value={ attributes.summaryContent }
/>
<div className="wp-block-a8c-details__content">
<InnerBlocks.Content />
</div>
</details>
);
};
60 changes: 60 additions & 0 deletions blocks/details/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Front end and editor styles.

$bgcolor: #efefef; // Be nice if this was customizable via a background color property.

@keyframes open-card {
0% {
transform: rotateX(-180deg);
opacity: 0;
}
100% {
transform: rotateX(0deg);
opacity: 1;
}
}

.wp-block-a8c-details {

// 3D flip-card style.
&.is-style-flipcard {
margin-bottom: 1.5em;

// Enable 3D perspective.
transform-style: preserve-3d;
perspective: 300px;


// Card front-face.
summary {
background: $bgcolor;
padding: 1em;

// Allows a focus style on the summary to be uncropped.
position: relative;
}

// Back-face regardless of opened or closed.
> *:not(summary) {
background: $bgcolor;
transform-origin: top center;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;

// Some baseline left and right padding.
padding-left: 1em;
padding-right: 1em;
}

// Neutralize the top margin of the first innerblock, add padding.
> summary+*, // Frontend
> .block-editor-inner-blocks > .block-editor-block-list__layout > * { // Editor
margin-top: 0;
padding-top: 1em;
}

// Back-face when opened.
&[open] > *:not(summary) {
animation: open-card .2s ease;
}
}
}
9 changes: 9 additions & 0 deletions bundler/bundles/details.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"blocks": [
"details"
],
"version": "0.0.1",
"name": "Details Block",
"description": "Create a toggle to show and hide content",
"resource": "a8c-details"
}
1 change: 1 addition & 0 deletions editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
@import './blocks/starscape/editor.scss';
@import './blocks/waves/editor.scss';
@import './blocks/book/editor.scss';
@import './blocks/details/editor.scss';
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import * as motionBackgroundBlock from '../blocks/motion-background/src';
import * as starscapeBlock from '../blocks/starscape/src';
import * as wavesBlock from '../blocks/waves/src';
import * as bookBlock from '../blocks/book/src';
import * as detailsBlock from '../blocks/details/src';

// Instantiate the blocks, adding them to our block category
bauhausCentenaryBlock.registerBlock();
Expand All @@ -38,3 +39,4 @@ motionBackgroundBlock.registerBlock();
starscapeBlock.registerBlock();
wavesBlock.registerBlock();
bookBlock.registerBlock();
detailsBlock.registerBlock();
1 change: 1 addition & 0 deletions style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
@import './blocks/starscape/style.scss';
@import './blocks/waves/style.scss';
@import './blocks/book/style.scss';
@import './blocks/details/style.scss';