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 ( + + + + { + setAttributes({ + icon: newValue, + }); + }} + /> + + +
+
{__('Accordion Item Text')}
+
+ { + setAttributes({ title: newValue }); + }} + /> + +
+
+
+ ); + }), + + save: () => { + return ; + }, +}); diff --git a/packages/drupal/gutenberg_blocks/src/blocks/accordion.tsx b/packages/drupal/gutenberg_blocks/src/blocks/accordion.tsx new file mode 100644 index 000000000..924746dd8 --- /dev/null +++ b/packages/drupal/gutenberg_blocks/src/blocks/accordion.tsx @@ -0,0 +1,25 @@ +import { InnerBlocks } from 'wordpress__block-editor'; +import { registerBlockType } from 'wordpress__blocks'; + +// @ts-ignore +const { t: __ } = Drupal; + +registerBlockType('custom/accordion', { + title: __('Accordion'), + icon: 'menu', + category: 'layout', + attributes: {}, + edit: () => { + return ( +
+
{__('Accordion')}
+ +
+ ); + }, + save: () => , +}); diff --git a/packages/drupal/gutenberg_blocks/src/blocks/cta.tsx b/packages/drupal/gutenberg_blocks/src/blocks/cta.tsx index 83bfd63de..5b70375d3 100644 --- a/packages/drupal/gutenberg_blocks/src/blocks/cta.tsx +++ b/packages/drupal/gutenberg_blocks/src/blocks/cta.tsx @@ -1,3 +1,4 @@ +import clsx from 'clsx'; import { // @ts-ignore __experimentalLinkControl as LinkControl, @@ -14,6 +15,23 @@ const { t: __ } = Drupal; // @ts-ignore const { setPlainTextAttribute } = silverbackGutenbergUtils; +const ArrowRightIcon = () => ( + + + +); + // @ts-ignore registerBlockType('custom/cta', { title: 'CTA', @@ -50,23 +68,33 @@ registerBlockType('custom/cta', { edit: compose(withState({}))((props) => { return (
- { - setPlainTextAttribute(props, 'text', text); - }} - /> + + { + setPlainTextAttribute(props, 'text', text); + }} + /> + {typeof props.attributes.icon !== 'undefined' && + props.attributes.icon === 'ARROW' && } + string }; + +const { t: __ } = Drupal; + +// @ts-ignore +registerBlockType(`custom/horizontal-separator`, { + title: __('Horizontal separator'), + icon: 'minus', + category: 'text', + attributes: {}, + // @ts-ignore + edit: compose(withState())(() => { + return
; + }), + save() { + return null; + }, +}); diff --git a/packages/drupal/gutenberg_blocks/src/index.ts b/packages/drupal/gutenberg_blocks/src/index.ts index 2763bdad8..e2c0159f7 100644 --- a/packages/drupal/gutenberg_blocks/src/index.ts +++ b/packages/drupal/gutenberg_blocks/src/index.ts @@ -9,3 +9,6 @@ import './blocks/image-with-text'; import './filters/list'; import './blocks/cta'; import './blocks/quote'; +import './blocks/horizontal-separator'; +import './blocks/accordion'; +import './blocks/accordion-item-text'; 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 3f3c9aa3a..465669703 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 @@ -55,6 +55,8 @@ default:

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.

+ + + + + +
  • Moitié-moitié
  • Fribourgeoise
+ + + +

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; + +export const Default = { + render: () => { + return ( + + + + ); + }, +}; diff --git a/packages/ui/src/components/Molecules/Breadcrumbs.tsx b/packages/ui/src/components/Molecules/Breadcrumbs.tsx new file mode 100644 index 000000000..431291137 --- /dev/null +++ b/packages/ui/src/components/Molecules/Breadcrumbs.tsx @@ -0,0 +1,56 @@ +import { Link } from '@custom/schema'; +import { ChevronRightIcon } from '@heroicons/react/24/outline'; +import clsx from 'clsx'; +import React from 'react'; + +import { isTruthy } from '../../utils/isTruthy'; +import { useBreadcrumbs } from '../Routes/Menu'; + +export function BreadCrumbs() { + const breadcrumbs = useBreadcrumbs(); + + if (!breadcrumbs.length) { + return null; + } + + return ( +
+ +
+ ); +} diff --git a/packages/ui/src/components/Organisms/Footer.tsx b/packages/ui/src/components/Organisms/Footer.tsx index c41d751be..73dc34bdf 100644 --- a/packages/ui/src/components/Organisms/Footer.tsx +++ b/packages/ui/src/components/Organisms/Footer.tsx @@ -21,11 +21,13 @@ export function Footer() { return (