Files
2025-10-16 21:45:52 -07:00

14 lines
2.9 KiB
JSON

{
"name": "message-dock",
"description": "Message app dock interface",
"dependencies": [
"motion"
],
"files": [
{
"name": "message-dock.tsx",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { X } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/default/ui/button\"\n\nexport interface Message {\n id: string\n type?: \"info\" | \"success\" | \"warning\" | \"error\"\n title: string\n description?: string\n}\n\nexport interface MessageDockProps extends React.HTMLAttributes<HTMLDivElement> {\n messages: Message[]\n onClose?: (id: string) => void\n position?: \"top\" | \"bottom\" | \"top-right\" | \"bottom-right\"\n}\n\nconst MessageDock = React.forwardRef<HTMLDivElement, MessageDockProps>(\n (\n { className, messages, onClose, position = \"bottom-right\", ...props },\n ref\n ) => {\n const positionClasses = {\n top: \"top-4 left-1/2 -translate-x-1/2\",\n bottom: \"bottom-4 left-1/2 -translate-x-1/2\",\n \"top-right\": \"top-4 right-4\",\n \"bottom-right\": \"bottom-4 right-4\",\n }\n\n return (\n <div\n ref={ref}\n className={cn(\n \"fixed z-50 flex flex-col gap-2\",\n positionClasses[position],\n className\n )}\n {...props}\n >\n {messages.map((message) => (\n <div\n key={message.id}\n className={cn(\n \"min-w-[300px] rounded-lg border p-4 shadow-lg\",\n message.type === \"success\" &&\n \"border-green-500 bg-green-50 dark:bg-green-950\",\n message.type === \"warning\" &&\n \"border-yellow-500 bg-yellow-50 dark:bg-yellow-950\",\n message.type === \"error\" &&\n \"border-red-500 bg-red-50 dark:bg-red-950\",\n message.type === \"info\" &&\n \"border-blue-500 bg-blue-50 dark:bg-blue-950\",\n !message.type && \"bg-background\"\n )}\n >\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"flex-1\">\n <h4 className=\"font-medium\">{message.title}</h4>\n {message.description && (\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {message.description}\n </p>\n )}\n </div>\n {onClose && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6\"\n onClick={() => onClose(message.id)}\n >\n <X className=\"h-4 w-4\" />\n </Button>\n )}\n </div>\n </div>\n ))}\n </div>\n )\n }\n)\nMessageDock.displayName = \"MessageDock\"\n\nexport { MessageDock }\n"
}
],
"type": "components:ui"
}