Skip to content

Commit

Permalink
feat(SLB-286): add image-teasers gutenberg block
Browse files Browse the repository at this point in the history
  • Loading branch information
Leksat committed Apr 11, 2024
1 parent fd0ab14 commit aeea400
Show file tree
Hide file tree
Showing 9 changed files with 234 additions and 2 deletions.
119 changes: 119 additions & 0 deletions packages/drupal/gutenberg_blocks/src/blocks/image-teaser.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import {
// @ts-ignore
__experimentalLinkControl as LinkControl,
InnerBlocks,
InspectorControls,
RichText,
} from 'wordpress__block-editor';
import { registerBlockType } from 'wordpress__blocks';
import { PanelBody } from 'wordpress__components';
import { dispatch } from 'wordpress__data';

import { DrupalMediaEntity } from '../utils/drupal-media';

// @ts-ignore
const { t: __ } = Drupal;
// @ts-ignore
const { setPlainTextAttribute } = silverbackGutenbergUtils;

registerBlockType('custom/image-teaser', {
title: __('Image Teaser'),
parent: ['custom/image-teasers'],
icon: 'cover-image',
category: 'layout',
attributes: {
mediaEntityIds: {
type: 'array',
},
title: {
type: 'string',
},
ctaUrl: {
type: 'string',
},
ctaText: {
type: 'string',
},
},
edit: (props) => {
return (
<>
<InspectorControls>
<PanelBody title={__('CTA Link')}>
<LinkControl
placeholder={__('Link')}
value={{
url: props.attributes.ctaUrl,
}}
settings={{}}
onChange={(link: { url: string; opensInNewTab: boolean }) => {
props.setAttributes({
ctaUrl: link.url,
});
}}
/>
</PanelBody>
</InspectorControls>
<div>
<div>
<DrupalMediaEntity
classname={'w-full'}
attributes={{
...(props.attributes as any),
lockViewMode: true,
viewMode: 'gutenberg_header',
allowedTypes: ['image'],
}}
setAttributes={props.setAttributes}
isMediaLibraryEnabled={true}
onError={(error) => {
// @ts-ignore
error = typeof error === 'string' ? error : error[2];
dispatch('core/notices').createWarningNotice(error);
}}
/>
</div>

<div>
<div>
<RichText
className={'font-bold text-2xl mt-3'}
identifier="title"
tagName="div"
value={props.attributes.title as string}
allowedFormats={[]}
// @ts-ignore
disableLineBreaks={true}
placeholder={__('Title')}
keepPlaceholderOnFocus={true}
onChange={(title) => {
setPlainTextAttribute(props, 'title', title);
}}
/>
</div>
<div>
<RichText
identifier="ctaText"
tagName="div"
multiline={false}
value={props.attributes.ctaText as string}
allowedFormats={[]}
// @ts-ignore
disableLineBreaks={true}
placeholder={__('CTA text')}
keepPlaceholderOnFocus={true}
style={{
cursor: 'text',
}}
onChange={(ctaText) => {
setPlainTextAttribute(props, 'ctaText', ctaText);
}}
/>
</div>
</div>
</div>
</>
);
},
save: () => <InnerBlocks.Content />,
});
24 changes: 24 additions & 0 deletions packages/drupal/gutenberg_blocks/src/blocks/image-teasers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { InnerBlocks } from 'wordpress__block-editor';
import { registerBlockType } from 'wordpress__blocks';

// @ts-ignore
const { t: __ } = Drupal;

registerBlockType('custom/image-teasers', {
title: __('Image Teasers'),
icon: 'format-image',
category: 'layout',
attributes: {},
edit: () => {
return (
<>
<InnerBlocks
templateLock={false}
allowedBlocks={['custom/image-teaser']}
template={[['custom/image-teaser']]}
/>
</>
);
},
save: () => <InnerBlocks.Content />,
});
2 changes: 2 additions & 0 deletions packages/drupal/gutenberg_blocks/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ import './blocks/hero';
import './blocks/content';
import './blocks/heading';
import './blocks/form';
import './blocks/image-teaser';
import './blocks/image-teasers';
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ _meta:
depends:
3a0fe860-a6d6-428a-9474-365bd57509aa: media
478c4289-961d-4ce8-85d6-578ae05f3019: media
72187a1f-3e48-4b45-a9b7-189c6fd7ee26: media
default:
revision_uid:
-
Expand Down Expand Up @@ -79,6 +80,12 @@ default:
<blockquote class="wp-block-quote"><p>Quote</p><cite>Citation</cite></blockquote>
<!-- /wp:quote -->
<!-- wp:custom/image-teasers -->
<!-- wp:custom/image-teaser {"mediaEntityIds":["3a0fe860-a6d6-428a-9474-365bd57509aa"],"title":"Teaser 1","ctaUrl":"https://google.com","ctaText":"Foo"} /-->
<!-- wp:custom/image-teaser {"mediaEntityIds":["72187a1f-3e48-4b45-a9b7-189c6fd7ee26"],"title":"Teaser 2","ctaUrl":"https://google.com","ctaText":"Bar"} /-->
<!-- /wp:custom/image-teasers -->
<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->
Expand Down
1 change: 1 addition & 0 deletions packages/schema/src/fragments/Page.gql
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ fragment Page on Page {
...BlockMarkup
...BlockMedia
...BlockForm
...BlockImageTeasers
}
metaTags {
tag
Expand Down
11 changes: 11 additions & 0 deletions packages/schema/src/fragments/PageContent/BlockImageTeasers.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
fragment BlockImageTeasers on BlockImageTeasers {
teasers {
image {
source(width: 1536, sizes: [[768, 768], [1536, 1536]])
alt
}
title
ctaText
ctaUrl
}
}
17 changes: 16 additions & 1 deletion packages/schema/src/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,11 @@ type Hero {
@webformIdToUrl(id: "$")
}

union PageContent @resolveEditorBlockType = BlockMarkup | BlockMedia | BlockForm
union PageContent @resolveEditorBlockType =
BlockMarkup
| BlockMedia
| BlockForm
| BlockImageTeasers

type BlockForm @type(id: "custom/form") {
url: Url @resolveEditorBlockAttribute(key: "formId") @webformIdToUrl(id: "$")
Expand Down Expand Up @@ -222,6 +226,17 @@ type BlockMedia @type(id: "drupalmedia/drupal-media-entity") {
caption: Markup @resolveEditorBlockAttribute(key: "caption")
}

type BlockImageTeasers @type(id: "custom/image-teasers") {
teasers: [BlockImageTeaser!]! @resolveEditorBlockChildren
}

type BlockImageTeaser @default @value {
image: MediaImage @resolveEditorBlockMedia
title: String @resolveEditorBlockAttribute(key: "title")
ctaText: String @resolveEditorBlockAttribute(key: "ctaText")
ctaUrl: Url @resolveEditorBlockAttribute(key: "ctaUrl")
}

input PaginationInput {
limit: Int!
offset: Int!
Expand Down
15 changes: 15 additions & 0 deletions packages/ui/src/components/Organisms/PageDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,21 @@ export function PageDisplay(page: PageFragment) {
return <BlockMarkup key={index} {...block} />;
case 'BlockForm':
return <BlockForm key={index} {...block} />;
case 'BlockImageTeasers':
return (
// TODO: Implement BlockImageTeasers
<div
style={{
color: 'red',
border: 'solid 3px red',
padding: '3px',
margin: '5px 0',
}}
// eslint-disable-next-line react/jsx-no-literals
>
BlockImageTeasers goes here
</div>
);
default:
throw new UnreachableCaseError(block);
}
Expand Down
40 changes: 39 additions & 1 deletion tests/schema/specs/blocks.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ test('Blocks', async () => {
... on BlockForm {
url
}
... on BlockImageTeasers {
teasers {
__typename
image {
__typename
}
title
ctaText
ctaUrl
}
}
}
}
{
Expand Down Expand Up @@ -96,7 +107,34 @@ test('Blocks', async () => {
<h3 class="wp-block-custom-heading">Heading 3</h3>
<blockquote class="wp-block-quote"><p>Quote</p><cite>Citation</cite></blockquote>
",
},
{
"__typename": "BlockImageTeasers",
"teasers": [
{
"__typename": "BlockImageTeaser",
"ctaText": "Foo",
"ctaUrl": "https://google.com",
"image": {
"__typename": "MediaImage",
},
"title": "Teaser 1",
},
{
"__typename": "BlockImageTeaser",
"ctaText": "Bar",
"ctaUrl": "https://google.com",
"image": {
"__typename": "MediaImage",
},
"title": "Teaser 2",
},
],
},
{
"__typename": "BlockMarkup",
"markup": "
<p></p>
",
},
Expand Down

0 comments on commit aeea400

Please sign in to comment.