49 lines
1.9 KiB
TypeScript
49 lines
1.9 KiB
TypeScript
import * as React from 'react'
|
|
import { cva, type VariantProps } from 'class-variance-authority'
|
|
import { cn } from '@/lib/utils'
|
|
|
|
/**
|
|
* Alert / inline message — статусная карточка с border-left accent.
|
|
* shadcn-style API: children может быть [Title, Description] или произвольный.
|
|
*/
|
|
const alertVariants = cva(
|
|
'relative w-full rounded-md border-l-4 px-4 py-3 text-body [&>svg]:text-ink-2 [&>svg]:size-4 [&>svg]:absolute [&>svg]:left-3 [&>svg]:top-3 [&>svg+*]:pl-6',
|
|
{
|
|
variants: {
|
|
variant: {
|
|
info: 'border-l-accent bg-accent-bg text-ink',
|
|
success: 'border-l-green bg-green-bg text-ink',
|
|
warning: 'border-l-warn bg-warn-bg text-ink',
|
|
danger: 'border-l-pink bg-pink-bg text-ink',
|
|
// Alias для nstart-compat: error === danger визуально.
|
|
error: 'border-l-pink bg-pink-bg text-ink',
|
|
neutral: 'border-l-line bg-surface-2 text-ink',
|
|
},
|
|
},
|
|
defaultVariants: { variant: 'info' },
|
|
},
|
|
)
|
|
|
|
export type AlertProps = React.HTMLAttributes<HTMLDivElement> &
|
|
VariantProps<typeof alertVariants> & {
|
|
title?: React.ReactNode
|
|
/** Right-aligned slot для action button(s) inside alert. */
|
|
action?: React.ReactNode
|
|
}
|
|
|
|
export const Alert = React.forwardRef<HTMLDivElement, AlertProps>(
|
|
function Alert({ className, variant, title, action, children, ...props }, ref) {
|
|
return (
|
|
<div ref={ref} role="alert" className={cn(alertVariants({ variant }), className)} {...props}>
|
|
<div className="flex items-start justify-between gap-3">
|
|
<div className="min-w-0 flex-1">
|
|
{title && <div className="font-medium mb-0.5">{title}</div>}
|
|
<div className="text-ink-2 text-body leading-snug">{children}</div>
|
|
</div>
|
|
{action && <div className="shrink-0 flex items-center gap-2">{action}</div>}
|
|
</div>
|
|
</div>
|
|
)
|
|
},
|
|
)
|