11"use client" ;
22
33import { XIcon } from "lucide-react" ;
4+ import { useState } from "react" ;
45import { Button } from "@/components/ui/button" ;
56import { useLocalStorage } from "@/hooks/useLocalStorage" ;
67
7- export function DismissibleAlert ( props : {
8+ export function DismissibleAlert (
9+ props : {
10+ title : React . ReactNode ;
11+ header ?: React . ReactNode ;
12+ className ?: string ;
13+ description : React . ReactNode ;
14+ children ?: React . ReactNode ;
15+ } & (
16+ | {
17+ preserveState : true ;
18+ localStorageId : string ;
19+ }
20+ | {
21+ preserveState : false ;
22+ }
23+ ) ,
24+ ) {
25+ if ( props . preserveState ) {
26+ return < DismissibleAlertWithLocalStorage { ...props } /> ;
27+ }
28+
29+ return < DismissibleAlertWithoutLocalStorage { ...props } /> ;
30+ }
31+
32+ function DismissibleAlertWithLocalStorage ( props : {
833 title : React . ReactNode ;
34+ header ?: React . ReactNode ;
935 description : React . ReactNode ;
36+ children ?: React . ReactNode ;
1037 localStorageId : string ;
1138} ) {
1239 const [ isVisible , setIsVisible ] = useLocalStorage (
@@ -17,19 +44,48 @@ export function DismissibleAlert(props: {
1744
1845 if ( ! isVisible ) return null ;
1946
47+ return < AlertUI { ...props } onClose = { ( ) => setIsVisible ( false ) } /> ;
48+ }
49+
50+ function DismissibleAlertWithoutLocalStorage ( props : {
51+ title : React . ReactNode ;
52+ description : React . ReactNode ;
53+ children ?: React . ReactNode ;
54+ } ) {
55+ const [ isVisible , setIsVisible ] = useState ( true ) ;
56+
57+ if ( ! isVisible ) return null ;
58+
59+ return < AlertUI { ...props } onClose = { ( ) => setIsVisible ( false ) } /> ;
60+ }
61+
62+ function AlertUI ( props : {
63+ title : React . ReactNode ;
64+ header ?: React . ReactNode ;
65+ description : React . ReactNode ;
66+ children ?: React . ReactNode ;
67+ className ?: string ;
68+ onClose : ( ) => void ;
69+ } ) {
2070 return (
21- < div className = "relative rounded-lg border border-border bg-card p-4" >
22- < Button
23- aria-label = "Close alert"
24- className = "absolute top-4 right-4 h-auto w-auto p-1 text-muted-foreground"
25- onClick = { ( ) => setIsVisible ( false ) }
26- variant = "ghost"
27- >
28- < XIcon className = "size-5" />
29- </ Button >
30- < div >
31- < h2 className = "mb-0.5 font-semibold" > { props . title } </ h2 >
32- < div className = "text-muted-foreground text-sm" > { props . description } </ div >
71+ < div className = { props . className } >
72+ < div className = "relative rounded-lg border border-border bg-card p-4 lg:p-6 overflow-hidden" >
73+ < Button
74+ aria-label = "Close alert"
75+ className = "absolute top-4 right-4 h-auto w-auto p-1 text-muted-foreground"
76+ onClick = { props . onClose }
77+ variant = "ghost"
78+ >
79+ < XIcon className = "size-5" />
80+ </ Button >
81+ < div >
82+ { props . header }
83+ < h2 className = "mb-0.5 font-semibold" > { props . title } </ h2 >
84+ < div className = "text-muted-foreground text-sm" >
85+ { props . description }
86+ </ div >
87+ { props . children }
88+ </ div >
3389 </ div >
3490 </ div >
3591 ) ;
0 commit comments