diff --git a/src/components/Feedback/ErrorGraphic/ErrorGraphic.stories.tsx b/src/components/Feedback/ErrorGraphic/ErrorGraphic.stories.tsx new file mode 100644 index 0000000..6dec49b --- /dev/null +++ b/src/components/Feedback/ErrorGraphic/ErrorGraphic.stories.tsx @@ -0,0 +1,43 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { ErrorGraphic } from "."; + +// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export +const meta: Meta = { + component: ErrorGraphic, + // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/7.0/react/writing-docs/docs-page + tags: ["autodocs"], + parameters: { + // More on Story layout: https://storybook.js.org/docs/react/configure/story-layout + layout: "centered", + }, + // More on argTypes: https://storybook.js.org/docs/react/api/argtypes + argTypes: { + type: { + options: ["unrecoverable", "not-found", "server"], + }, + }, + args: {}, +}; + +export default meta; +type Story = StoryObj; + +// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args +export const Unrecoverable: Story = { + // More on args: https://storybook.js.org/docs/react/writing-stories/args + args: { + type: "unrecoverable", + }, +}; + +export const NotFound: Story = { + args: { + type: "not-found", + }, +}; + +export const Server: Story = { + args: { + type: "server", + }, +}; diff --git a/src/components/Feedback/ErrorGraphic/ErrorGraphic.tsx b/src/components/Feedback/ErrorGraphic/ErrorGraphic.tsx new file mode 100644 index 0000000..6f239eb --- /dev/null +++ b/src/components/Feedback/ErrorGraphic/ErrorGraphic.tsx @@ -0,0 +1,789 @@ +import { FC } from "react"; +import { twMerge } from "tailwind-merge"; + +export type ErrorGraphicProps = React.SVGProps & { + type: ErrorGraphicType; +}; +export type ErrorGraphicType = "unrecoverable" | "not-found" | "server"; +export const ErrorGraphic: FC = ({ + type, + className, + ...props +}) => { + const darkClassName = twMerge("hidden dark:block", className); + const lightClassName = twMerge("block dark:hidden", className); + + switch (type) { + case "unrecoverable": + return ( + <> + + + + ); + case "not-found": + return ( + <> + + + + ); + case "server": + return ( + <> + + + + ); + default: + throw new Error(`Unhandled error type ${type}`); + } +}; + +// Most of these are copy and paste from https://react-svgr.com/playground/ +// Be sure to fill in `viewBox` for scaling. + +const ServerErrorDark: FC> = (props) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +const ServerErrorLight: FC> = (props) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +const UnrecoverableErrorDark: FC> = (props) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +const UnrecoverableErrorLight: FC> = (props) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +const NotFoundErrorDark: FC> = (props) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +const NotFoundErrorLight: FC> = (props) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); diff --git a/src/components/Feedback/ErrorGraphic/index.ts b/src/components/Feedback/ErrorGraphic/index.ts new file mode 100644 index 0000000..ece257f --- /dev/null +++ b/src/components/Feedback/ErrorGraphic/index.ts @@ -0,0 +1 @@ +export * from "./ErrorGraphic"; diff --git a/src/components/Feedback/GraphicalError/GraphicalError.stories.tsx b/src/components/Feedback/GraphicalError/GraphicalError.stories.tsx new file mode 100644 index 0000000..6b9742b --- /dev/null +++ b/src/components/Feedback/GraphicalError/GraphicalError.stories.tsx @@ -0,0 +1,85 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { GraphicalError } from "."; +import { Paragraph } from "../../Typography"; + +// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export +const meta: Meta = { + component: GraphicalError, + // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/7.0/react/writing-docs/docs-page + tags: ["autodocs"], + parameters: { + // More on Story layout: https://storybook.js.org/docs/react/configure/story-layout + layout: "centered", + }, + // More on argTypes: https://storybook.js.org/docs/react/api/argtypes + argTypes: { + type: { + options: ["unrecoverable", "not-found", "server"], + }, + }, + args: { + description: + "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", + className: "", + heading: "Lorem ipsum dolor sit amet", + type: "unrecoverable", + }, +}; + +export default meta; +type Story = StoryObj; + +// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args +export const Default: Story = { + // More on args: https://storybook.js.org/docs/react/writing-stories/args + args: {}, +}; + +export const TwoSentenceDescription: Story = { + args: { + description: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Consectetur lorem donec massa sapien faucibus et molestie.", + }, +}; + +export const MultipleParagraphDescription: Story = { + args: { + description: ( + <> + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. + Consectetur lorem donec massa sapien faucibus et molestie. Vitae proin + sagittis nisl rhoncus mattis rhoncus urna. Viverra ipsum nunc aliquet + bibendum. Egestas dui id ornare arcu odio ut sem nulla. Enim lobortis + scelerisque fermentum dui faucibus. Felis eget velit aliquet sagittis + id consectetur. Morbi tristique senectus et netus et malesuada fames + ac turpis. Amet risus nullam eget felis eget nunc lobortis mattis + aliquam. Cursus in hac habitasse platea dictumst quisque sagittis. + Massa eget egestas purus viverra accumsan in. Amet venenatis urna + cursus eget. Viverra maecenas accumsan lacus vel facilisis volutpat + est velit. In vitae turpis massa sed elementum tempus egestas sed. At + elementum eu facilisis sed odio morbi quis. Scelerisque fermentum dui + faucibus in. Pretium aenean pharetra magna ac placerat vestibulum + lectus mauris. Ut placerat orci nulla pellentesque dignissim enim sit + amet. Quisque id diam vel quam. + + + Condimentum id venenatis a condimentum vitae. Non arcu risus quis + varius quam quisque id diam. Tellus rutrum tellus pellentesque eu + tincidunt tortor aliquam. Nec tincidunt praesent semper feugiat. + Viverra nam libero justo laoreet. Amet tellus cras adipiscing enim eu + turpis egestas. Vehicula ipsum a arcu cursus vitae congue mauris + rhoncus aenean. Facilisis mauris sit amet massa vitae tortor. + Tincidunt ornare massa eget egestas purus viverra accumsan in. Eu mi + bibendum neque egestas congue quisque. Sagittis eu volutpat odio + facilisis mauris sit. Vulputate odio ut enim blandit volutpat maecenas + volutpat blandit aliquam. Bibendum ut tristique et egestas quis ipsum. + Ante metus dictum at tempor commodo ullamcorper. Aliquam nulla + facilisi cras fermentum odio. Et magnis dis parturient montes nascetur + ridiculus mus mauris vitae. Sed nisi lacus sed viverra tellus. + + + ), + }, +}; diff --git a/src/components/Feedback/GraphicalError/GraphicalError.tsx b/src/components/Feedback/GraphicalError/GraphicalError.tsx new file mode 100644 index 0000000..1dfd6c7 --- /dev/null +++ b/src/components/Feedback/GraphicalError/GraphicalError.tsx @@ -0,0 +1,39 @@ +import { FC, ReactNode } from "react"; +import { twMerge } from "tailwind-merge"; +import { ErrorGraphic, ErrorGraphicType } from "../ErrorGraphic"; +import { ReadabilityConstraint } from "../../Typography"; + +export type GraphicalErrorProps = { + description?: ReactNode; + className?: string; + heading: ReactNode; + type: ErrorGraphicType; +}; + +export const GraphicalError: FC = function ({ + description, + className, + type, + heading, +}) { + return ( +
+
+ +
+
+

+ {heading} +

+ {description && ( + {description} + )} +
+
+ ); +}; diff --git a/src/components/Feedback/GraphicalError/index.ts b/src/components/Feedback/GraphicalError/index.ts new file mode 100644 index 0000000..5da39ee --- /dev/null +++ b/src/components/Feedback/GraphicalError/index.ts @@ -0,0 +1 @@ +export * from "./GraphicalError"; diff --git a/src/components/Feedback/index.ts b/src/components/Feedback/index.ts new file mode 100644 index 0000000..6bdfff9 --- /dev/null +++ b/src/components/Feedback/index.ts @@ -0,0 +1,2 @@ +export * from "./ErrorGraphic"; +export * from "./GraphicalError"; diff --git a/src/components/Typography/ReadabilityConstraint/ReadabilityConstraint.stories.tsx b/src/components/Typography/ReadabilityConstraint/ReadabilityConstraint.stories.tsx new file mode 100644 index 0000000..7eb2a46 --- /dev/null +++ b/src/components/Typography/ReadabilityConstraint/ReadabilityConstraint.stories.tsx @@ -0,0 +1,28 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { ReadabilityConstraint } from "."; + +// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export +const meta: Meta = { + component: ReadabilityConstraint, + // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/7.0/react/writing-docs/docs-page + tags: ["autodocs"], + parameters: { + // More on Story layout: https://storybook.js.org/docs/react/configure/story-layout + layout: "centered", + }, + // More on argTypes: https://storybook.js.org/docs/react/api/argtypes + argTypes: {}, + args: { + children: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Consectetur lorem donec massa sapien faucibus et molestie. Vitae proin sagittis nisl rhoncus mattis rhoncus urna. Viverra ipsum nunc aliquet bibendum. Egestas dui id ornare arcu odio ut sem nulla. Enim lobortis scelerisque fermentum dui faucibus. Felis eget velit aliquet sagittis id consectetur. Morbi tristique senectus et netus et malesuada fames ac turpis. Amet risus nullam eget felis eget nunc lobortis mattis aliquam. Cursus in hac habitasse platea dictumst quisque sagittis. Massa eget egestas purus viverra accumsan in. Amet venenatis urna cursus eget. Viverra maecenas accumsan lacus vel facilisis volutpat est velit. In vitae turpis massa sed elementum tempus egestas sed. At elementum eu facilisis sed odio morbi quis. Scelerisque fermentum dui faucibus in. Pretium aenean pharetra magna ac placerat vestibulum lectus mauris. Ut placerat orci nulla pellentesque dignissim enim sit amet. Quisque id diam vel quam.", + }, +}; + +export default meta; +type Story = StoryObj; + +// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args +export const Default: Story = { + // More on args: https://storybook.js.org/docs/react/writing-stories/args + args: {}, +}; diff --git a/src/components/Typography/ReadabilityConstraint/ReadabilityConstraint.tsx b/src/components/Typography/ReadabilityConstraint/ReadabilityConstraint.tsx new file mode 100644 index 0000000..26c010d --- /dev/null +++ b/src/components/Typography/ReadabilityConstraint/ReadabilityConstraint.tsx @@ -0,0 +1,14 @@ +import { FC } from "react"; +import { twMerge } from "tailwind-merge"; + +export type ReadabilityConstraintProps = React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLDivElement +>; +export const ReadabilityConstraint: FC = function ( + props +) { + return ( +
+ ); +}; diff --git a/src/components/Typography/ReadabilityConstraint/index.ts b/src/components/Typography/ReadabilityConstraint/index.ts new file mode 100644 index 0000000..e7343f9 --- /dev/null +++ b/src/components/Typography/ReadabilityConstraint/index.ts @@ -0,0 +1 @@ +export * from "./ReadabilityConstraint"; diff --git a/src/components/Typography/index.ts b/src/components/Typography/index.ts index 8fd1819..ace5cb8 100644 --- a/src/components/Typography/index.ts +++ b/src/components/Typography/index.ts @@ -1,3 +1,4 @@ export * from "./LineClamp"; export * from "./Link"; export * from "./Paragraph"; +export * from "./ReadabilityConstraint"; diff --git a/src/components/index.ts b/src/components/index.ts index 5077032..25ac7d8 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1,2 +1,3 @@ export * from "./Buttons"; +export * from "./Feedback"; export * from "./Typography";