From 80a8cb5ede49f1d329d4d84e20135a26b3d71b0f Mon Sep 17 00:00:00 2001 From: Spencer Peace Date: Tue, 24 Dec 2024 12:55:52 +0100 Subject: [PATCH] feat(add InlineNotice to InfoBoxItem) --- app/components/InfoBoxItem.tsx | 14 +++-- app/components/__test__/InfoBoxItem.test.tsx | 21 ++++++++ app/services/cms/models/StrapiInfoBoxItem.ts | 6 +++ .../cms/models/StrapiInlineNotice.tsx | 2 +- app/services/errorPages/fallbackInfobox.ts | 1 + stories/InfoBoxItem.stories.tsx | 51 +++++++++++++++++++ 6 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 stories/InfoBoxItem.stories.tsx diff --git a/app/components/InfoBoxItem.tsx b/app/components/InfoBoxItem.tsx index b5749aacd..246c501ad 100644 --- a/app/components/InfoBoxItem.tsx +++ b/app/components/InfoBoxItem.tsx @@ -1,4 +1,6 @@ import classNames from "classnames"; +import type { InlineNoticeProps } from "~/components/InlineNotice"; +import { InlineNotice } from "~/components/InlineNotice"; import { arrayIsNonEmpty } from "~/util/array"; import Button, { type ButtonProps } from "./Button"; import ButtonContainer from "./ButtonContainer"; @@ -14,6 +16,7 @@ export type InfoBoxItemProps = { image?: ImageProps; content?: string; details?: DetailsProps[]; + inlineNotices?: InlineNoticeProps[]; buttons?: ButtonProps[]; separator?: boolean; }; @@ -25,6 +28,7 @@ const InfoBoxItem = ({ image, content, details, + inlineNotices, buttons, separator, }: InfoBoxItemProps) => { @@ -53,10 +57,12 @@ const InfoBoxItem = ({ {label && } {headline && } {content && } - {details && - details.map((details) => ( -
- ))} + {details?.map((details) => ( +
+ ))} + {inlineNotices?.map((inlineNotice) => ( + + ))} {arrayIsNonEmpty(buttons) && ( {buttons.map((button) => ( diff --git a/app/components/__test__/InfoBoxItem.test.tsx b/app/components/__test__/InfoBoxItem.test.tsx index 7df5e864c..afe68e8b8 100644 --- a/app/components/__test__/InfoBoxItem.test.tsx +++ b/app/components/__test__/InfoBoxItem.test.tsx @@ -15,4 +15,25 @@ describe("InfoBoxItem", () => { container.querySelector(separatorStyleClass), ).not.toBeInTheDocument(); }); + it("should correctly renders inline notices when provided", () => { + const inlineNoticeTitle = "Inline Notice"; + const inlineNoticeContent = + "Testing an inline notice inside of an InfoBoxItem."; + const { getByRole } = render( + , + ); + const inlineNotice = getByRole("note"); + expect(inlineNotice).toBeInTheDocument(); + expect(inlineNotice).toHaveTextContent(inlineNoticeTitle); + expect(inlineNotice).toHaveTextContent(inlineNoticeContent); + }); }); diff --git a/app/services/cms/models/StrapiInfoBoxItem.ts b/app/services/cms/models/StrapiInfoBoxItem.ts index e03266a03..a12a5ab76 100644 --- a/app/services/cms/models/StrapiInfoBoxItem.ts +++ b/app/services/cms/models/StrapiInfoBoxItem.ts @@ -1,6 +1,10 @@ import pick from "lodash/pick"; import { z } from "zod"; import type { InfoBoxItemProps } from "~/components/InfoBoxItem"; +import { + getInlineNoticeProps, + StrapiInlineNoticeSchema, +} from "~/services/cms/models/StrapiInlineNotice"; import { omitNull } from "~/util/omitNull"; import { HasOptionalStrapiIdSchema } from "./HasStrapiId"; import { OptionalStrapiLinkIdentifierSchema } from "./HasStrapiLinkIdentifier"; @@ -16,6 +20,7 @@ export const StrapiInfoBoxItemSchema = z image: StrapiImageSchema.nullable(), content: z.string().nullable(), detailsSummary: z.array(StrapiDetailsSchema), + inlineNotice: z.array(StrapiInlineNoticeSchema), buttons: z.array(StrapiButtonSchema), }) .merge(HasOptionalStrapiIdSchema) @@ -28,6 +33,7 @@ export const getInfoBoxItemProps = ( ): InfoBoxItemProps => omitNull({ details: cmsData.detailsSummary.map(getDetailsProps), + inlineNotices: cmsData.inlineNotice.map(getInlineNoticeProps), image: getImageProps(cmsData.image), ...pick(cmsData, "label", "headline", "content", "buttons", "identifier"), }); diff --git a/app/services/cms/models/StrapiInlineNotice.tsx b/app/services/cms/models/StrapiInlineNotice.tsx index e8da4503f..460ad32cd 100644 --- a/app/services/cms/models/StrapiInlineNotice.tsx +++ b/app/services/cms/models/StrapiInlineNotice.tsx @@ -7,7 +7,7 @@ import { OptionalStrapiLinkIdentifierSchema } from "../models/HasStrapiLinkIdent import { StrapiBackgroundSchema } from "../models/StrapiBackground"; import { StrapiContainerSchema } from "../models/StrapiContainer"; -const StrapiInlineNoticeSchema = z +export const StrapiInlineNoticeSchema = z .object({ title: z.string(), tagName: z.enum(["h1", "h2", "h3", "h4", "h5", "h6", "p", "div"]), diff --git a/app/services/errorPages/fallbackInfobox.ts b/app/services/errorPages/fallbackInfobox.ts index 28d8d68e2..c9c5d86f4 100644 --- a/app/services/errorPages/fallbackInfobox.ts +++ b/app/services/errorPages/fallbackInfobox.ts @@ -10,6 +10,7 @@ const fallbackStrapiInfoBox = { { label: { text: "500", look: "ds-label-01-reg", tagName: "div" }, detailsSummary: [], + inlineNotice: [], headline: { text: "Unerwarteter Fehler", look: "ds-heading-02-reg", diff --git a/stories/InfoBoxItem.stories.tsx b/stories/InfoBoxItem.stories.tsx new file mode 100644 index 000000000..0ea40f974 --- /dev/null +++ b/stories/InfoBoxItem.stories.tsx @@ -0,0 +1,51 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import Container from "../app/components/Container"; +import InfoBoxItem, { InfoBoxItemProps } from "~/components/InfoBoxItem"; + +const meta = { + title: "Content/InfoBoxItem", + component: InfoBoxItem, + parameters: { + layout: "fullscreen", + }, + tags: ["autodocs"], +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +const defaultArgs: InfoBoxItemProps = { + identifier: "default-info-box-item-id", + headline: { + text: "InfoBoxItem Header", + }, + content: "InfoBoxItem Content", +}; + +export const Default: Story = { + args: defaultArgs, +}; + +export const InContainer: Story = { + decorators: (Story) => ( + + + + ), + args: defaultArgs, +}; + +export const WithInlineNotice: Story = { + args: { + ...defaultArgs, + inlineNotices: [ + { + title: "InlineNotice Title", + tagName: "h3", + look: "tips", + content: "Lorem **ipsum**\n\n* Lorem ipsum\n* Lorem ipsum", + }, + ], + }, +};