Skip to content

Commit

Permalink
Add banner component, add missing Storybook stories (#103)
Browse files Browse the repository at this point in the history
  • Loading branch information
evadecker authored Sep 22, 2024
1 parent 4f1b0b9 commit 82b2055
Show file tree
Hide file tree
Showing 20 changed files with 377 additions and 15 deletions.
5 changes: 5 additions & 0 deletions .changeset/happy-coats-yell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"namesake": patch
---

Add banner component, display banners for login error and success messages
5 changes: 5 additions & 0 deletions .changeset/pink-islands-sparkle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"namesake": patch
---

Fix login screen sizing and padding
45 changes: 45 additions & 0 deletions src/components/Badge/Badge.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import type { Meta, StoryObj } from "@storybook/react";

import { Badge } from "./Badge";

const meta = {
component: Badge,
} satisfies Meta<typeof Badge>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
children: "Default",
},
};

export const Info: Story = {
args: {
children: "Info",
variant: "info",
},
};

export const Success: Story = {
args: {
children: "Success",
variant: "success",
},
};

export const Warning: Story = {
args: {
children: "Warning",
variant: "warning",
},
};

export const Danger: Story = {
args: {
children: "Error",
variant: "danger",
},
};
45 changes: 45 additions & 0 deletions src/components/Banner/Banner.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import type { Meta, StoryObj } from "@storybook/react";

import { Banner } from "./Banner";

const meta = {
component: Banner,
} satisfies Meta<typeof Banner>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
children: "Basic information",
},
};

export const Info: Story = {
args: {
children: "Here's some handy information",
variant: "info",
},
};

export const Success: Story = {
args: {
children: "Something successful happened",
variant: "success",
},
};

export const Danger: Story = {
args: {
children: "Something went wrong",
variant: "danger",
},
};

export const Warning: Story = {
args: {
children: "Be careful!",
variant: "warning",
},
};
68 changes: 68 additions & 0 deletions src/components/Banner/Banner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import {
type RemixiconComponentType,
RiAlertLine,
RiCheckLine,
RiErrorWarningLine,
RiInformationLine,
} from "@remixicon/react";
import { tv } from "tailwind-variants";

export interface BannerProps {
children: React.ReactNode;
icon?: RemixiconComponentType;
variant?: "info" | "success" | "danger" | "warning";
}

const bannerStyles = tv({
base: "flex gap-2 p-3 pr-4 items-start w-full text-sm rounded-lg bg-gray-3 dark:bg-graydark-3 text-gray-dim",
variants: {
variant: {
info: "bg-blue-3 dark:bg-bluedark-3 text-blue-normal",
success: "bg-green-3 dark:bg-greendark-3 text-green-normal",
danger: "bg-red-3 dark:bg-reddark-3 text-red-normal",
warning: "bg-amber-3 dark:bg-amberdark-3 text-amber-normal",
},
},
defaultVariants: {
variant: undefined,
},
});

const iconStyles = tv({
base: "text-gray-9 dark:text-graydark-9 shrink-0",
variants: {
variant: {
info: "text-blue-10 dark:text-bluedark-10",
success: "text-green-10 dark:text-greendark-10",
danger: "text-red-10 dark:text-reddark-10",
warning: "text-amber-10 dark:text-amberdark-10",
},
},
defaultVariants: {
variant: undefined,
},
});

export function Banner({ children, icon: Icon, variant }: BannerProps) {
const DefaultIcon = () => {
switch (variant) {
case "success":
return RiCheckLine;
case "danger":
return RiErrorWarningLine;
case "warning":
return RiAlertLine;
default:
return RiInformationLine;
}
};

Icon = Icon ?? DefaultIcon();

return (
<div className={bannerStyles({ variant })}>
<Icon size={20} className={iconStyles({ variant })} />
{children}
</div>
);
}
1 change: 1 addition & 0 deletions src/components/Banner/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./Banner";
17 changes: 17 additions & 0 deletions src/components/Card/Card.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Meta, StoryObj } from "@storybook/react";

import { Card } from "./Card";

const meta = {
component: Card,
} satisfies Meta<typeof Card>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
children: "Default",
},
};
2 changes: 1 addition & 1 deletion src/components/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export function Card({ children, className }: CardProps) {
<div
className={twMerge(
className,
"p-6 bg-gray-subtle border border-gray-dim rounded-xl",
"p-6 text-gray-normal bg-gray-subtle border border-gray-dim rounded-xl",
)}
>
{children}
Expand Down
38 changes: 38 additions & 0 deletions src/components/Empty/Empty.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import type { Meta, StoryObj } from "@storybook/react";

import { RiQuestionLine } from "@remixicon/react";
import { Empty } from "./Empty";

const meta = {
component: Empty,
} satisfies Meta<typeof Empty>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
icon: RiQuestionLine,
title: "Page not found",
},
};

export const Subtitle: Story = {
args: {
icon: RiQuestionLine,
title: "Page not found",
subtitle: "We couldn't find that page.",
},
};

export const Button: Story = {
args: {
icon: RiQuestionLine,
title: "Page not found",
subtitle: "We couldn't find that page.",
button: {
children: "Return home",
},
},
};
2 changes: 1 addition & 1 deletion src/components/Empty/Empty.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function Empty({
return (
<div
className={twMerge(
"flex flex-1 flex-col items-center justify-center gap-4 w-full min-h-80",
"flex flex-1 flex-col items-center justify-center gap-4 w-full min-h-80 text-gray-normal",
className,
)}
>
Expand Down
16 changes: 16 additions & 0 deletions src/components/FileTrigger/FileTrigger.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { Meta } from "@storybook/react";

import { Button } from "../Button";
import { FileTrigger } from "./FileTrigger";

const meta = {
component: FileTrigger,
} satisfies Meta<typeof FileTrigger>;

export default meta;

export const Default = (args: any) => (
<FileTrigger {...args}>
<Button>Upload file</Button>
</FileTrigger>
);
13 changes: 13 additions & 0 deletions src/components/Logo/Logo.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { Meta, StoryObj } from "@storybook/react";

import { Logo } from "./Logo";

const meta = {
component: Logo,
} satisfies Meta<typeof Logo>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {};
2 changes: 1 addition & 1 deletion src/components/Logo/Logo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export interface LogoProps {
export const Logo = ({ className }: LogoProps) => (
<svg
aria-label="namesake"
className={twMerge("w-auto", className)}
className={twMerge("w-auto text-gray-normal", className)}
fill="currentColor"
height="30"
role="img"
Expand Down
46 changes: 46 additions & 0 deletions src/components/PageHeader/PageHeader.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { Meta, StoryObj } from "@storybook/react";

import { Badge } from "../Badge";
import { Button } from "../Button";
import { PageHeader } from "./PageHeader";

const meta = {
component: PageHeader,
parameters: {
layout: "padded",
},
} satisfies Meta<typeof PageHeader>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
title: "Court Order",
},
};

export const Badged: Story = {
args: {
title: "Court Order",
badge: <Badge>MA</Badge>,
},
};

export const Subtitle: Story = {
args: {
title: "Court Order",
badge: <Badge>MA</Badge>,
subtitle: "Case #123456",
},
};

export const Actions: Story = {
args: {
title: "Court Order",
badge: <Badge>MA</Badge>,
subtitle: "Case #123456",
children: <Button>Mark complete</Button>,
},
};
2 changes: 1 addition & 1 deletion src/components/PageHeader/PageHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const PageHeader = ({
children,
}: PageHeaderProps) => {
return (
<header className="flex items-center justify-between pb-6">
<header className="flex items-center justify-between pb-6 gap-6 text-gray-normal">
<div className="flex flex-col gap-1">
<div className="flex gap-2 items-center">
<h1 className="text-2xl font-semibold">{title}</h1>
Expand Down
20 changes: 20 additions & 0 deletions src/components/RichTextEditor/RichTextEditor.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Meta, StoryObj } from "@storybook/react";

import { RichTextEditor } from "./RichTextEditor";

const meta = {
component: RichTextEditor,
parameters: {
layout: "padded",
},
} satisfies Meta<typeof RichTextEditor>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
markdown: "hello",
},
};
8 changes: 6 additions & 2 deletions src/components/RichTextEditor/RichTextEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,19 @@ import {
} from "@mdxeditor/editor";
import "@mdxeditor/editor/style.css";
import { useRef } from "react";
import { twMerge } from "tailwind-merge";

export interface RichTextEditorProps extends MDXEditorProps {}

export function RichTextEditor(props: RichTextEditorProps) {
export function RichTextEditor({ className, ...props }: RichTextEditorProps) {
const ref = useRef<MDXEditorMethods>(null);

return (
<MDXEditor
className="dark-theme dark-editor border border-gray-dim rounded-lg flex flex-col"
className={twMerge(
className,
"dark-theme dark-editor border border-gray-dim text-gray-normal rounded-lg flex flex-col",
)}
contentEditableClassName="prose dark:prose-invert"
suppressHtmlProcessing
{...props}
Expand Down
Loading

0 comments on commit 82b2055

Please sign in to comment.