Skip to content

Commit

Permalink
Merge pull request #13617 from ethereum/shadcn-alert
Browse files Browse the repository at this point in the history
Shadcn migration - alert
  • Loading branch information
wackerow authored Aug 19, 2024
2 parents ef24328 + d5ee22b commit b5df8b6
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/components/Alert/Alert.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Meta, StoryObj } from "@storybook/react"
import Alert from "."

const meta = {
title: "Molecules / Action Feedback / Alerts",
title: "Molecules / Action Feedback / Old Alerts",
component: Alert,
decorators: [
(Story) => (
Expand Down
87 changes: 87 additions & 0 deletions src/components/ui/__stories__/Alert.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import * as React from "react"
import { MdInfoOutline } from "react-icons/md"
import { Meta, StoryObj } from "@storybook/react"

import {
Alert,
AlertCloseButton,
AlertContent,
AlertDescription,
AlertTitle,
} from "../alert"
import { Center } from "../flex"

const meta = {
title: "Molecules / Action Feedback / Alerts",
component: Alert,
parameters: {
layout: "none",
},
decorators: [
(Story) => (
<Center className="min-h-[100vh]">
<Story />
</Center>
),
],
} satisfies Meta<typeof Alert>

export default meta

type Story = StoryObj<typeof meta>

const DEMO_TITLE = "Alert or callout title"
const DEMO_DESC = "This is an alert to be used for important information."

const VARIANTS = ["info", "error", "success", "warning", "update"] as const

export const Variants: Story = {
render: (args) => (
<div className="flex w-[500px] flex-col gap-4">
{VARIANTS.map((variant) => (
<Alert key={variant} variant={variant} className="w-full" {...args}>
<AlertContent>
<AlertTitle>{DEMO_TITLE}</AlertTitle>
<AlertDescription>This is a {variant} alert</AlertDescription>
</AlertContent>
</Alert>
))}
</div>
),
}

export const WithCloseButton: Story = {
render: (args) => (
<div className="flex flex-col gap-4">
{VARIANTS.map((variant) => (
<Alert key={variant} variant={variant} {...args}>
<AlertContent>
<AlertTitle>{DEMO_TITLE}</AlertTitle>
<AlertDescription>{DEMO_DESC}</AlertDescription>
</AlertContent>
<AlertCloseButton />
</Alert>
))}
</div>
),
}

export const Banner: Story = {
render: (args) => (
<div className="mx-8 flex w-full flex-col gap-4">
{VARIANTS.map((variant) => (
<Alert key={variant} variant={variant} size="full" {...args}>
<MdInfoOutline className="h-6 w-6" />
<AlertContent>
<AlertTitle>Banner use case</AlertTitle>
<AlertDescription>
<p>{DEMO_DESC}</p>
<p>{DEMO_DESC}</p>
</AlertDescription>
</AlertContent>
<AlertCloseButton />
</Alert>
))}
</div>
),
}
92 changes: 92 additions & 0 deletions src/components/ui/alert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { MdClose } from "react-icons/md"

import { cn } from "@/lib/utils/cn"

import { Button } from "./buttons/Button"

const alertVariants = cva(
"flex flex-row gap-4 items-center rounded-lg border p-4",
{
variants: {
variant: {
info: "bg-background-highlight border",
error:
"border-error bg-error-light [&_h6]:text-error [&_svg]:text-error text-gray-800",
success:
"border-success bg-success-light [&_h6]:text-success [&_svg]:text-success text-gray-800",
warning:
"border-attention-outline bg-attention-light [&_h6]:text-attention [&_svg]:text-attention text-gray-800",
update:
"bg-primary-low-contrast border-primary-high-contrast [&_h6]:text-primary-high-contrast [&_svg]:text-primary-high-contrast",
},
size: {
// Useful for banner alerts
full: "rounded-none border-none w-full",
},
},
defaultVariants: {
variant: "info",
},
}
)

const Alert = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
>(({ className, variant, size, ...props }, ref) => (
<div
ref={ref}
role="alert"
className={cn(alertVariants({ variant, size }), className)}
{...props}
/>
))
Alert.displayName = "Alert"

const AlertContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("flex flex-1 flex-col", className)} {...props} />
))
AlertContent.displayName = "AlertContent"

const AlertTitle = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLHeadingElement>
>(({ className, ...props }, ref) => (
<h6 ref={ref} className={cn("tracking-tight", className)} {...props} />
))
AlertTitle.displayName = "AlertTitle"

const AlertDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("text-sm [&_p]:leading-relaxed", className)}
{...props}
/>
))
AlertDescription.displayName = "AlertDescription"

const AlertCloseButton = React.forwardRef<
HTMLButtonElement,
React.ButtonHTMLAttributes<HTMLButtonElement>
>(({ className, ...props }, ref) => (
<Button
ref={ref}
variant="ghost"
className={cn("-me-4 rounded-full text-body", className)}
{...props}
>
<MdClose className="h-6 w-6" />
<span className="sr-only">Close</span>
</Button>
))
AlertCloseButton.displayName = "AlertCloseButton"

export { Alert, AlertCloseButton, AlertContent, AlertDescription, AlertTitle }
4 changes: 3 additions & 1 deletion src/styles/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@
/* Complementary Set */
--attention-outline: var(--attention-light);

--error-light: var(--error-light);
--error: var(--red-500);
--error-light: var(--red-100);
--error-outline: var(--error);
/* ! Deprecating error-neutral */
--error-netural: var(--red-900);

Expand Down

0 comments on commit b5df8b6

Please sign in to comment.