Skip to content

Commit d027194

Browse files
authored
Merge pull request #55 from oasisprotocol/mz/alert
Create custom Alert component
2 parents cfa7e2b + 25b7edf commit d027194

2 files changed

Lines changed: 88 additions & 13 deletions

File tree

src/components/alert/index.tsx

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { FC } from 'react'
2+
import { CircleAlert, CircleCheck, Info, TriangleAlert } from 'lucide-react'
3+
import { cva, type VariantProps } from 'class-variance-authority'
4+
import { cn } from '../../lib/utils'
5+
import { Alert as BaseAlert, AlertDescription, AlertTitle } from '../ui/alert'
6+
7+
const alertVariants = cva('p-2 md:p-4 gap-1 rounded-lg border', {
8+
variants: {
9+
variant: {
10+
info: 'bg-background border-border',
11+
error: 'bg-background border-destructive dark:border-[#7F2424] text-destructive',
12+
warning: 'bg-background border-warning/50 text-warning',
13+
'error-filled': 'bg-destructive/10 border-destructive dark:border-[#7F2424] text-destructive',
14+
'warning-filled':
15+
'bg-yellow-50 border-warning/50 text-warning dark:bg-yellow-900/10 dark:border-yellow-900/50 dark:text-yellow-500',
16+
success: 'bg-background border-success text-success',
17+
'success-filled': 'bg-success/10 border-success text-success',
18+
},
19+
},
20+
defaultVariants: {
21+
variant: 'info',
22+
},
23+
})
24+
25+
type AlertProps = {
26+
className?: string
27+
title?: string
28+
children?: React.ReactNode
29+
sticky?: boolean
30+
} & VariantProps<typeof alertVariants>
31+
32+
export const Alert: FC<AlertProps> = ({ className, title, variant = 'info', sticky = false, children }) => {
33+
const iconMap = {
34+
info: Info,
35+
success: CircleCheck,
36+
'success-filled': CircleCheck,
37+
error: CircleAlert,
38+
'error-filled': CircleAlert,
39+
warning: TriangleAlert,
40+
'warning-filled': TriangleAlert,
41+
}
42+
const Icon = iconMap[variant || 'info']
43+
44+
return (
45+
<BaseAlert
46+
className={cn(
47+
alertVariants({ variant }),
48+
{
49+
'sticky top-0 z-[1000] rounded-none border-0 flex justify-center items-center': sticky,
50+
},
51+
className
52+
)}
53+
>
54+
<Icon
55+
className={cn('w-4 h-4 min-w-4 min-h-4', {
56+
'mt-0.5': title,
57+
'-mt-1': !title && sticky,
58+
})}
59+
/>
60+
<div className="flex flex-col gap-1">
61+
{title && <AlertTitle className="text-inherit text-base font-medium leading-6">{title}</AlertTitle>}
62+
<AlertDescription className="text-inherit text-sm font-normal leading-5">{children}</AlertDescription>
63+
</div>
64+
</BaseAlert>
65+
)
66+
}

src/stories/Alert/Alert.stories.tsx

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type { Meta, StoryObj } from '@storybook/react-vite'
2-
import { Alert, AlertDescription, AlertTitle } from '../../components/ui/alert.tsx'
3-
import { InfoIcon } from 'lucide-react'
2+
import { Alert } from '../../components/alert'
43
import { expect, within } from 'storybook/test'
54

65
const meta: Meta<typeof Alert> = {
@@ -19,23 +18,33 @@ const meta: Meta<typeof Alert> = {
1918
},
2019
},
2120
tags: ['autodocs'],
21+
argTypes: {
22+
variant: {
23+
control: 'select',
24+
options: ['info', 'success', 'success-filled', 'warning', 'warning-filled', 'error', 'error-filled'],
25+
description: 'The variant of the alert',
26+
table: {
27+
defaultValue: { summary: 'info' },
28+
},
29+
},
30+
sticky: {
31+
control: 'boolean',
32+
description: 'Makes the alert stick to the top of its container',
33+
table: {
34+
defaultValue: { summary: 'false' },
35+
},
36+
},
37+
},
2238
}
2339

2440
export default meta
2541
type Story = StoryObj<typeof meta>
2642

27-
export const Default: Story = {
43+
export const Info: Story = {
2844
args: {
29-
children: (
30-
<>
31-
<InfoIcon />
32-
<AlertTitle>Information</AlertTitle>
33-
<AlertDescription>
34-
Alert description provides additional information about the alert.
35-
</AlertDescription>
36-
</>
37-
),
38-
variant: 'default',
45+
children: <>Alert description provides additional information about the alert.</>,
46+
variant: 'info',
47+
title: '',
3948
},
4049
play: async ({ canvasElement }) => {
4150
const canvas = within(canvasElement)

0 commit comments

Comments
 (0)