diff --git a/packages/drupal/gutenberg_blocks/css/edit.css b/packages/drupal/gutenberg_blocks/css/edit.css
index 252a81b73..1ef6f0086 100644
--- a/packages/drupal/gutenberg_blocks/css/edit.css
+++ b/packages/drupal/gutenberg_blocks/css/edit.css
@@ -82,3 +82,21 @@
height: 1.25rem;
content: url("data:image/svg+xml,%3Csvg aria-hidden='true' xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='%236B7280' viewBox='0 0 20 24'%3E%3Cpath fill-rule='evenodd' d='M2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12Zm9.008-3.018a1.502 1.502 0 0 1 2.522 1.159v.024a1.44 1.44 0 0 1-1.493 1.418 1 1 0 0 0-1.037.999V14a1 1 0 1 0 2 0v-.539a3.44 3.44 0 0 0 2.529-3.256 3.502 3.502 0 0 0-7-.255 1 1 0 0 0 2 .076c.014-.398.187-.774.48-1.044Zm.982 7.026a1 1 0 1 0 0 2H12a1 1 0 1 0 0-2h-.01Z' clip-rule='evenodd'/%3E%3C/svg%3E%0A");
}
+.gutenberg__editor .custom-block-accordion-item-text.questionmark h3::before {
+ margin-right: 7px;
+ content: url("data:image/svg+xml,%3Csvg aria-hidden='true' xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='%236B7280' viewBox='0 0 20 24'%3E%3Cpath fill-rule='evenodd' d='M2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12Zm9.008-3.018a1.502 1.502 0 0 1 2.522 1.159v.024a1.44 1.44 0 0 1-1.493 1.418 1 1 0 0 0-1.037.999V14a1 1 0 1 0 2 0v-.539a3.44 3.44 0 0 0 2.529-3.256 3.502 3.502 0 0 0-7-.255 1 1 0 0 0 2 .076c.014-.398.187-.774.48-1.044Zm.982 7.026a1 1 0 1 0 0 2H12a1 1 0 1 0 0-2h-.01Z' clip-rule='evenodd'/%3E%3C/svg%3E%0A");
+}
+
+.gutenberg__editor .custom-block-accordion-item-text.checkmark h3::before {
+ margin-right: 7px;
+ content: url("data:image/svg+xml,%3Csvg aria-hidden='true' xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='%236B7280' viewBox='0 0 20 24'%3E%3Cpath fill-rule='evenodd' d='M2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12Zm13.707-1.293a1 1 0 0 0-1.414-1.414L11 12.586l-1.793-1.793a1 1 0 0 0-1.414 1.414l2.5 2.5a1 1 0 0 0 1.414 0l4-4Z' clip-rule='evenodd'%3E%3C/path%3E%3C/svg%3E");
+}
+
+.gutenberg__editor .custom-block-accordion-item-text.arrow h3::before {
+ margin-right: 7px;
+ content: url("data:image/svg+xml,%3Csvg aria-hidden='true' xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='%236B7280' %3E%3Cpath fill-rule='evenodd' d='M10 18a8 8 0 1 0 0-16 8 8 0 0 0 0 16ZM6.75 9.25a.75.75 0 0 0 0 1.5h4.59l-2.1 1.95a.75.75 0 0 0 1.02 1.1l3.5-3.25a.75.75 0 0 0 0-1.1l-3.5-3.25a.75.75 0 1 0-1.02 1.1l2.1 1.95H6.75Z' clip-rule='evenodd'%3E%3C/path%3E%3C/svg%3E");
+}
+
+.gutenberg__editor .edit-post-visual-editor__content-area a.no-underline {
+ text-decoration: none;
+}
diff --git a/packages/drupal/gutenberg_blocks/src/Plugin/Validation/GutenbergValidator/AccordionItemTextValidator.php b/packages/drupal/gutenberg_blocks/src/Plugin/Validation/GutenbergValidator/AccordionItemTextValidator.php
new file mode 100644
index 000000000..4ab6b31ab
--- /dev/null
+++ b/packages/drupal/gutenberg_blocks/src/Plugin/Validation/GutenbergValidator/AccordionItemTextValidator.php
@@ -0,0 +1,51 @@
+ [
+ 'field_label' => $this->t('Title'),
+ 'rules' => ['required'],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function validateContent($block = []): array {
+ $expectedChildren = [
+ 'validationType' => GutenbergCardinalityValidatorInterface::CARDINALITY_ANY,
+ 'min' => 1,
+ 'max' => GutenbergCardinalityValidatorInterface::CARDINALITY_UNLIMITED,
+ ];
+ return $this->validateCardinality($block, $expectedChildren);
+ }
+
+}
diff --git a/packages/drupal/gutenberg_blocks/src/Plugin/Validation/GutenbergValidator/AccordionValidator.php b/packages/drupal/gutenberg_blocks/src/Plugin/Validation/GutenbergValidator/AccordionValidator.php
new file mode 100644
index 000000000..d0bae38b0
--- /dev/null
+++ b/packages/drupal/gutenberg_blocks/src/Plugin/Validation/GutenbergValidator/AccordionValidator.php
@@ -0,0 +1,42 @@
+ 'custom/accordion-item-text',
+ 'blockLabel' => $this->t('Accordion'),
+ 'min' => 1,
+ 'max' => GutenbergCardinalityValidatorInterface::CARDINALITY_UNLIMITED,
+ ],
+ ];
+ return $this->validateCardinality($block, $expectedChildren);
+ }
+
+}
diff --git a/packages/drupal/gutenberg_blocks/src/blocks/accordion-item-text.tsx b/packages/drupal/gutenberg_blocks/src/blocks/accordion-item-text.tsx
new file mode 100644
index 000000000..aaf3f4a6d
--- /dev/null
+++ b/packages/drupal/gutenberg_blocks/src/blocks/accordion-item-text.tsx
@@ -0,0 +1,91 @@
+import clsx from 'clsx';
+import React, { Fragment } from 'react';
+import {
+ InnerBlocks,
+ InspectorControls,
+ RichText,
+} from 'wordpress__block-editor';
+import { registerBlockType } from 'wordpress__blocks';
+import { PanelBody, SelectControl } from 'wordpress__components';
+import { compose, withState } from 'wordpress__compose';
+
+// @ts-ignore
+const { t: __ } = Drupal;
+// @ts-ignore
+registerBlockType('custom/accordion-item-text', {
+ title: 'Accordion Item Text',
+ icon: 'text',
+ category: 'layout',
+ parent: ['custom/accordion'],
+ attributes: {
+ title: {
+ type: 'string',
+ },
+ icon: {
+ type: 'string',
+ },
+ },
+ // @ts-ignore
+ edit: compose(withState())((props) => {
+ const { attributes, setAttributes } = props;
+ const icons = [
+ { label: __('- Select an optional icon -'), value: '' },
+ { label: __('Checkmark'), value: 'checkmark' },
+ { label: __('Questionmark'), value: 'questionmark' },
+ { label: __('Arrow'), value: 'arrow' },
+ ];
+ setAttributes({
+ icon: attributes.icon === undefined ? '' : attributes.icon,
+ });
+
+ return (
+
A standalone paragraph with markup and link
+ + @@ -115,9 +117,23 @@ default: + + - +Incididunt laborum velit non proident nostrud velit. Minim excepteur ut aliqua nisi. Culpa laboris consectetur proident. Tempor esse ullamco et dolor proident id officia laborum voluptate nostrud elit dolore qui amet. Ex Lorem irure eu anim ipsum officia.
+ + + + + +Incididunt laborum velit non proident nostrud velit. Minim excepteur ut aliqua nisi. Culpa laboris consectetur proident. Tempor esse ullamco et dolor proident id officia laborum voluptate nostrud elit dolore qui amet. Ex Lorem irure eu anim ipsum officia.
+ + format: gutenberg summary: '' diff --git a/packages/schema/src/fragments/Page.gql b/packages/schema/src/fragments/Page.gql index cbf2227eb..59285ccc4 100644 --- a/packages/schema/src/fragments/Page.gql +++ b/packages/schema/src/fragments/Page.gql @@ -35,6 +35,8 @@ fragment Page on Page { ...BlockCta ...BlockImageWithText ...BlockQuote + ...BlockHorizontalSeparator + ...BlockAccordion } metaTags { tag diff --git a/packages/schema/src/fragments/PageContent/BlockAccordion.gql b/packages/schema/src/fragments/PageContent/BlockAccordion.gql new file mode 100644 index 000000000..0f77b257d --- /dev/null +++ b/packages/schema/src/fragments/PageContent/BlockAccordion.gql @@ -0,0 +1,13 @@ +fragment BlockAccordion on BlockAccordion { + items { + ...BlockAccordionItemText + } +} + +fragment BlockAccordionItemText on BlockAccordionItemText { + title + icon + textContent { + markup + } +} diff --git a/packages/schema/src/fragments/PageContent/BlockHorizontalSeparator.gql b/packages/schema/src/fragments/PageContent/BlockHorizontalSeparator.gql new file mode 100644 index 000000000..ef992a139 --- /dev/null +++ b/packages/schema/src/fragments/PageContent/BlockHorizontalSeparator.gql @@ -0,0 +1,5 @@ +fragment BlockHorizontalSeparator on BlockHorizontalSeparator { + # This is not really used, but until we have other real setting fields, we + # have to provide a dummy one. + markup +} diff --git a/packages/schema/src/schema.graphql b/packages/schema/src/schema.graphql index e2034acb5..fbeafa4e3 100644 --- a/packages/schema/src/schema.graphql +++ b/packages/schema/src/schema.graphql @@ -206,6 +206,8 @@ union PageContent @resolveEditorBlockType = | BlockCta | BlockImageWithText | BlockQuote + | BlockHorizontalSeparator + | BlockAccordion type BlockForm @type(id: "custom/form") { url: Url @resolveEditorBlockAttribute(key: "formId") @webformIdToUrl(id: "$") @@ -245,6 +247,16 @@ type BlockImageTeaser @default @value { ctaUrl: Url @resolveEditorBlockAttribute(key: "ctaUrl") } +type BlockAccordion @type(id: "custom/accordion") { + items: [BlockAccordionItemText!]! @resolveEditorBlockChildren +} + +type BlockAccordionItemText @default @value { + title: String! @resolveEditorBlockAttribute(key: "title") + icon: String! @resolveEditorBlockAttribute(key: "icon") + textContent: BlockMarkup @resolveEditorBlockChildren @seek(pos: 0) +} + type BlockCta @type(id: "custom/cta") { url: Url @resolveEditorBlockAttribute(key: "url") text: String @resolveEditorBlockAttribute(key: "text") @@ -283,6 +295,10 @@ type BlockQuote @type(id: "custom/quote") { image: MediaImage @resolveEditorBlockMedia } +type BlockHorizontalSeparator @type(id: "custom/horizontal-separator") { + markup: Markup! @resolveEditorBlockMarkup +} + input PaginationInput { limit: Int! offset: Int! diff --git a/packages/ui/package.json b/packages/ui/package.json index f3320b5ce..967e148ea 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -44,6 +44,7 @@ "@heroicons/react": "^2.1.1", "@hookform/resolvers": "^3.3.3", "clsx": "^2.1.0", + "flowbite-react": "^0.9.0", "framer-motion": "^10.17.4", "hast-util-is-element": "^2.1.3", "hast-util-select": "^5.0.5", diff --git a/packages/ui/src/components/Atoms/Container.css b/packages/ui/src/components/Atoms/Container.css index b30f83468..7186533ad 100644 --- a/packages/ui/src/components/Atoms/Container.css +++ b/packages/ui/src/components/Atoms/Container.css @@ -1,5 +1,5 @@ .container-page { - @apply max-w-full px-[1.25rem] md:px-[3.75rem]; + @apply max-w-full px-[1.25rem] md:px-[3.75rem] lg:px-[5rem]; } .container-content { @@ -7,7 +7,7 @@ } .container-text { - @apply max-w-[40.75rem] xl:ml-[11rem] lg:ml-[7rem]; + @apply max-w-3xl mx-auto; } .nested-container .container-page { diff --git a/packages/ui/src/components/Molecules/Breadcrumbs.stories.tsx b/packages/ui/src/components/Molecules/Breadcrumbs.stories.tsx new file mode 100644 index 000000000..9a7c6d0e5 --- /dev/null +++ b/packages/ui/src/components/Molecules/Breadcrumbs.stories.tsx @@ -0,0 +1,24 @@ +import { FrameQuery, OperationExecutor } from '@custom/schema'; +import { Meta } from '@storybook/react'; +import React from 'react'; + +import { Default as FrameStory } from '../Routes/Frame.stories'; +import { BreadCrumbs } from './Breadcrumbs'; + +export default { + component: BreadCrumbs, + parameters: { + layout: 'fullscreen', + location: new URL('local:/gatsby-turbo'), + }, +} satisfies Meta