Openstatus www.openstatus.dev
at main 61 lines 1.6 kB view raw
1"use client"; 2 3import * as React from "react"; 4 5import { Button } from "@/components/ui/button"; 6import { 7 Collapsible, 8 CollapsibleContent, 9 CollapsibleTrigger, 10} from "@/components/ui/collapsible"; 11import { cn } from "@/lib/utils"; 12 13export function BlockWrapper({ 14 className, 15 children, 16 autoOpen, 17 ...props 18}: React.HTMLAttributes<HTMLDivElement> & { 19 autoOpen?: boolean; 20}) { 21 const ref = React.useRef<HTMLDivElement>(null); 22 const [isOpened, setIsOpened] = React.useState(false); 23 24 React.useEffect(() => { 25 if (ref.current && autoOpen) { 26 const height = ref.current.scrollHeight; 27 // NOTE: max-h-48 in tw equals 192px (48 * 4px) 28 if (height <= 192) { 29 setIsOpened(true); 30 } 31 } 32 }, [autoOpen]); 33 34 return ( 35 <Collapsible open={isOpened} onOpenChange={setIsOpened}> 36 <div className={cn("relative overflow-hidden", className)} {...props}> 37 <CollapsibleContent 38 forceMount 39 ref={ref} 40 className={cn("overflow-hidden", !isOpened && "max-h-48")} 41 > 42 {children} 43 </CollapsibleContent> 44 {!isOpened ? ( 45 <div 46 className={cn( 47 "absolute flex items-center justify-center bg-gradient-to-b from-transparent to-90% to-background p-2", 48 isOpened ? "inset-x-0 bottom-0 h-12" : "inset-0", 49 )} 50 > 51 <CollapsibleTrigger asChild> 52 <Button variant="outline" size="sm"> 53 Expand 54 </Button> 55 </CollapsibleTrigger> 56 </div> 57 ) : null} 58 </div> 59 </Collapsible> 60 ); 61}