diff --git a/src/components/alert/index.tsx b/src/components/alert/index.tsx new file mode 100644 index 00000000..32c435b1 --- /dev/null +++ b/src/components/alert/index.tsx @@ -0,0 +1,66 @@ +import { FC } from 'react' +import { CircleAlert, CircleCheck, Info, TriangleAlert } from 'lucide-react' +import { cva, type VariantProps } from 'class-variance-authority' +import { cn } from '../../lib/utils' +import { Alert as BaseAlert, AlertDescription, AlertTitle } from '../ui/alert' + +const alertVariants = cva('p-2 md:p-4 gap-1 rounded-lg border', { + variants: { + variant: { + info: 'bg-background border-border', + error: 'bg-background border-destructive dark:border-[#7F2424] text-destructive', + warning: 'bg-background border-warning/50 text-warning', + 'error-filled': 'bg-destructive/10 border-destructive dark:border-[#7F2424] text-destructive', + 'warning-filled': + 'bg-yellow-50 border-warning/50 text-warning dark:bg-yellow-900/10 dark:border-yellow-900/50 dark:text-yellow-500', + success: 'bg-background border-success text-success', + 'success-filled': 'bg-success/10 border-success text-success', + }, + }, + defaultVariants: { + variant: 'info', + }, +}) + +type AlertProps = { + className?: string + title?: string + children?: React.ReactNode + sticky?: boolean +} & VariantProps + +export const Alert: FC = ({ className, title, variant = 'info', sticky = false, children }) => { + const iconMap = { + info: Info, + success: CircleCheck, + 'success-filled': CircleCheck, + error: CircleAlert, + 'error-filled': CircleAlert, + warning: TriangleAlert, + 'warning-filled': TriangleAlert, + } + const Icon = iconMap[variant || 'info'] + + return ( + + +
+ {title && {title}} + {children} +
+
+ ) +} diff --git a/src/stories/Alert/Alert.stories.tsx b/src/stories/Alert/Alert.stories.tsx index 7c3a7688..43994fe7 100644 --- a/src/stories/Alert/Alert.stories.tsx +++ b/src/stories/Alert/Alert.stories.tsx @@ -1,6 +1,5 @@ import type { Meta, StoryObj } from '@storybook/react-vite' -import { Alert, AlertDescription, AlertTitle } from '../../components/ui/alert.tsx' -import { InfoIcon } from 'lucide-react' +import { Alert } from '../../components/alert' import { expect, within } from 'storybook/test' const meta: Meta = { @@ -19,23 +18,33 @@ const meta: Meta = { }, }, tags: ['autodocs'], + argTypes: { + variant: { + control: 'select', + options: ['info', 'success', 'success-filled', 'warning', 'warning-filled', 'error', 'error-filled'], + description: 'The variant of the alert', + table: { + defaultValue: { summary: 'info' }, + }, + }, + sticky: { + control: 'boolean', + description: 'Makes the alert stick to the top of its container', + table: { + defaultValue: { summary: 'false' }, + }, + }, + }, } export default meta type Story = StoryObj -export const Default: Story = { +export const Info: Story = { args: { - children: ( - <> - - Information - - Alert description provides additional information about the alert. - - - ), - variant: 'default', + children: <>Alert description provides additional information about the alert., + variant: 'info', + title: '', }, play: async ({ canvasElement }) => { const canvas = within(canvasElement)