From 94cb6277ea0acb6f52f5d54d2ffc8590fe013bdd Mon Sep 17 00:00:00 2001 From: Luqmaan Essop Date: Tue, 16 Apr 2024 14:51:14 +0000 Subject: [PATCH 1/7] style: adjust quote styling --- .../Organisms/PageContent/BlockMarkup.tsx | 19 +++++++++++++++++++ packages/ui/src/tailwind.css | 8 +++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/packages/ui/src/components/Organisms/PageContent/BlockMarkup.tsx b/packages/ui/src/components/Organisms/PageContent/BlockMarkup.tsx index 54f29a9fb..443b8fd19 100644 --- a/packages/ui/src/components/Organisms/PageContent/BlockMarkup.tsx +++ b/packages/ui/src/components/Organisms/PageContent/BlockMarkup.tsx @@ -49,6 +49,25 @@ export function BlockMarkup(props: BlockMarkupFragment) { ); }, + blockquote: ({ children }: PropsWithChildren<{}>) => { + return ( +
+ + + + {children} +
+ ); + }, }} markup={props.markup} /> diff --git a/packages/ui/src/tailwind.css b/packages/ui/src/tailwind.css index bd6213e1d..33a4a800a 100644 --- a/packages/ui/src/tailwind.css +++ b/packages/ui/src/tailwind.css @@ -1,3 +1,9 @@ @tailwind base; @tailwind components; -@tailwind utilities; \ No newline at end of file +@tailwind utilities; + +/* Prose overrides */ +.lg\:prose-xl + :where(blockquote):not(:where([class~='not-prose'], [class~='not-prose'] *)) { + padding-left: 0 !important; +} From b32adedb10e0ba88c97a66045de5fb3e3bc867dc Mon Sep 17 00:00:00 2001 From: Vasile Chindris Date: Tue, 16 Apr 2024 17:13:15 +0300 Subject: [PATCH 2/7] feat(SLB-297 SLB-296): replace the core quote block with a custom one --- apps/cms/config/sync/gutenberg.settings.yml | 6 +- packages/drupal/gutenberg_blocks/css/edit.css | 5 + .../GutenbergValidator/QuoteValidator.php | 40 +++++++ .../gutenberg_blocks/src/blocks/quote.tsx | 100 ++++++++++++++++++ packages/drupal/gutenberg_blocks/src/index.ts | 1 + 5 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 packages/drupal/gutenberg_blocks/src/Plugin/Validation/GutenbergValidator/QuoteValidator.php create mode 100644 packages/drupal/gutenberg_blocks/src/blocks/quote.tsx diff --git a/apps/cms/config/sync/gutenberg.settings.yml b/apps/cms/config/sync/gutenberg.settings.yml index e58422162..ed9ef9d7d 100644 --- a/apps/cms/config/sync/gutenberg.settings.yml +++ b/apps/cms/config/sync/gutenberg.settings.yml @@ -4,12 +4,12 @@ page_template_lock: all page_allowed_blocks: core/paragraph: core/paragraph core/list: core/list - core/quote: core/quote core/table: core/table core/all: 0 core/image: 0 core/heading: 0 core/gallery: 0 + core/quote: 0 core/audio: 0 core/button: 0 core/buttons: 0 @@ -75,6 +75,7 @@ page_allowed_drupal_blocks: drupalblock/all_core: 0 page_title_block: 0 drupalblock/all_forms: 0 + masquerade: 0 user_login_block: 0 drupalblock/all_lists_views_: 0 'views_block:content_recent-block_1': 0 @@ -91,3 +92,6 @@ page_allowed_drupal_blocks: system_branding_block: 0 node_syndicate_block: 0 drupalblock/all_user: 0 + drupalblock/all_webform: 0 + webform_block: 0 + webform_submission_limit_block: 0 diff --git a/packages/drupal/gutenberg_blocks/css/edit.css b/packages/drupal/gutenberg_blocks/css/edit.css index f4a49c277..1c603451e 100644 --- a/packages/drupal/gutenberg_blocks/css/edit.css +++ b/packages/drupal/gutenberg_blocks/css/edit.css @@ -12,6 +12,11 @@ content: ''; } +.gutenberg__editor blockquote .quote-author, +.gutenberg__editor blockquote .quote-role { + text-align: right; +} + .gutenberg__editor .container-wrapper { display: block; position: relative; diff --git a/packages/drupal/gutenberg_blocks/src/Plugin/Validation/GutenbergValidator/QuoteValidator.php b/packages/drupal/gutenberg_blocks/src/Plugin/Validation/GutenbergValidator/QuoteValidator.php new file mode 100644 index 000000000..1f9f9d9c9 --- /dev/null +++ b/packages/drupal/gutenberg_blocks/src/Plugin/Validation/GutenbergValidator/QuoteValidator.php @@ -0,0 +1,40 @@ + [ + 'field_label' => $this->t('Quote text'), + 'rules' => ['required'], + ], + 'author' => [ + 'field_label' => $this->t('Quote author'), + 'rules' => ['required'], + ], + ]; + } + +} diff --git a/packages/drupal/gutenberg_blocks/src/blocks/quote.tsx b/packages/drupal/gutenberg_blocks/src/blocks/quote.tsx new file mode 100644 index 000000000..1dacdf98b --- /dev/null +++ b/packages/drupal/gutenberg_blocks/src/blocks/quote.tsx @@ -0,0 +1,100 @@ +import { RichText } from 'wordpress__block-editor'; +import { registerBlockType } from 'wordpress__blocks'; +import { compose, withState } from 'wordpress__compose'; +import { dispatch } from 'wordpress__data'; + +import { cleanUpText } from '../utils/clean-up-text'; +import { DrupalMediaEntity } from '../utils/drupal-media'; + +declare const Drupal: { t: (s: string) => string }; + +const { t: __ } = Drupal; + +// @ts-ignore +const { setPlainTextAttribute } = silverbackGutenbergUtils; + +// @ts-ignore +registerBlockType(`custom/quote`, { + title: __('Quote'), + icon: 'format-quote', + category: 'text', + attributes: { + text: { + type: 'string', + }, + author: { + tpye: 'string', + }, + role: { + type: 'string', + }, + mediaEntityIds: { + type: 'array', + }, + }, + // @ts-ignore + edit: compose(withState())((props) => { + return ( +
+ { + props.setAttributes({ + text: cleanUpText(text), + }); + }} + /> + { + setPlainTextAttribute(props, 'author', author); + }} + /> + { + setPlainTextAttribute(props, 'role', role); + }} + /> + { + // @ts-ignore + error = typeof error === 'string' ? error : error[2]; + dispatch('core/notices').createWarningNotice(error); + }} + /> +
+ ); + }), + save() { + return null; + }, +}); diff --git a/packages/drupal/gutenberg_blocks/src/index.ts b/packages/drupal/gutenberg_blocks/src/index.ts index a0aff90af..332b5720f 100644 --- a/packages/drupal/gutenberg_blocks/src/index.ts +++ b/packages/drupal/gutenberg_blocks/src/index.ts @@ -6,3 +6,4 @@ import './blocks/form'; import './blocks/image-teaser'; import './blocks/image-teasers'; import './blocks/cta'; +import './blocks/quote'; From 31867676bf6db6ccca4d90922725859cd4942a44 Mon Sep 17 00:00:00 2001 From: Vasile Chindris Date: Tue, 16 Apr 2024 17:28:27 +0300 Subject: [PATCH 3/7] feat(SLB-297 SLB-296): quote graphql block type --- packages/drupal/gutenberg_blocks/src/blocks/quote.tsx | 2 +- packages/schema/src/schema.graphql | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/drupal/gutenberg_blocks/src/blocks/quote.tsx b/packages/drupal/gutenberg_blocks/src/blocks/quote.tsx index 1dacdf98b..f42c3f82d 100644 --- a/packages/drupal/gutenberg_blocks/src/blocks/quote.tsx +++ b/packages/drupal/gutenberg_blocks/src/blocks/quote.tsx @@ -46,7 +46,7 @@ registerBlockType(`custom/quote`, { keepPlaceholderOnFocus={false} onChange={(text) => { props.setAttributes({ - text: cleanUpText(text), + text: cleanUpText(text, ['strong']), }); }} /> diff --git a/packages/schema/src/schema.graphql b/packages/schema/src/schema.graphql index 9300972cb..e379509fb 100644 --- a/packages/schema/src/schema.graphql +++ b/packages/schema/src/schema.graphql @@ -199,6 +199,7 @@ union PageContent @resolveEditorBlockType = | BlockForm | BlockImageTeasers | BlockCta + | BlockQuote type BlockForm @type(id: "custom/form") { url: Url @resolveEditorBlockAttribute(key: "formId") @webformIdToUrl(id: "$") @@ -244,6 +245,13 @@ type BlockCta @type(id: "custom/cta") { openInNewTab: Boolean @resolveEditorBlockAttribute(key: "openInNewTab") } +type BlockQuote @type(id: "custom/quote") { + text: Markup @resolveEditorBlockAttribute(key: "text") + author: String @resolveEditorBlockAttribute(key: "author") + role: String @resolveEditorBlockAttribute(key: "role") + image: MediaImage @resolveEditorBlockMedia +} + input PaginationInput { limit: Int! offset: Int! From d0e0b9558dd88ac4f9c8066982e93bd8c152d110 Mon Sep 17 00:00:00 2001 From: Vasile Chindris Date: Tue, 16 Apr 2024 17:42:21 +0300 Subject: [PATCH 4/7] feat(SLB-296): organism placeholder for quote blocks --- packages/schema/src/fragments/Page.gql | 1 + packages/schema/src/fragments/PageContent/BlockQuote.gql | 9 +++++++++ .../src/components/Organisms/PageContent/BlockQuote.tsx | 7 +++++++ packages/ui/src/components/Organisms/PageDisplay.tsx | 3 +++ 4 files changed, 20 insertions(+) create mode 100644 packages/schema/src/fragments/PageContent/BlockQuote.gql create mode 100644 packages/ui/src/components/Organisms/PageContent/BlockQuote.tsx diff --git a/packages/schema/src/fragments/Page.gql b/packages/schema/src/fragments/Page.gql index 38c057340..4c3fe1e11 100644 --- a/packages/schema/src/fragments/Page.gql +++ b/packages/schema/src/fragments/Page.gql @@ -33,6 +33,7 @@ fragment Page on Page { ...BlockForm ...BlockImageTeasers ...BlockCta + ...BlockQuote } metaTags { tag diff --git a/packages/schema/src/fragments/PageContent/BlockQuote.gql b/packages/schema/src/fragments/PageContent/BlockQuote.gql new file mode 100644 index 000000000..b50478e0a --- /dev/null +++ b/packages/schema/src/fragments/PageContent/BlockQuote.gql @@ -0,0 +1,9 @@ +fragment BlockQuote on BlockQuote { + text + author + role + image { + source(width: 1536, sizes: [[768, 768], [1536, 1536]]) + alt + } +} diff --git a/packages/ui/src/components/Organisms/PageContent/BlockQuote.tsx b/packages/ui/src/components/Organisms/PageContent/BlockQuote.tsx new file mode 100644 index 000000000..4676f6302 --- /dev/null +++ b/packages/ui/src/components/Organisms/PageContent/BlockQuote.tsx @@ -0,0 +1,7 @@ +import { BlockQuoteFragment } from '@custom/schema'; +import React from 'react'; + +export function BlockQuote(props: BlockQuoteFragment) { + console.log('Block quote props:', props); + return <>; +} diff --git a/packages/ui/src/components/Organisms/PageDisplay.tsx b/packages/ui/src/components/Organisms/PageDisplay.tsx index bcefcb2ec..21af1c5eb 100644 --- a/packages/ui/src/components/Organisms/PageDisplay.tsx +++ b/packages/ui/src/components/Organisms/PageDisplay.tsx @@ -8,6 +8,7 @@ import { BlockCta } from './PageContent/BlockCta'; import { BlockForm } from './PageContent/BlockForm'; import { BlockMarkup } from './PageContent/BlockMarkup'; import { BlockMedia } from './PageContent/BlockMedia'; +import { BlockQuote } from './PageContent/BlockQuote'; import { PageHero } from './PageHero'; export function PageDisplay(page: PageFragment) { @@ -43,6 +44,8 @@ export function PageDisplay(page: PageFragment) { ); case 'BlockCta': return ; + case 'BlockQuote': + return
; default: throw new UnreachableCaseError(block); } From d8d41f3a55859b7f08f58ab3f9c1bf5ea9b5d96f Mon Sep 17 00:00:00 2001 From: Vasile Chindris Date: Tue, 16 Apr 2024 20:26:22 +0300 Subject: [PATCH 5/7] chore(SLB-297 SLB-296): update the quote text from text to quote --- .../Validation/GutenbergValidator/QuoteValidator.php | 2 +- packages/drupal/gutenberg_blocks/src/blocks/quote.tsx | 10 +++++----- .../schema/src/fragments/PageContent/BlockQuote.gql | 2 +- packages/schema/src/schema.graphql | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/drupal/gutenberg_blocks/src/Plugin/Validation/GutenbergValidator/QuoteValidator.php b/packages/drupal/gutenberg_blocks/src/Plugin/Validation/GutenbergValidator/QuoteValidator.php index 1f9f9d9c9..53df53041 100644 --- a/packages/drupal/gutenberg_blocks/src/Plugin/Validation/GutenbergValidator/QuoteValidator.php +++ b/packages/drupal/gutenberg_blocks/src/Plugin/Validation/GutenbergValidator/QuoteValidator.php @@ -26,7 +26,7 @@ public function applies(array $block): bool { */ public function validatedFields($block = []): array { return [ - 'text' => [ + 'quote' => [ 'field_label' => $this->t('Quote text'), 'rules' => ['required'], ], diff --git a/packages/drupal/gutenberg_blocks/src/blocks/quote.tsx b/packages/drupal/gutenberg_blocks/src/blocks/quote.tsx index f42c3f82d..1aea31b6a 100644 --- a/packages/drupal/gutenberg_blocks/src/blocks/quote.tsx +++ b/packages/drupal/gutenberg_blocks/src/blocks/quote.tsx @@ -19,7 +19,7 @@ registerBlockType(`custom/quote`, { icon: 'format-quote', category: 'text', attributes: { - text: { + quote: { type: 'string', }, author: { @@ -37,16 +37,16 @@ registerBlockType(`custom/quote`, { return (
{ + onChange={(quote) => { props.setAttributes({ - text: cleanUpText(text, ['strong']), + quote: cleanUpText(quote, ['strong']), }); }} /> diff --git a/packages/schema/src/fragments/PageContent/BlockQuote.gql b/packages/schema/src/fragments/PageContent/BlockQuote.gql index b50478e0a..785efb620 100644 --- a/packages/schema/src/fragments/PageContent/BlockQuote.gql +++ b/packages/schema/src/fragments/PageContent/BlockQuote.gql @@ -1,5 +1,5 @@ fragment BlockQuote on BlockQuote { - text + quote author role image { diff --git a/packages/schema/src/schema.graphql b/packages/schema/src/schema.graphql index e379509fb..43bff39d9 100644 --- a/packages/schema/src/schema.graphql +++ b/packages/schema/src/schema.graphql @@ -246,7 +246,7 @@ type BlockCta @type(id: "custom/cta") { } type BlockQuote @type(id: "custom/quote") { - text: Markup @resolveEditorBlockAttribute(key: "text") + quote: Markup @resolveEditorBlockAttribute(key: "quote") author: String @resolveEditorBlockAttribute(key: "author") role: String @resolveEditorBlockAttribute(key: "role") image: MediaImage @resolveEditorBlockMedia From 63a9f6b61c0b983f0d3d985e75705e220b0b337e Mon Sep 17 00:00:00 2001 From: Vasile Chindris Date: Tue, 16 Apr 2024 20:44:05 +0300 Subject: [PATCH 6/7] test(SLB-297): update default content and schema tests to include quote blocks --- .../a397ca48-8fad-411e-8901-0eba2feb989c.yml | 74 +++++++++++++------ .../ceb9b2a7-4c4c-4084-ada9-d5f6505d466b.yml | 2 + tests/schema/specs/blocks.spec.ts | 24 ++++++ 3 files changed, 77 insertions(+), 23 deletions(-) diff --git a/packages/drupal/test_content/content/node/a397ca48-8fad-411e-8901-0eba2feb989c.yml b/packages/drupal/test_content/content/node/a397ca48-8fad-411e-8901-0eba2feb989c.yml index 2a18b3664..0ee37d6aa 100644 --- a/packages/drupal/test_content/content/node/a397ca48-8fad-411e-8901-0eba2feb989c.yml +++ b/packages/drupal/test_content/content/node/a397ca48-8fad-411e-8901-0eba2feb989c.yml @@ -10,31 +10,43 @@ _meta: 72187a1f-3e48-4b45-a9b7-189c6fd7ee26: media default: revision_uid: - - target_id: 1 + - + target_id: 1 status: - - value: true + - + value: true uid: - - target_id: 1 + - + target_id: 1 title: - - value: 'Blocks: complete' + - + value: 'Blocks: complete' created: - - value: 1686759493 + - + value: 1686759493 promote: - - value: false + - + value: false sticky: - - value: false + - + value: false moderation_state: - - value: published + - + value: published path: - - alias: /blocks-complete + - + alias: /blocks-complete langcode: en pathauto: 0 content_translation_source: - - value: und + - + value: und content_translation_outdated: - - value: false + - + value: false body: - - value: |- + - + value: |- @@ -79,6 +91,9 @@ default: + + +

@@ -88,29 +103,40 @@ default: translations: de: status: - - value: true + - + value: true uid: - - target_id: 1 + - + target_id: 1 title: - - value: 'Blocks: complete DE' + - + value: 'Blocks: complete DE' created: - - value: 1687338353 + - + value: 1687338353 promote: - - value: false + - + value: false sticky: - - value: false + - + value: false moderation_state: - - value: published + - + value: published path: - - alias: /blocks-complete + - + alias: /blocks-complete langcode: de pathauto: 0 content_translation_source: - - value: en + - + value: en content_translation_outdated: - - value: false + - + value: false body: - - value: |- + - + value: |- @@ -149,6 +175,8 @@ translations: + + format: gutenberg summary: '' diff --git a/packages/drupal/test_content/content/node/ceb9b2a7-4c4c-4084-ada9-d5f6505d466b.yml b/packages/drupal/test_content/content/node/ceb9b2a7-4c4c-4084-ada9-d5f6505d466b.yml index 6c19a491d..704d39565 100644 --- a/packages/drupal/test_content/content/node/ceb9b2a7-4c4c-4084-ada9-d5f6505d466b.yml +++ b/packages/drupal/test_content/content/node/ceb9b2a7-4c4c-4084-ada9-d5f6505d466b.yml @@ -67,6 +67,8 @@ default: + + format: gutenberg summary: '' diff --git a/tests/schema/specs/blocks.spec.ts b/tests/schema/specs/blocks.spec.ts index 5a9c453af..762315702 100644 --- a/tests/schema/specs/blocks.spec.ts +++ b/tests/schema/specs/blocks.spec.ts @@ -53,6 +53,14 @@ test('Blocks', async () => { text openInNewTab } + ... on BlockQuote { + quote + author + role + image { + __typename + } + } } } { @@ -161,6 +169,15 @@ test('Blocks', async () => { "text": "CTA with link to media", "url": "/media/[numeric]", }, + { + "__typename": "BlockQuote", + "author": "John Doe", + "image": { + "__typename": "MediaImage", + }, + "quote": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus sagittis nisi nec neque porta, a ornare ligula efficitur.", + "role": "Project manager", + }, { "__typename": "BlockMarkup", "markup": " @@ -209,6 +226,13 @@ test('Blocks', async () => { "text": null, "url": null, }, + { + "__typename": "BlockQuote", + "author": "Jane Doe", + "image": null, + "quote": "In vitae diam quis odio tincidunt faucibus eget ut libero", + "role": null, + }, ], "hero": { "__typename": "Hero", From c6cf6db03c825b5a6393b1fce1b0cb5488f4513c Mon Sep 17 00:00:00 2001 From: Luqmaan Essop Date: Wed, 17 Apr 2024 09:02:17 +0000 Subject: [PATCH 7/7] style: add block quote styling --- .../Organisms/PageContent/BlockMarkup.tsx | 1 - .../PageContent/BlockQuote.stories.ts | 23 ++++++++++ .../Organisms/PageContent/BlockQuote.tsx | 46 +++++++++++++++++-- packages/ui/src/tailwind.css | 14 ++++++ 4 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 packages/ui/src/components/Organisms/PageContent/BlockQuote.stories.ts diff --git a/packages/ui/src/components/Organisms/PageContent/BlockMarkup.tsx b/packages/ui/src/components/Organisms/PageContent/BlockMarkup.tsx index 443b8fd19..a83f81b79 100644 --- a/packages/ui/src/components/Organisms/PageContent/BlockMarkup.tsx +++ b/packages/ui/src/components/Organisms/PageContent/BlockMarkup.tsx @@ -18,7 +18,6 @@ export function BlockMarkup(props: BlockMarkupFragment) { className={clsx([ 'mx-auto max-w-3xl prose lg:prose-xl mt-10', 'prose-a:text-indigo-600', - 'prose-blockquote:border-indigo-200', 'prose-em:text-indigo-600', 'prose-strong:text-indigo-600', 'marker:text-indigo-600 marker:font-bold', diff --git a/packages/ui/src/components/Organisms/PageContent/BlockQuote.stories.ts b/packages/ui/src/components/Organisms/PageContent/BlockQuote.stories.ts new file mode 100644 index 000000000..e5efd0c53 --- /dev/null +++ b/packages/ui/src/components/Organisms/PageContent/BlockQuote.stories.ts @@ -0,0 +1,23 @@ +import { Markup } from '@custom/schema'; +import Portrait from '@stories/portrait.jpg?as=metadata'; +import { Meta, StoryObj } from '@storybook/react'; + +import { image } from '../../../helpers/image'; +import { BlockQuote } from './BlockQuote'; + +export default { + component: BlockQuote, +} satisfies Meta; + +export const Quote = { + args: { + role: 'test role', + author: 'Author name', + image: { + source: image({ src: Portrait.src, width: 50, height: 50 }), + alt: 'Portrait', + }, + quote: + '

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

' as Markup, + }, +} satisfies StoryObj; diff --git a/packages/ui/src/components/Organisms/PageContent/BlockQuote.tsx b/packages/ui/src/components/Organisms/PageContent/BlockQuote.tsx index 4676f6302..adab18a20 100644 --- a/packages/ui/src/components/Organisms/PageContent/BlockQuote.tsx +++ b/packages/ui/src/components/Organisms/PageContent/BlockQuote.tsx @@ -1,7 +1,47 @@ -import { BlockQuoteFragment } from '@custom/schema'; +import { BlockQuoteFragment, Html, Image } from '@custom/schema'; import React from 'react'; export function BlockQuote(props: BlockQuoteFragment) { - console.log('Block quote props:', props); - return <>; + return ( +
+
+ + Quote Symbol + + + {props.quote && } +
+ {props.image && ( + {props.image.alt + )} +
+ {props.author &&

{props.author}

} +
+ {props.role && ( +

+ / + + {props.role} + +

+ )} +
+
+
+ ); } diff --git a/packages/ui/src/tailwind.css b/packages/ui/src/tailwind.css index 33a4a800a..d432c1677 100644 --- a/packages/ui/src/tailwind.css +++ b/packages/ui/src/tailwind.css @@ -7,3 +7,17 @@ :where(blockquote):not(:where([class~='not-prose'], [class~='not-prose'] *)) { padding-left: 0 !important; } + +.prose + :where(blockquote p:first-of-type):not( + :where([class~='not-prose'], [class~='not-prose'] *) + )::before { + content: '' !important; +} + +.prose + :where(blockquote p:first-of-type):not( + :where([class~='not-prose'], [class~='not-prose'] *) + )::after { + content: '' !important; +}