@static-ui/registry 0.0.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.json +1184 -68
- package/package.json +33 -14
- package/registry.json +649 -0
package/dist/index.json
CHANGED
|
@@ -1,505 +1,1621 @@
|
|
|
1
1
|
[
|
|
2
2
|
{
|
|
3
3
|
"name": "accordion",
|
|
4
|
+
"type": "components:ui",
|
|
5
|
+
"frameworks": [
|
|
6
|
+
"react",
|
|
7
|
+
"nextjs",
|
|
8
|
+
"remix"
|
|
9
|
+
],
|
|
4
10
|
"dependencies": [
|
|
5
11
|
"@base-ui/react"
|
|
6
12
|
],
|
|
13
|
+
"registryDependencies": [],
|
|
7
14
|
"files": [
|
|
8
15
|
{
|
|
9
16
|
"name": "accordion.tsx",
|
|
10
|
-
"content": "
|
|
17
|
+
"content": "import { Accordion as AccordionPrimitive } from \"@base-ui/react/accordion\"\r\nimport { ChevronDownIcon, ChevronUpIcon } from \"lucide-react\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction Accordion({ className, ...props }: AccordionPrimitive.Root.Props) {\r\n return (\r\n <AccordionPrimitive.Root\r\n data-slot=\"accordion\"\r\n className={cn(\"flex w-full flex-col\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction AccordionItem({ className, ...props }: AccordionPrimitive.Item.Props) {\r\n return (\r\n <AccordionPrimitive.Item\r\n data-slot=\"accordion-item\"\r\n className={cn(\"not-last:border-b\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction AccordionTrigger({\r\n className,\r\n children,\r\n ...props\r\n}: AccordionPrimitive.Trigger.Props) {\r\n return (\r\n <AccordionPrimitive.Header className=\"flex\">\r\n <AccordionPrimitive.Trigger\r\n data-slot=\"accordion-trigger\"\r\n className={cn(\r\n \"group/accordion-trigger relative flex flex-1 items-start justify-between rounded-lg border border-transparent py-2.5 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:after:border-ring aria-disabled:pointer-events-none aria-disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n {children}\r\n <ChevronDownIcon\r\n data-slot=\"accordion-trigger-icon\"\r\n className=\"pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden\"\r\n />\r\n <ChevronUpIcon\r\n data-slot=\"accordion-trigger-icon\"\r\n className=\"pointer-events-none hidden shrink-0 group-aria-expanded/accordion-trigger:inline\"\r\n />\r\n </AccordionPrimitive.Trigger>\r\n </AccordionPrimitive.Header>\r\n )\r\n}\r\n\r\nfunction AccordionContent({\r\n className,\r\n children,\r\n ...props\r\n}: AccordionPrimitive.Panel.Props) {\r\n return (\r\n <AccordionPrimitive.Panel\r\n data-slot=\"accordion-content\"\r\n className=\"overflow-hidden text-sm data-open:animate-accordion-down data-closed:animate-accordion-up\"\r\n {...props}\r\n >\r\n <div\r\n className={cn(\r\n \"h-(--accordion-panel-height) pt-0 pb-2.5 data-ending-style:h-0 data-starting-style:h-0 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4\",\r\n className\r\n )}\r\n >\r\n {children}\r\n </div>\r\n </AccordionPrimitive.Panel>\r\n )\r\n}\r\n\r\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent }\r\n"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"name": "ai-chat-layout",
|
|
23
|
+
"type": "components:ui",
|
|
24
|
+
"frameworks": [
|
|
25
|
+
"react",
|
|
26
|
+
"nextjs",
|
|
27
|
+
"vue",
|
|
28
|
+
"nuxt",
|
|
29
|
+
"solid",
|
|
30
|
+
"svelte",
|
|
31
|
+
"astro",
|
|
32
|
+
"remix"
|
|
33
|
+
],
|
|
34
|
+
"dependencies": [
|
|
35
|
+
"@base-ui/react"
|
|
36
|
+
],
|
|
37
|
+
"registryDependencies": [
|
|
38
|
+
"ai-sidebar"
|
|
39
|
+
],
|
|
40
|
+
"files": [
|
|
41
|
+
{
|
|
42
|
+
"name": "ai-chat-layout.tsx",
|
|
43
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"@/lib/utils\"\n\nexport interface AiChatLayoutProps extends React.HTMLAttributes<HTMLDivElement> {\n sidebar: React.ReactNode\n children: React.ReactNode\n headerContent?: React.ReactNode\n}\n\nconst AiChatLayout = React.forwardRef<HTMLDivElement, AiChatLayoutProps>(\n ({ className, sidebar, children, headerContent, ...props }, ref) => {\n const [sidebarOpen, setSidebarOpen] = React.useState(false)\n\n return (\n <div\n ref={ref}\n className={cn(\n \"flex h-dvh w-full overflow-hidden bg-background text-foreground\",\n className\n )}\n {...props}\n >\n {/* Mobile sidebar backdrop */}\n {sidebarOpen && (\n <div\n className=\"fixed inset-0 z-40 bg-black/50 lg:hidden\"\n onClick={() => setSidebarOpen(false)}\n aria-hidden=\"true\"\n />\n )}\n\n {/* Sidebar */}\n <aside\n className={cn(\n \"fixed inset-y-0 left-0 z-50 flex w-72 flex-col border-r border-border bg-background p-3 transition-transform duration-200\",\n \"lg:static lg:z-auto lg:translate-x-0\",\n sidebarOpen ? \"translate-x-0\" : \"-translate-x-full\"\n )}\n aria-label=\"Chat sidebar\"\n >\n {sidebar}\n </aside>\n\n {/* Main area */}\n <div className=\"flex flex-1 flex-col min-w-0\">\n {/* Header */}\n {headerContent && (\n <header className=\"flex items-center gap-3 border-b border-border px-4 py-3\">\n <button\n type=\"button\"\n onClick={() => setSidebarOpen(!sidebarOpen)}\n className={cn(\n \"flex size-8 items-center justify-center rounded-lg text-muted-foreground lg:hidden\",\n \"hover:bg-muted hover:text-foreground\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n )}\n aria-label={sidebarOpen ? \"Close sidebar\" : \"Open sidebar\"}\n aria-expanded={sidebarOpen}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\" />\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\" />\n <line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\" />\n </svg>\n </button>\n {headerContent}\n </header>\n )}\n\n {/* Content area */}\n {children}\n </div>\n </div>\n )\n }\n)\nAiChatLayout.displayName = \"AiChatLayout\"\n\nexport { AiChatLayout }\n"
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "ai-chat",
|
|
49
|
+
"type": "components:ui",
|
|
50
|
+
"frameworks": [
|
|
51
|
+
"react",
|
|
52
|
+
"nextjs",
|
|
53
|
+
"vue",
|
|
54
|
+
"nuxt",
|
|
55
|
+
"solid",
|
|
56
|
+
"svelte",
|
|
57
|
+
"astro",
|
|
58
|
+
"remix"
|
|
59
|
+
],
|
|
60
|
+
"dependencies": [
|
|
61
|
+
"@base-ui/react"
|
|
62
|
+
],
|
|
63
|
+
"registryDependencies": [
|
|
64
|
+
"ai-message",
|
|
65
|
+
"ai-prompt"
|
|
66
|
+
],
|
|
67
|
+
"files": [
|
|
68
|
+
{
|
|
69
|
+
"name": "ai-chat.tsx",
|
|
70
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"@/lib/utils\"\nimport { AiMessage } from \"./ai-message\"\nimport { AiPrompt } from \"./ai-prompt\"\n\nexport interface ChatMessage {\n id: string\n role: \"user\" | \"assistant\"\n content: string\n timestamp?: string\n}\n\nexport interface AiChatProps extends React.HTMLAttributes<HTMLDivElement> {\n messages: ChatMessage[]\n onSend?: (message: string) => void\n loading?: boolean\n promptPlaceholder?: string\n}\n\nconst AiChat = React.forwardRef<HTMLDivElement, AiChatProps>(\n ({ className, messages, onSend, loading, promptPlaceholder, ...props }, ref) => {\n const listRef = React.useRef<HTMLDivElement>(null)\n\n React.useEffect(() => {\n if (listRef.current) {\n listRef.current.scrollTo({\n top: listRef.current.scrollHeight,\n behavior: \"smooth\",\n })\n }\n }, [messages])\n\n return (\n <div\n ref={ref}\n className={cn(\"flex flex-1 flex-col min-h-0\", className)}\n {...props}\n >\n <div\n ref={listRef}\n className=\"flex-1 overflow-y-auto px-4 py-4\"\n role=\"list\"\n aria-label=\"Chat messages\"\n aria-live=\"polite\"\n >\n <div className=\"mx-auto flex max-w-2xl flex-col gap-4\">\n {messages.length === 0 && (\n <div className=\"flex flex-1 items-center justify-center py-12\">\n <p className=\"text-sm text-muted-foreground text-center\">\n Start a conversation by sending a message below.\n </p>\n </div>\n )}\n {messages.map((msg) => (\n <AiMessage\n key={msg.id}\n role={msg.role}\n content={msg.content}\n timestamp={msg.timestamp}\n />\n ))}\n {loading && (\n <div className=\"flex items-center gap-2 px-1\" role=\"status\" aria-label=\"AI is typing\">\n <div className=\"flex size-8 items-center justify-center rounded-full bg-primary text-primary-foreground text-xs font-semibold\">\n AI\n </div>\n <div className=\"flex gap-1\">\n <span className=\"size-2 animate-bounce rounded-full bg-muted-foreground/40\" style={{ animationDelay: \"0ms\" }} />\n <span className=\"size-2 animate-bounce rounded-full bg-muted-foreground/40\" style={{ animationDelay: \"150ms\" }} />\n <span className=\"size-2 animate-bounce rounded-full bg-muted-foreground/40\" style={{ animationDelay: \"300ms\" }} />\n </div>\n <span className=\"sr-only\">AI is generating a response...</span>\n </div>\n )}\n </div>\n </div>\n\n <div className=\"border-t border-border p-4\">\n <div className=\"mx-auto max-w-2xl\">\n <AiPrompt\n onSubmit={(value) => onSend?.(value)}\n disabled={loading}\n placeholder={promptPlaceholder}\n />\n </div>\n </div>\n </div>\n )\n }\n)\nAiChat.displayName = \"AiChat\"\n\nexport { AiChat }\n"
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"name": "ai-code-block",
|
|
76
|
+
"type": "components:ui",
|
|
77
|
+
"frameworks": [
|
|
78
|
+
"react",
|
|
79
|
+
"nextjs",
|
|
80
|
+
"vue",
|
|
81
|
+
"nuxt",
|
|
82
|
+
"solid",
|
|
83
|
+
"svelte",
|
|
84
|
+
"astro",
|
|
85
|
+
"remix"
|
|
86
|
+
],
|
|
87
|
+
"dependencies": [
|
|
88
|
+
"@base-ui/react"
|
|
89
|
+
],
|
|
90
|
+
"registryDependencies": [],
|
|
91
|
+
"files": [
|
|
92
|
+
{
|
|
93
|
+
"name": "ai-code-block.tsx",
|
|
94
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"@/lib/utils\"\n\nexport interface AiCodeBlockProps extends React.HTMLAttributes<HTMLDivElement> {\n code: string\n language?: string\n showLineNumbers?: boolean\n}\n\nconst AiCodeBlock = React.forwardRef<HTMLDivElement, AiCodeBlockProps>(\n ({ className, code, language, showLineNumbers = false, ...props }, ref) => {\n const [copied, setCopied] = React.useState(false)\n\n const handleCopy = React.useCallback(async () => {\n try {\n await navigator.clipboard.writeText(code)\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n } catch {\n // Clipboard API not available\n }\n }, [code])\n\n const lines = code.split(\"\\n\")\n\n return (\n <div\n ref={ref}\n className={cn(\"group relative rounded-lg border border-border overflow-hidden\", className)}\n role=\"region\"\n aria-label={language ? `${language} code block` : \"Code block\"}\n {...props}\n >\n <div className=\"flex items-center justify-between border-b border-border bg-muted/50 px-4 py-2\">\n <span className=\"text-xs text-muted-foreground font-mono\">\n {language || \"code\"}\n </span>\n <button\n type=\"button\"\n onClick={handleCopy}\n className={cn(\n \"flex items-center gap-1.5 rounded-md px-2 py-1 text-xs text-muted-foreground transition-colors\",\n \"hover:bg-muted hover:text-foreground\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n )}\n aria-label={copied ? \"Copied\" : \"Copy code\"}\n >\n {copied ? (\n <>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n Copied\n </>\n ) : (\n <>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1\" />\n </svg>\n Copy\n </>\n )}\n </button>\n </div>\n <div className=\"overflow-x-auto p-4 text-sm\">\n <pre className=\"font-mono text-sm leading-relaxed\">\n <code>\n {showLineNumbers\n ? lines.map((line, i) => (\n <span key={i} className=\"table-row\">\n <span className=\"table-cell text-right text-muted-foreground/50 select-none pr-4 text-xs w-[1%]\">\n {i + 1}\n </span>\n <span className=\"table-cell text-foreground\">\n {line || \"\\u00A0\"}\n </span>\n </span>\n ))\n : code}\n </code>\n </pre>\n </div>\n </div>\n )\n }\n)\nAiCodeBlock.displayName = \"AiCodeBlock\"\n\nexport { AiCodeBlock }\n"
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"name": "ai-conversation",
|
|
100
|
+
"type": "components:ui",
|
|
101
|
+
"frameworks": [
|
|
102
|
+
"react",
|
|
103
|
+
"nextjs",
|
|
104
|
+
"vue",
|
|
105
|
+
"nuxt",
|
|
106
|
+
"solid",
|
|
107
|
+
"svelte",
|
|
108
|
+
"astro",
|
|
109
|
+
"remix"
|
|
110
|
+
],
|
|
111
|
+
"dependencies": [
|
|
112
|
+
"@base-ui/react"
|
|
113
|
+
],
|
|
114
|
+
"registryDependencies": [],
|
|
115
|
+
"files": [
|
|
116
|
+
{
|
|
117
|
+
"name": "ai-conversation.tsx",
|
|
118
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"@/lib/utils\"\n\nexport interface AiConversationProps extends React.HTMLAttributes<HTMLDivElement> {\n title: string\n preview?: string\n timestamp?: string\n active?: boolean\n onClick?: () => void\n onDelete?: () => void\n}\n\nconst AiConversation = React.forwardRef<HTMLDivElement, AiConversationProps>(\n ({ className, title, preview, timestamp, active, onClick, onDelete, ...props }, ref) => {\n return (\n <div\n ref={ref}\n role=\"button\"\n tabIndex={0}\n onClick={onClick}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") onClick?.()\n }}\n className={cn(\n \"group flex cursor-pointer items-center gap-3 rounded-lg px-3 py-2.5 transition-colors\",\n active\n ? \"bg-primary/10 text-foreground\"\n : \"text-muted-foreground hover:bg-muted hover:text-foreground\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n className\n )}\n aria-current={active ? \"page\" : undefined}\n {...props}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"shrink-0\"\n aria-hidden=\"true\"\n >\n <path d=\"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z\" />\n </svg>\n <div className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n <span className=\"truncate text-sm font-medium leading-tight\">{title}</span>\n {preview && (\n <span className=\"truncate text-xs text-muted-foreground\">{preview}</span>\n )}\n </div>\n <div className=\"flex shrink-0 items-center gap-1.5\">\n {timestamp && (\n <span className=\"text-[10px] text-muted-foreground\">{timestamp}</span>\n )}\n {onDelete && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n onDelete()\n }}\n className=\"rounded-md p-1 opacity-0 group-hover:opacity-100 focus-visible:opacity-100 text-muted-foreground hover:text-destructive hover:bg-destructive/10 transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n aria-label={`Delete conversation: ${title}`}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"3 6 5 6 21 6\" />\n <path d=\"M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2\" />\n </svg>\n </button>\n )}\n </div>\n </div>\n )\n }\n)\nAiConversation.displayName = \"AiConversation\"\n\nexport { AiConversation }\n"
|
|
119
|
+
}
|
|
120
|
+
]
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"name": "ai-file-upload",
|
|
124
|
+
"type": "components:ui",
|
|
125
|
+
"frameworks": [
|
|
126
|
+
"react",
|
|
127
|
+
"nextjs",
|
|
128
|
+
"vue",
|
|
129
|
+
"nuxt",
|
|
130
|
+
"solid",
|
|
131
|
+
"svelte",
|
|
132
|
+
"astro",
|
|
133
|
+
"remix"
|
|
134
|
+
],
|
|
135
|
+
"dependencies": [
|
|
136
|
+
"@base-ui/react"
|
|
137
|
+
],
|
|
138
|
+
"registryDependencies": [],
|
|
139
|
+
"files": [
|
|
140
|
+
{
|
|
141
|
+
"name": "ai-file-upload.tsx",
|
|
142
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"@/lib/utils\"\n\nexport interface AiFileUploadProps extends React.HTMLAttributes<HTMLDivElement> {\n accept?: string\n maxSize?: number\n multiple?: boolean\n onUpload?: (files: File[]) => void\n}\n\ninterface FileEntry {\n file: File\n progress: number\n size: string\n}\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) return bytes + \" B\"\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + \" KB\"\n return (bytes / (1024 * 1024)).toFixed(1) + \" MB\"\n}\n\nconst AiFileUpload = React.forwardRef<HTMLDivElement, AiFileUploadProps>(\n ({ className, accept, maxSize, multiple = true, onUpload, ...props }, ref) => {\n const [isDragging, setIsDragging] = React.useState(false)\n const [files, setFiles] = React.useState<FileEntry[]>([])\n const inputRef = React.useRef<HTMLInputElement>(null)\n\n const addFiles = React.useCallback(\n (incoming: FileList | File[]) => {\n const newFiles: FileEntry[] = Array.from(incoming).map((file) => ({\n file,\n progress: 0,\n size: formatSize(file.size),\n }))\n setFiles((prev) => (multiple ? [...prev, ...newFiles] : newFiles))\n onUpload?.(newFiles.map((f) => f.file))\n\n // Simulate upload progress\n newFiles.forEach((entry, i) => {\n let p = 0\n const interval = setInterval(() => {\n p += Math.random() * 30\n if (p >= 100) {\n p = 100\n clearInterval(interval)\n }\n setFiles((prev) => {\n const updated = [...prev]\n const idx = updated.indexOf(entry)\n if (idx !== -1) updated[idx] = { ...updated[idx], progress: p }\n return updated\n })\n }, 200 + i * 100)\n })\n },\n [multiple, onUpload]\n )\n\n const handleDragOver = (e: React.DragEvent) => {\n e.preventDefault()\n setIsDragging(true)\n }\n\n const handleDragLeave = (e: React.DragEvent) => {\n e.preventDefault()\n setIsDragging(false)\n }\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault()\n setIsDragging(false)\n if (e.dataTransfer.files.length > 0) {\n addFiles(e.dataTransfer.files)\n }\n }\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (e.target.files && e.target.files.length > 0) {\n addFiles(e.target.files)\n e.target.value = \"\"\n }\n }\n\n const removeFile = (index: number) => {\n setFiles((prev) => prev.filter((_, i) => i !== index))\n }\n\n return (\n <div\n ref={ref}\n className={cn(\"flex flex-col gap-3\", className)}\n {...props}\n >\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => inputRef.current?.click()}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") inputRef.current?.click()\n }}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n aria-label=\"File upload zone\"\n className={cn(\n \"flex cursor-pointer flex-col items-center justify-center gap-2 rounded-xl border-2 border-dashed px-6 py-8 text-center transition-colors\",\n isDragging\n ? \"border-primary bg-primary/5\"\n : \"border-border hover:border-muted-foreground/30\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n )}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"text-muted-foreground\"\n aria-hidden=\"true\"\n >\n <path d=\"M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z\" />\n <polyline points=\"14 2 14 8 20 8\" />\n <path d=\"M12 18v-6\" />\n <path d=\"M9 15l3-3 3 3\" />\n </svg>\n <div className=\"text-sm text-foreground\">\n <span className=\"font-medium\">Click to upload</span> or drag and drop\n </div>\n {accept && (\n <p className=\"text-xs text-muted-foreground\">\n Accepted: {accept}\n {maxSize && ` · Max: ${formatSize(maxSize)}`}\n </p>\n )}\n <input\n ref={inputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n onChange={handleInputChange}\n className=\"hidden\"\n aria-hidden=\"true\"\n />\n </div>\n\n {files.length > 0 && (\n <ul className=\"flex flex-col gap-2\" role=\"list\" aria-label=\"Uploaded files\">\n {files.map((entry, i) => (\n <li\n key={i}\n className=\"flex items-center gap-3 rounded-lg border border-border bg-background px-3 py-2.5\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"shrink-0 text-muted-foreground\"\n aria-hidden=\"true\"\n >\n <path d=\"M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z\" />\n <polyline points=\"14 2 14 8 20 8\" />\n </svg>\n <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"truncate text-sm text-foreground\">\n {entry.file.name}\n </span>\n <span className=\"shrink-0 text-xs text-muted-foreground\">\n {entry.size}\n </span>\n </div>\n <div className=\"h-1.5 w-full overflow-hidden rounded-full bg-muted\">\n <div\n className={cn(\n \"h-full rounded-full transition-all duration-300\",\n entry.progress === 100 ? \"bg-primary\" : \"bg-primary/70\"\n )}\n style={{ width: `${entry.progress}%` }}\n />\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => removeFile(i)}\n className=\"shrink-0 rounded-md p-1 text-muted-foreground hover:text-foreground hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n aria-label={`Remove ${entry.file.name}`}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </li>\n ))}\n </ul>\n )}\n </div>\n )\n }\n)\nAiFileUpload.displayName = \"AiFileUpload\"\n\nexport { AiFileUpload }\n"
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"name": "ai-message",
|
|
148
|
+
"type": "components:ui",
|
|
149
|
+
"frameworks": [
|
|
150
|
+
"react",
|
|
151
|
+
"nextjs",
|
|
152
|
+
"vue",
|
|
153
|
+
"nuxt",
|
|
154
|
+
"solid",
|
|
155
|
+
"svelte",
|
|
156
|
+
"astro",
|
|
157
|
+
"remix"
|
|
158
|
+
],
|
|
159
|
+
"dependencies": [
|
|
160
|
+
"@base-ui/react"
|
|
161
|
+
],
|
|
162
|
+
"registryDependencies": [],
|
|
163
|
+
"files": [
|
|
164
|
+
{
|
|
165
|
+
"name": "ai-message.tsx",
|
|
166
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"@/lib/utils\"\n\nexport interface AiMessageProps extends React.HTMLAttributes<HTMLDivElement> {\n role: \"user\" | \"assistant\"\n content: string\n timestamp?: string\n}\n\nconst AiMessage = React.forwardRef<HTMLDivElement, AiMessageProps>(\n ({ className, role, content, timestamp, ...props }, ref) => {\n const isUser = role === \"user\"\n\n return (\n <div\n ref={ref}\n className={cn(\n \"flex w-full gap-3\",\n isUser ? \"justify-end\" : \"justify-start\",\n className\n )}\n role=\"listitem\"\n {...props}\n >\n {!isUser && (\n <div className=\"flex size-8 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground text-xs font-semibold\">\n AI\n </div>\n )}\n <div className={cn(\"flex max-w-[80%] flex-col gap-1\", isUser && \"items-end\")}>\n <div\n className={cn(\n \"rounded-2xl px-4 py-2.5 text-sm whitespace-pre-wrap\",\n isUser\n ? \"bg-primary text-primary-foreground rounded-br-md\"\n : \"bg-muted text-foreground rounded-bl-md\"\n )}\n >\n {content}\n </div>\n {timestamp && (\n <span className=\"text-[10px] text-muted-foreground px-1\">\n {timestamp}\n </span>\n )}\n </div>\n {isUser && (\n <div className=\"flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground text-xs font-semibold\">\n U\n </div>\n )}\n </div>\n )\n }\n)\nAiMessage.displayName = \"AiMessage\"\n\nexport { AiMessage }\n"
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"name": "ai-prompt",
|
|
172
|
+
"type": "components:ui",
|
|
173
|
+
"frameworks": [
|
|
174
|
+
"react",
|
|
175
|
+
"nextjs",
|
|
176
|
+
"vue",
|
|
177
|
+
"nuxt",
|
|
178
|
+
"solid",
|
|
179
|
+
"svelte",
|
|
180
|
+
"astro",
|
|
181
|
+
"remix"
|
|
182
|
+
],
|
|
183
|
+
"dependencies": [
|
|
184
|
+
"@base-ui/react"
|
|
185
|
+
],
|
|
186
|
+
"registryDependencies": [],
|
|
187
|
+
"files": [
|
|
188
|
+
{
|
|
189
|
+
"name": "ai-prompt.tsx",
|
|
190
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"@/lib/utils\"\n\nexport interface AiPromptProps\n extends Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, \"onSubmit\"> {\n onSubmit?: (value: string) => void\n disabled?: boolean\n maxLength?: number\n}\n\nconst AiPrompt = React.forwardRef<HTMLTextAreaElement, AiPromptProps>(\n ({ className, onSubmit, disabled, placeholder = \"Type a message...\", maxLength, ...props }, ref) => {\n const [value, setValue] = React.useState(\"\")\n const textareaRef = React.useRef<HTMLTextAreaElement>(null)\n const combinedRef = (node: HTMLTextAreaElement) => {\n (ref as React.RefCallback<HTMLTextAreaElement>)?.(node)\n ;(textareaRef as React.MutableRefObject<HTMLTextAreaElement | null>).current = node\n }\n\n const handleSubmit = React.useCallback(() => {\n const trimmed = value.trim()\n if (!trimmed || disabled) return\n onSubmit?.(trimmed)\n setValue(\"\")\n }, [value, disabled, onSubmit])\n\n const handleKeyDown = React.useCallback(\n (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === \"Enter\" && (e.metaKey || e.ctrlKey)) {\n e.preventDefault()\n handleSubmit()\n }\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault()\n handleSubmit()\n }\n },\n [handleSubmit]\n )\n\n const charCount = value.length\n\n return (\n <div className={cn(\"flex flex-col gap-2\", className)}>\n <div className=\"relative flex items-end gap-2\">\n <textarea\n ref={combinedRef}\n value={value}\n onChange={(e) => {\n if (maxLength && e.target.value.length > maxLength) return\n setValue(e.target.value)\n }}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n rows={1}\n className={cn(\n \"min-h-[44px] w-full resize-none rounded-xl border border-border bg-background px-4 py-3 text-sm text-foreground placeholder:text-muted-foreground\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n \"disabled:opacity-50 disabled:cursor-not-allowed\"\n )}\n aria-label=\"Chat input\"\n aria-disabled={disabled}\n {...props}\n />\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={disabled || !value.trim()}\n aria-label=\"Send message\"\n className={cn(\n \"flex size-10 shrink-0 items-center justify-center rounded-xl bg-primary text-primary-foreground transition-colors\",\n \"hover:bg-primary/90\",\n \"disabled:opacity-50 disabled:cursor-not-allowed\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n )}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M5 12h14\" />\n <path d=\"M12 5l7 7-7 7\" />\n </svg>\n </button>\n </div>\n <div className=\"flex justify-between px-1\">\n {maxLength && (\n <span className=\"text-[11px] text-muted-foreground\">\n {charCount}/{maxLength}\n </span>\n )}\n <span className=\"text-[11px] text-muted-foreground ml-auto opacity-60\">\n Enter to send · Shift+Enter for new line\n </span>\n </div>\n </div>\n )\n }\n)\nAiPrompt.displayName = \"AiPrompt\"\n\nexport { AiPrompt }\n"
|
|
191
|
+
}
|
|
192
|
+
]
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"name": "ai-sidebar",
|
|
196
|
+
"type": "components:ui",
|
|
197
|
+
"frameworks": [
|
|
198
|
+
"react",
|
|
199
|
+
"nextjs",
|
|
200
|
+
"vue",
|
|
201
|
+
"nuxt",
|
|
202
|
+
"solid",
|
|
203
|
+
"svelte",
|
|
204
|
+
"astro",
|
|
205
|
+
"remix"
|
|
206
|
+
],
|
|
207
|
+
"dependencies": [
|
|
208
|
+
"@base-ui/react"
|
|
209
|
+
],
|
|
210
|
+
"registryDependencies": [
|
|
211
|
+
"ai-conversation"
|
|
212
|
+
],
|
|
213
|
+
"files": [
|
|
214
|
+
{
|
|
215
|
+
"name": "ai-sidebar.tsx",
|
|
216
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"@/lib/utils\"\nimport { AiConversation } from \"./ai-conversation\"\n\nexport interface Conversation {\n id: string\n title: string\n preview?: string\n timestamp?: string\n}\n\nexport interface AiSidebarProps {\n className?: string\n conversations: Conversation[]\n activeId?: string\n onSelect?: (id: string) => void\n onNew?: () => void\n onDelete?: (id: string) => void\n}\n\nconst AiSidebar = React.forwardRef<HTMLDivElement, AiSidebarProps>(\n ({ className, conversations, activeId, onSelect, onNew, onDelete, ...props }, ref) => {\n const [search, setSearch] = React.useState(\"\")\n\n const filtered = React.useMemo(\n () =>\n conversations.filter((c) =>\n c.title.toLowerCase().includes(search.toLowerCase())\n ),\n [conversations, search]\n )\n\n return (\n <div\n ref={ref}\n className={cn(\"flex h-full flex-col gap-3\", className)}\n {...props}\n >\n <div className=\"flex items-center justify-between px-1\">\n <h2 className=\"text-sm font-semibold text-foreground\">Conversations</h2>\n <button\n type=\"button\"\n onClick={onNew}\n className={cn(\n \"flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-medium text-foreground transition-colors\",\n \"hover:bg-muted\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n )}\n aria-label=\"New conversation\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n New\n </button>\n </div>\n\n <div className=\"relative\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground\"\n aria-hidden=\"true\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n </svg>\n <input\n type=\"text\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"Search...\"\n aria-label=\"Search conversations\"\n className={cn(\n \"w-full rounded-lg border border-border bg-background py-2 pl-9 pr-3 text-sm text-foreground placeholder:text-muted-foreground\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n )}\n />\n </div>\n\n <div className=\"flex-1 overflow-y-auto\" role=\"list\" aria-label=\"Conversation list\">\n {filtered.length === 0 ? (\n <p className=\"px-1 text-xs text-muted-foreground py-4 text-center\">\n {search ? \"No conversations found\" : \"No conversations yet\"}\n </p>\n ) : (\n <div className=\"flex flex-col gap-0.5\">\n {filtered.map((conv) => (\n <AiConversation\n key={conv.id}\n title={conv.title}\n preview={conv.preview}\n timestamp={conv.timestamp}\n active={conv.id === activeId}\n onClick={() => onSelect?.(conv.id)}\n onDelete={onDelete ? () => onDelete(conv.id) : undefined}\n />\n ))}\n </div>\n )}\n </div>\n </div>\n )\n }\n)\nAiSidebar.displayName = \"AiSidebar\"\n\nexport { AiSidebar }\n"
|
|
11
217
|
}
|
|
12
218
|
]
|
|
13
219
|
},
|
|
14
220
|
{
|
|
15
221
|
"name": "alert-dialog",
|
|
222
|
+
"type": "components:ui",
|
|
223
|
+
"frameworks": [
|
|
224
|
+
"react",
|
|
225
|
+
"nextjs",
|
|
226
|
+
"remix"
|
|
227
|
+
],
|
|
16
228
|
"dependencies": [
|
|
17
229
|
"@base-ui/react"
|
|
18
230
|
],
|
|
231
|
+
"registryDependencies": [],
|
|
19
232
|
"files": [
|
|
20
233
|
{
|
|
21
234
|
"name": "alert-dialog.tsx",
|
|
22
|
-
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { AlertDialog as
|
|
235
|
+
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { AlertDialog as AlertDialogPrimitive } from \"@base-ui/react/alert-dialog\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\nimport { Button } from \"@/button\"\r\n\r\nfunction AlertDialog({ ...props }: AlertDialogPrimitive.Root.Props) {\r\n return <AlertDialogPrimitive.Root data-slot=\"alert-dialog\" {...props} />\r\n}\r\n\r\nfunction AlertDialogTrigger({ ...props }: AlertDialogPrimitive.Trigger.Props) {\r\n return (\r\n <AlertDialogPrimitive.Trigger data-slot=\"alert-dialog-trigger\" {...props} />\r\n )\r\n}\r\n\r\nfunction AlertDialogPortal({ ...props }: AlertDialogPrimitive.Portal.Props) {\r\n return (\r\n <AlertDialogPrimitive.Portal data-slot=\"alert-dialog-portal\" {...props} />\r\n )\r\n}\r\n\r\nfunction AlertDialogOverlay({\r\n className,\r\n ...props\r\n}: AlertDialogPrimitive.Backdrop.Props) {\r\n return (\r\n <AlertDialogPrimitive.Backdrop\r\n data-slot=\"alert-dialog-overlay\"\r\n className={cn(\r\n \"fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction AlertDialogContent({\r\n className,\r\n size = \"default\",\r\n ...props\r\n}: AlertDialogPrimitive.Popup.Props & {\r\n size?: \"default\" | \"sm\"\r\n}) {\r\n return (\r\n <AlertDialogPortal>\r\n <AlertDialogOverlay />\r\n <AlertDialogPrimitive.Popup\r\n data-slot=\"alert-dialog-content\"\r\n data-size={size}\r\n className={cn(\r\n \"group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n </AlertDialogPortal>\r\n )\r\n}\r\n\r\nfunction AlertDialogHeader({\r\n className,\r\n ...props\r\n}: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"alert-dialog-header\"\r\n className={cn(\r\n \"grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction AlertDialogFooter({\r\n className,\r\n ...props\r\n}: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"alert-dialog-footer\"\r\n className={cn(\r\n \"-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction AlertDialogMedia({\r\n className,\r\n ...props\r\n}: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"alert-dialog-media\"\r\n className={cn(\r\n \"mb-2 inline-flex size-10 items-center justify-center rounded-md bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-6\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction AlertDialogTitle({\r\n className,\r\n ...props\r\n}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {\r\n return (\r\n <AlertDialogPrimitive.Title\r\n data-slot=\"alert-dialog-title\"\r\n className={cn(\r\n \"cn-font-heading text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction AlertDialogDescription({\r\n className,\r\n ...props\r\n}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {\r\n return (\r\n <AlertDialogPrimitive.Description\r\n data-slot=\"alert-dialog-description\"\r\n className={cn(\r\n \"text-sm text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction AlertDialogAction({\r\n className,\r\n ...props\r\n}: React.ComponentProps<typeof Button>) {\r\n return (\r\n <Button\r\n data-slot=\"alert-dialog-action\"\r\n className={cn(className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction AlertDialogCancel({\r\n className,\r\n variant = \"outline\",\r\n size = \"default\",\r\n ...props\r\n}: AlertDialogPrimitive.Close.Props &\r\n Pick<React.ComponentProps<typeof Button>, \"variant\" | \"size\">) {\r\n return (\r\n <AlertDialogPrimitive.Close\r\n data-slot=\"alert-dialog-cancel\"\r\n className={cn(className)}\r\n render={<Button variant={variant} size={size} />}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport {\r\n AlertDialog,\r\n AlertDialogAction,\r\n AlertDialogCancel,\r\n AlertDialogContent,\r\n AlertDialogDescription,\r\n AlertDialogFooter,\r\n AlertDialogHeader,\r\n AlertDialogMedia,\r\n AlertDialogOverlay,\r\n AlertDialogPortal,\r\n AlertDialogTitle,\r\n AlertDialogTrigger,\r\n}\r\n"
|
|
23
236
|
}
|
|
24
237
|
]
|
|
25
238
|
},
|
|
26
239
|
{
|
|
27
240
|
"name": "alert",
|
|
241
|
+
"type": "components:ui",
|
|
242
|
+
"frameworks": [
|
|
243
|
+
"react",
|
|
244
|
+
"nextjs",
|
|
245
|
+
"vue",
|
|
246
|
+
"nuxt",
|
|
247
|
+
"solid",
|
|
248
|
+
"svelte",
|
|
249
|
+
"astro",
|
|
250
|
+
"remix"
|
|
251
|
+
],
|
|
28
252
|
"dependencies": [],
|
|
253
|
+
"registryDependencies": [],
|
|
29
254
|
"files": [
|
|
30
255
|
{
|
|
31
256
|
"name": "alert.tsx",
|
|
32
|
-
"content": "import * as React from \"react\"\r\nimport {
|
|
257
|
+
"content": "import * as React from \"react\"\r\nimport { cva, type VariantProps } from \"class-variance-authority\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nconst alertVariants = cva(\r\n \"relative grid w-full grid-cols-[0_1fr] items-start gap-y-0.5 rounded-lg border px-4 py-3 text-sm has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] has-[>svg]:gap-x-3 [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current\",\r\n {\r\n variants: {\r\n variant: {\r\n default: \"bg-card text-card-foreground\",\r\n destructive:\r\n \"bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 [&>svg]:text-current\",\r\n },\r\n },\r\n defaultVariants: {\r\n variant: \"default\",\r\n },\r\n }\r\n)\r\n\r\nfunction Alert({\r\n className,\r\n variant,\r\n ...props\r\n}: React.ComponentProps<\"div\"> & VariantProps<typeof alertVariants>) {\r\n return (\r\n <div\r\n data-slot=\"alert\"\r\n role=\"alert\"\r\n className={cn(alertVariants({ variant }), className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction AlertTitle({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"alert-title\"\r\n className={cn(\r\n \"col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction AlertDescription({\r\n className,\r\n ...props\r\n}: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"alert-description\"\r\n className={cn(\r\n \"col-start-2 grid justify-items-start gap-1 text-sm text-muted-foreground [&_p]:leading-relaxed\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport { Alert, AlertTitle, AlertDescription }\r\n"
|
|
33
258
|
}
|
|
34
259
|
]
|
|
35
260
|
},
|
|
36
261
|
{
|
|
37
262
|
"name": "aspect-ratio",
|
|
263
|
+
"type": "components:ui",
|
|
264
|
+
"frameworks": [
|
|
265
|
+
"react",
|
|
266
|
+
"nextjs",
|
|
267
|
+
"vue",
|
|
268
|
+
"nuxt",
|
|
269
|
+
"solid",
|
|
270
|
+
"svelte",
|
|
271
|
+
"astro",
|
|
272
|
+
"remix"
|
|
273
|
+
],
|
|
38
274
|
"dependencies": [],
|
|
275
|
+
"registryDependencies": [],
|
|
39
276
|
"files": [
|
|
40
277
|
{
|
|
41
278
|
"name": "aspect-ratio.tsx",
|
|
42
|
-
"content": "import
|
|
279
|
+
"content": "import { cn } from \"@/lib/utils\"\r\n\r\nfunction AspectRatio({\r\n ratio,\r\n className,\r\n ...props\r\n}: React.ComponentProps<\"div\"> & { ratio: number }) {\r\n return (\r\n <div\r\n data-slot=\"aspect-ratio\"\r\n style={\r\n {\r\n \"--ratio\": ratio,\r\n } as React.CSSProperties\r\n }\r\n className={cn(\"relative aspect-(--ratio)\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport { AspectRatio }\r\n"
|
|
43
280
|
}
|
|
44
281
|
]
|
|
45
282
|
},
|
|
46
283
|
{
|
|
47
284
|
"name": "avatar",
|
|
285
|
+
"type": "components:ui",
|
|
286
|
+
"frameworks": [
|
|
287
|
+
"react",
|
|
288
|
+
"nextjs",
|
|
289
|
+
"remix"
|
|
290
|
+
],
|
|
48
291
|
"dependencies": [
|
|
49
292
|
"@base-ui/react"
|
|
50
293
|
],
|
|
294
|
+
"registryDependencies": [],
|
|
51
295
|
"files": [
|
|
52
296
|
{
|
|
53
297
|
"name": "avatar.tsx",
|
|
54
|
-
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { Avatar as
|
|
298
|
+
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { Avatar as AvatarPrimitive } from \"@base-ui/react/avatar\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction Avatar({\r\n className,\r\n size = \"default\",\r\n ...props\r\n}: AvatarPrimitive.Root.Props & {\r\n size?: \"default\" | \"sm\" | \"lg\"\r\n}) {\r\n return (\r\n <AvatarPrimitive.Root\r\n data-slot=\"avatar\"\r\n data-size={size}\r\n className={cn(\r\n \"group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:border-border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction AvatarImage({ className, ...props }: AvatarPrimitive.Image.Props) {\r\n return (\r\n <AvatarPrimitive.Image\r\n data-slot=\"avatar-image\"\r\n className={cn(\r\n \"aspect-square size-full rounded-full object-cover\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction AvatarFallback({\r\n className,\r\n ...props\r\n}: AvatarPrimitive.Fallback.Props) {\r\n return (\r\n <AvatarPrimitive.Fallback\r\n data-slot=\"avatar-fallback\"\r\n className={cn(\r\n \"flex size-full items-center justify-center rounded-full bg-muted text-sm text-muted-foreground group-data-[size=sm]/avatar:text-xs\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction AvatarBadge({ className, ...props }: React.ComponentProps<\"span\">) {\r\n return (\r\n <span\r\n data-slot=\"avatar-badge\"\r\n className={cn(\r\n \"absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-primary text-primary-foreground bg-blend-color ring-2 ring-background select-none\",\r\n \"group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden\",\r\n \"group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2\",\r\n \"group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction AvatarGroup({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"avatar-group\"\r\n className={cn(\r\n \"group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction AvatarGroupCount({\r\n className,\r\n ...props\r\n}: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"avatar-group-count\"\r\n className={cn(\r\n \"relative flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-sm text-muted-foreground ring-2 ring-background group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport {\r\n Avatar,\r\n AvatarImage,\r\n AvatarFallback,\r\n AvatarGroup,\r\n AvatarGroupCount,\r\n AvatarBadge,\r\n}\r\n"
|
|
55
299
|
}
|
|
56
300
|
]
|
|
57
301
|
},
|
|
58
302
|
{
|
|
59
303
|
"name": "badge",
|
|
304
|
+
"type": "components:ui",
|
|
305
|
+
"frameworks": [
|
|
306
|
+
"react",
|
|
307
|
+
"nextjs",
|
|
308
|
+
"vue",
|
|
309
|
+
"nuxt",
|
|
310
|
+
"solid",
|
|
311
|
+
"svelte",
|
|
312
|
+
"astro",
|
|
313
|
+
"remix"
|
|
314
|
+
],
|
|
60
315
|
"dependencies": [
|
|
61
316
|
"class-variance-authority"
|
|
62
317
|
],
|
|
318
|
+
"registryDependencies": [],
|
|
63
319
|
"files": [
|
|
64
320
|
{
|
|
65
321
|
"name": "badge.tsx",
|
|
66
|
-
"content": "import
|
|
322
|
+
"content": "import { mergeProps } from \"@base-ui/react/merge-props\"\r\nimport { useRender } from \"@base-ui/react/use-render\"\r\nimport { cva, type VariantProps } from \"class-variance-authority\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nconst badgeVariants = cva(\r\n \"group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!\",\r\n {\r\n variants: {\r\n variant: {\r\n default: \"bg-primary text-primary-foreground [a]:hover:bg-primary/80\",\r\n secondary:\r\n \"bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80\",\r\n destructive:\r\n \"bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20\",\r\n outline:\r\n \"border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground\",\r\n ghost:\r\n \"hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50\",\r\n link: \"text-primary underline-offset-4 hover:underline\",\r\n },\r\n },\r\n defaultVariants: {\r\n variant: \"default\",\r\n },\r\n }\r\n)\r\n\r\nfunction Badge({\r\n className,\r\n variant = \"default\",\r\n render,\r\n ...props\r\n}: useRender.ComponentProps<\"span\"> & VariantProps<typeof badgeVariants>) {\r\n return useRender({\r\n defaultTagName: \"span\",\r\n props: mergeProps<\"span\">(\r\n {\r\n className: cn(badgeVariants({ variant }), className),\r\n },\r\n props\r\n ),\r\n render,\r\n state: {\r\n slot: \"badge\",\r\n variant,\r\n },\r\n })\r\n}\r\n\r\nexport { Badge, badgeVariants }\r\n"
|
|
67
323
|
}
|
|
68
324
|
]
|
|
69
325
|
},
|
|
70
326
|
{
|
|
71
327
|
"name": "breadcrumb",
|
|
328
|
+
"type": "components:ui",
|
|
329
|
+
"frameworks": [
|
|
330
|
+
"react",
|
|
331
|
+
"nextjs",
|
|
332
|
+
"vue",
|
|
333
|
+
"nuxt",
|
|
334
|
+
"solid",
|
|
335
|
+
"svelte",
|
|
336
|
+
"astro",
|
|
337
|
+
"remix"
|
|
338
|
+
],
|
|
72
339
|
"dependencies": [],
|
|
340
|
+
"registryDependencies": [],
|
|
73
341
|
"files": [
|
|
74
342
|
{
|
|
75
343
|
"name": "breadcrumb.tsx",
|
|
76
|
-
"content": "import * as React from \"react\"\r\nimport {
|
|
344
|
+
"content": "import * as React from \"react\"\r\nimport { mergeProps } from \"@base-ui/react/merge-props\"\r\nimport { useRender } from \"@base-ui/react/use-render\"\r\nimport { ChevronRightIcon, MoreHorizontalIcon } from \"lucide-react\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction Breadcrumb({ className, ...props }: React.ComponentProps<\"nav\">) {\r\n return (\r\n <nav\r\n aria-label=\"breadcrumb\"\r\n data-slot=\"breadcrumb\"\r\n className={cn(className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction BreadcrumbList({ className, ...props }: React.ComponentProps<\"ol\">) {\r\n return (\r\n <ol\r\n data-slot=\"breadcrumb-list\"\r\n className={cn(\r\n \"flex flex-wrap items-center gap-1.5 text-sm wrap-break-word text-muted-foreground\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction BreadcrumbItem({ className, ...props }: React.ComponentProps<\"li\">) {\r\n return (\r\n <li\r\n data-slot=\"breadcrumb-item\"\r\n className={cn(\"inline-flex items-center gap-1\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction BreadcrumbLink({\r\n className,\r\n render,\r\n ...props\r\n}: useRender.ComponentProps<\"a\">) {\r\n return useRender({\r\n defaultTagName: \"a\",\r\n props: mergeProps<\"a\">(\r\n {\r\n className: cn(\"transition-colors hover:text-foreground\", className),\r\n },\r\n props\r\n ),\r\n render,\r\n state: {\r\n slot: \"breadcrumb-link\",\r\n },\r\n })\r\n}\r\n\r\nfunction BreadcrumbPage({ className, ...props }: React.ComponentProps<\"span\">) {\r\n return (\r\n <span\r\n data-slot=\"breadcrumb-page\"\r\n role=\"link\"\r\n aria-disabled=\"true\"\r\n aria-current=\"page\"\r\n className={cn(\"font-normal text-foreground\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction BreadcrumbSeparator({\r\n children,\r\n className,\r\n ...props\r\n}: React.ComponentProps<\"li\">) {\r\n return (\r\n <li\r\n data-slot=\"breadcrumb-separator\"\r\n role=\"presentation\"\r\n aria-hidden=\"true\"\r\n className={cn(\"[&>svg]:size-3.5\", className)}\r\n {...props}\r\n >\r\n {children ?? <ChevronRightIcon className=\"cn-rtl-flip\" />}\r\n </li>\r\n )\r\n}\r\n\r\nfunction BreadcrumbEllipsis({\r\n className,\r\n ...props\r\n}: React.ComponentProps<\"span\">) {\r\n return (\r\n <span\r\n data-slot=\"breadcrumb-ellipsis\"\r\n role=\"presentation\"\r\n aria-hidden=\"true\"\r\n className={cn(\r\n \"flex size-5 items-center justify-center [&>svg]:size-4\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n <MoreHorizontalIcon />\r\n <span className=\"sr-only\">More</span>\r\n </span>\r\n )\r\n}\r\n\r\nexport {\r\n Breadcrumb,\r\n BreadcrumbList,\r\n BreadcrumbItem,\r\n BreadcrumbLink,\r\n BreadcrumbPage,\r\n BreadcrumbSeparator,\r\n BreadcrumbEllipsis,\r\n}\r\n"
|
|
77
345
|
}
|
|
78
346
|
]
|
|
79
347
|
},
|
|
80
348
|
{
|
|
81
349
|
"name": "button",
|
|
350
|
+
"type": "components:ui",
|
|
351
|
+
"frameworks": [
|
|
352
|
+
"react",
|
|
353
|
+
"nextjs",
|
|
354
|
+
"vue",
|
|
355
|
+
"nuxt",
|
|
356
|
+
"solid",
|
|
357
|
+
"svelte",
|
|
358
|
+
"astro",
|
|
359
|
+
"remix"
|
|
360
|
+
],
|
|
82
361
|
"dependencies": [
|
|
83
362
|
"@base-ui/react",
|
|
84
363
|
"class-variance-authority"
|
|
85
364
|
],
|
|
365
|
+
"registryDependencies": [],
|
|
86
366
|
"files": [
|
|
87
367
|
{
|
|
88
368
|
"name": "button.tsx",
|
|
89
|
-
"content": "import
|
|
369
|
+
"content": "import { Button as ButtonPrimitive } from \"@base-ui/react/button\"\r\nimport { cva, type VariantProps } from \"class-variance-authority\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nconst buttonVariants = cva(\r\n \"group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\r\n {\r\n variants: {\r\n variant: {\r\n default: \"bg-primary text-primary-foreground hover:bg-primary/80\",\r\n outline:\r\n \"border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\r\n secondary:\r\n \"bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground\",\r\n ghost:\r\n \"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50\",\r\n destructive:\r\n \"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40\",\r\n link: \"text-primary underline-offset-4 hover:underline\",\r\n },\r\n size: {\r\n default:\r\n \"h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\r\n xs: \"h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3\",\r\n sm: \"h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5\",\r\n lg: \"h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\r\n icon: \"size-8\",\r\n \"icon-xs\":\r\n \"size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3\",\r\n \"icon-sm\":\r\n \"size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg\",\r\n \"icon-lg\": \"size-9\",\r\n },\r\n },\r\n defaultVariants: {\r\n variant: \"default\",\r\n size: \"default\",\r\n },\r\n }\r\n)\r\n\r\nfunction Button({\r\n className,\r\n variant = \"default\",\r\n size = \"default\",\r\n ...props\r\n}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {\r\n return (\r\n <ButtonPrimitive\r\n data-slot=\"button\"\r\n className={cn(buttonVariants({ variant, size, className }))}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport { Button, buttonVariants }\r\n"
|
|
90
370
|
}
|
|
91
371
|
]
|
|
92
372
|
},
|
|
93
373
|
{
|
|
94
374
|
"name": "calendar",
|
|
375
|
+
"type": "components:ui",
|
|
376
|
+
"frameworks": [
|
|
377
|
+
"react",
|
|
378
|
+
"nextjs",
|
|
379
|
+
"vue",
|
|
380
|
+
"nuxt",
|
|
381
|
+
"solid",
|
|
382
|
+
"svelte",
|
|
383
|
+
"astro",
|
|
384
|
+
"remix"
|
|
385
|
+
],
|
|
95
386
|
"dependencies": [],
|
|
387
|
+
"registryDependencies": [],
|
|
96
388
|
"files": [
|
|
97
389
|
{
|
|
98
390
|
"name": "calendar.tsx",
|
|
99
|
-
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { cn } from \"@/lib/utils\"\r\n\r\
|
|
391
|
+
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport {\r\n ChevronDownIcon,\r\n ChevronLeftIcon,\r\n ChevronRightIcon,\r\n} from \"lucide-react\"\r\nimport {\r\n DayPicker,\r\n getDefaultClassNames,\r\n type DayButton,\r\n type Locale,\r\n} from \"react-day-picker\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\nimport { Button, buttonVariants } from \"@/button\"\r\n\r\nfunction Calendar({\r\n className,\r\n classNames,\r\n showOutsideDays = true,\r\n captionLayout = \"label\",\r\n buttonVariant = \"ghost\",\r\n locale,\r\n formatters,\r\n components,\r\n ...props\r\n}: React.ComponentProps<typeof DayPicker> & {\r\n buttonVariant?: React.ComponentProps<typeof Button>[\"variant\"]\r\n}) {\r\n const defaultClassNames = getDefaultClassNames()\r\n\r\n return (\r\n <DayPicker\r\n showOutsideDays={showOutsideDays}\r\n className={cn(\r\n \"group/calendar bg-background p-2 [--cell-radius:var(--radius-md)] [--cell-size:--spacing(7)] in-data-[slot=card-content]:bg-transparent in-data-[slot=popover-content]:bg-transparent\",\r\n String.raw`rtl:**:[.rdp-button\\_next>svg]:rotate-180`,\r\n String.raw`rtl:**:[.rdp-button\\_previous>svg]:rotate-180`,\r\n className\r\n )}\r\n captionLayout={captionLayout}\r\n locale={locale}\r\n formatters={{\r\n formatMonthDropdown: (date) =>\r\n date.toLocaleString(locale?.code, { month: \"short\" }),\r\n ...formatters,\r\n }}\r\n classNames={{\r\n root: cn(\"w-fit\", defaultClassNames.root),\r\n months: cn(\r\n \"relative flex flex-col gap-4 md:flex-row\",\r\n defaultClassNames.months\r\n ),\r\n month: cn(\"flex w-full flex-col gap-4\", defaultClassNames.month),\r\n nav: cn(\r\n \"absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1\",\r\n defaultClassNames.nav\r\n ),\r\n button_previous: cn(\r\n buttonVariants({ variant: buttonVariant }),\r\n \"size-(--cell-size) p-0 select-none aria-disabled:opacity-50\",\r\n defaultClassNames.button_previous\r\n ),\r\n button_next: cn(\r\n buttonVariants({ variant: buttonVariant }),\r\n \"size-(--cell-size) p-0 select-none aria-disabled:opacity-50\",\r\n defaultClassNames.button_next\r\n ),\r\n month_caption: cn(\r\n \"flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)\",\r\n defaultClassNames.month_caption\r\n ),\r\n dropdowns: cn(\r\n \"flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium\",\r\n defaultClassNames.dropdowns\r\n ),\r\n dropdown_root: cn(\r\n \"cn-calendar-dropdown-root relative rounded-(--cell-radius)\",\r\n defaultClassNames.dropdown_root\r\n ),\r\n dropdown: cn(\r\n \"absolute inset-0 bg-popover opacity-0\",\r\n defaultClassNames.dropdown\r\n ),\r\n caption_label: cn(\r\n \"font-medium select-none\",\r\n captionLayout === \"label\"\r\n ? \"cn-calendar-caption text-sm\"\r\n : \"cn-calendar-caption-label flex items-center gap-1 rounded-(--cell-radius) text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground\",\r\n defaultClassNames.caption_label\r\n ),\r\n table: \"w-full border-collapse\",\r\n weekdays: cn(\"flex\", defaultClassNames.weekdays),\r\n weekday: cn(\r\n \"flex-1 rounded-(--cell-radius) text-[0.8rem] font-normal text-muted-foreground select-none\",\r\n defaultClassNames.weekday\r\n ),\r\n week: cn(\"mt-2 flex w-full\", defaultClassNames.week),\r\n week_number_header: cn(\r\n \"w-(--cell-size) select-none\",\r\n defaultClassNames.week_number_header\r\n ),\r\n week_number: cn(\r\n \"text-[0.8rem] text-muted-foreground select-none\",\r\n defaultClassNames.week_number\r\n ),\r\n day: cn(\r\n \"group/day relative aspect-square h-full w-full rounded-(--cell-radius) p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-(--cell-radius)\",\r\n props.showWeekNumber\r\n ? \"[&:nth-child(2)[data-selected=true]_button]:rounded-l-(--cell-radius)\"\r\n : \"[&:first-child[data-selected=true]_button]:rounded-l-(--cell-radius)\",\r\n defaultClassNames.day\r\n ),\r\n range_start: cn(\r\n \"relative isolate z-0 rounded-l-(--cell-radius) bg-muted after:absolute after:inset-y-0 after:right-0 after:w-4 after:bg-muted\",\r\n defaultClassNames.range_start\r\n ),\r\n range_middle: cn(\"rounded-none\", defaultClassNames.range_middle),\r\n range_end: cn(\r\n \"relative isolate z-0 rounded-r-(--cell-radius) bg-muted after:absolute after:inset-y-0 after:left-0 after:w-4 after:bg-muted\",\r\n defaultClassNames.range_end\r\n ),\r\n today: cn(\r\n \"rounded-(--cell-radius) bg-muted text-foreground data-[selected=true]:rounded-none\",\r\n defaultClassNames.today\r\n ),\r\n outside: cn(\r\n \"text-muted-foreground aria-selected:text-muted-foreground\",\r\n defaultClassNames.outside\r\n ),\r\n disabled: cn(\r\n \"text-muted-foreground opacity-50\",\r\n defaultClassNames.disabled\r\n ),\r\n hidden: cn(\"invisible\", defaultClassNames.hidden),\r\n ...classNames,\r\n } as any}\r\n components={{\r\n Root: ({ className, rootRef, ...props }) => {\r\n return (\r\n <div\r\n data-slot=\"calendar\"\r\n ref={rootRef}\r\n className={cn(className)}\r\n {...props}\r\n />\r\n )\r\n },\r\n Chevron: ({ className, orientation, ...props }) => {\r\n if (orientation === \"left\") {\r\n return (\r\n <ChevronLeftIcon\r\n className={cn(\"cn-rtl-flip size-4\", className)}\r\n {...props}\r\n />\r\n )\r\n }\r\n\r\n if (orientation === \"right\") {\r\n return (\r\n <ChevronRightIcon\r\n className={cn(\"cn-rtl-flip size-4\", className)}\r\n {...props}\r\n />\r\n )\r\n }\r\n\r\n return (\r\n <ChevronDownIcon className={cn(\"size-4\", className)} {...props} />\r\n )\r\n },\r\n DayButton: ({ ...props }) => (\r\n <CalendarDayButton locale={locale} {...props} />\r\n ),\r\n WeekNumber: ({ children, ...props }) => {\r\n return (\r\n <td {...props}>\r\n <div className=\"flex size-(--cell-size) items-center justify-center text-center\">\r\n {children}\r\n </div>\r\n </td>\r\n )\r\n },\r\n ...components,\r\n }}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction CalendarDayButton({\r\n className,\r\n day,\r\n modifiers,\r\n locale,\r\n ...props\r\n}: React.ComponentProps<typeof DayButton> & { locale?: Partial<Locale> }) {\r\n const defaultClassNames = getDefaultClassNames()\r\n\r\n const ref = React.useRef<HTMLButtonElement>(null)\r\n React.useEffect(() => {\r\n if (modifiers.focused) ref.current?.focus()\r\n }, [modifiers.focused])\r\n\r\n return (\r\n <Button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n data-day={day.date.toLocaleDateString(locale?.code)}\r\n data-selected-single={\r\n modifiers.selected &&\r\n !modifiers.range_start &&\r\n !modifiers.range_end &&\r\n !modifiers.range_middle\r\n }\r\n data-range-start={modifiers.range_start}\r\n data-range-end={modifiers.range_end}\r\n data-range-middle={modifiers.range_middle}\r\n className={cn(\r\n \"relative isolate z-10 flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 border-0 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-(--cell-radius) data-[range-end=true]:rounded-r-(--cell-radius) data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-muted data-[range-middle=true]:text-foreground data-[range-start=true]:rounded-(--cell-radius) data-[range-start=true]:rounded-l-(--cell-radius) data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-foreground [&>span]:text-xs [&>span]:opacity-70\",\r\n defaultClassNames.day,\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport { Calendar, CalendarDayButton }\r\n"
|
|
100
392
|
}
|
|
101
393
|
]
|
|
102
394
|
},
|
|
103
395
|
{
|
|
104
396
|
"name": "card",
|
|
397
|
+
"type": "components:ui",
|
|
398
|
+
"frameworks": [
|
|
399
|
+
"react",
|
|
400
|
+
"nextjs",
|
|
401
|
+
"vue",
|
|
402
|
+
"nuxt",
|
|
403
|
+
"solid",
|
|
404
|
+
"svelte",
|
|
405
|
+
"astro",
|
|
406
|
+
"remix"
|
|
407
|
+
],
|
|
105
408
|
"dependencies": [],
|
|
409
|
+
"registryDependencies": [],
|
|
106
410
|
"files": [
|
|
107
411
|
{
|
|
108
412
|
"name": "card.tsx",
|
|
109
|
-
"content": "import * as React from \"react\"\r\nimport { cn } from \"@/lib/utils\"\r\n\r\
|
|
413
|
+
"content": "import * as React from \"react\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction Card({\r\n className,\r\n size = \"default\",\r\n ...props\r\n}: React.ComponentProps<\"div\"> & { size?: \"default\" | \"sm\" }) {\r\n return (\r\n <div\r\n data-slot=\"card\"\r\n data-size={size}\r\n className={cn(\r\n \"group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"card-header\"\r\n className={cn(\r\n \"group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"card-title\"\r\n className={cn(\r\n \"cn-font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"card-description\"\r\n className={cn(\"text-sm text-muted-foreground\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"card-action\"\r\n className={cn(\r\n \"col-start-2 row-span-2 row-start-1 self-start justify-self-end\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"card-content\"\r\n className={cn(\"px-(--card-spacing)\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"card-footer\"\r\n className={cn(\r\n \"flex items-center rounded-b-xl border-t bg-muted/50 p-(--card-spacing)\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport {\r\n Card,\r\n CardHeader,\r\n CardFooter,\r\n CardTitle,\r\n CardAction,\r\n CardDescription,\r\n CardContent,\r\n}\r\n"
|
|
110
414
|
}
|
|
111
415
|
]
|
|
112
416
|
},
|
|
113
417
|
{
|
|
114
418
|
"name": "carousel",
|
|
419
|
+
"type": "components:ui",
|
|
420
|
+
"frameworks": [
|
|
421
|
+
"react",
|
|
422
|
+
"nextjs",
|
|
423
|
+
"vue",
|
|
424
|
+
"nuxt",
|
|
425
|
+
"solid",
|
|
426
|
+
"svelte",
|
|
427
|
+
"astro",
|
|
428
|
+
"remix"
|
|
429
|
+
],
|
|
115
430
|
"dependencies": [],
|
|
431
|
+
"registryDependencies": [],
|
|
116
432
|
"files": [
|
|
117
433
|
{
|
|
118
434
|
"name": "carousel.tsx",
|
|
119
|
-
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { cn } from \"@/lib/utils\"\r\n\r\ntype CarouselContextProps = {\r\n carouselRef:
|
|
435
|
+
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport useEmblaCarousel, {\r\n type UseEmblaCarouselType,\r\n} from \"embla-carousel-react\"\r\nimport { ChevronLeftIcon, ChevronRightIcon } from \"lucide-react\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\nimport { Button } from \"@/button\"\r\n\r\ntype CarouselApi = UseEmblaCarouselType[1]\r\ntype UseCarouselParameters = Parameters<typeof useEmblaCarousel>\r\ntype CarouselOptions = UseCarouselParameters[0]\r\ntype CarouselPlugin = UseCarouselParameters[1]\r\n\r\ntype CarouselProps = {\r\n opts?: CarouselOptions\r\n plugins?: CarouselPlugin\r\n orientation?: \"horizontal\" | \"vertical\"\r\n setApi?: (api: CarouselApi) => void\r\n}\r\n\r\ntype CarouselContextProps = {\r\n carouselRef: ReturnType<typeof useEmblaCarousel>[0]\r\n api: ReturnType<typeof useEmblaCarousel>[1]\r\n scrollPrev: () => void\r\n scrollNext: () => void\r\n canScrollPrev: boolean\r\n canScrollNext: boolean\r\n} & CarouselProps\r\n\r\nconst CarouselContext = React.createContext<CarouselContextProps | null>(null)\r\n\r\nfunction useCarousel() {\r\n const context = React.useContext(CarouselContext)\r\n\r\n if (!context) {\r\n throw new Error(\"useCarousel must be used within a <Carousel />\")\r\n }\r\n\r\n return context\r\n}\r\n\r\nfunction Carousel({\r\n orientation = \"horizontal\",\r\n opts,\r\n setApi,\r\n plugins,\r\n className,\r\n children,\r\n ...props\r\n}: React.ComponentProps<\"div\"> & CarouselProps) {\r\n const [carouselRef, api] = useEmblaCarousel(\r\n {\r\n ...opts,\r\n axis: orientation === \"horizontal\" ? \"x\" : \"y\",\r\n },\r\n plugins\r\n )\r\n const [canScrollPrev, setCanScrollPrev] = React.useState(false)\r\n const [canScrollNext, setCanScrollNext] = React.useState(false)\r\n\r\n const onSelect = React.useCallback((api: CarouselApi) => {\r\n if (!api) return\r\n setCanScrollPrev(api.canScrollPrev())\r\n setCanScrollNext(api.canScrollNext())\r\n }, [])\r\n\r\n const scrollPrev = React.useCallback(() => {\r\n api?.scrollPrev()\r\n }, [api])\r\n\r\n const scrollNext = React.useCallback(() => {\r\n api?.scrollNext()\r\n }, [api])\r\n\r\n const handleKeyDown = React.useCallback(\r\n (event: React.KeyboardEvent<HTMLDivElement>) => {\r\n if (event.key === \"ArrowLeft\") {\r\n event.preventDefault()\r\n scrollPrev()\r\n } else if (event.key === \"ArrowRight\") {\r\n event.preventDefault()\r\n scrollNext()\r\n }\r\n },\r\n [scrollPrev, scrollNext]\r\n )\r\n\r\n React.useEffect(() => {\r\n if (!api || !setApi) return\r\n setApi(api)\r\n }, [api, setApi])\r\n\r\n React.useEffect(() => {\r\n if (!api) return\r\n onSelect(api)\r\n api.on(\"reInit\", onSelect)\r\n api.on(\"select\", onSelect)\r\n\r\n return () => {\r\n api?.off(\"select\", onSelect)\r\n }\r\n }, [api, onSelect])\r\n\r\n return (\r\n <CarouselContext.Provider\r\n value={{\r\n carouselRef,\r\n api: api,\r\n opts,\r\n orientation:\r\n orientation || (opts?.axis === \"y\" ? \"vertical\" : \"horizontal\"),\r\n scrollPrev,\r\n scrollNext,\r\n canScrollPrev,\r\n canScrollNext,\r\n }}\r\n >\r\n <div\r\n onKeyDownCapture={handleKeyDown}\r\n className={cn(\"relative\", className)}\r\n role=\"region\"\r\n aria-roledescription=\"carousel\"\r\n data-slot=\"carousel\"\r\n {...props}\r\n >\r\n {children}\r\n </div>\r\n </CarouselContext.Provider>\r\n )\r\n}\r\n\r\nfunction CarouselContent({ className, ...props }: React.ComponentProps<\"div\">) {\r\n const { carouselRef, orientation } = useCarousel()\r\n\r\n return (\r\n <div\r\n ref={carouselRef}\r\n className=\"overflow-hidden\"\r\n data-slot=\"carousel-content\"\r\n >\r\n <div\r\n className={cn(\r\n \"flex\",\r\n orientation === \"horizontal\" ? \"-ml-4\" : \"-mt-4 flex-col\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n </div>\r\n )\r\n}\r\n\r\nfunction CarouselItem({ className, ...props }: React.ComponentProps<\"div\">) {\r\n const { orientation } = useCarousel()\r\n\r\n return (\r\n <div\r\n role=\"group\"\r\n aria-roledescription=\"slide\"\r\n data-slot=\"carousel-item\"\r\n className={cn(\r\n \"min-w-0 shrink-0 grow-0 basis-full\",\r\n orientation === \"horizontal\" ? \"pl-4\" : \"pt-4\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction CarouselPrevious({\r\n className,\r\n variant = \"outline\",\r\n size = \"icon-sm\",\r\n ...props\r\n}: React.ComponentProps<typeof Button>) {\r\n const { orientation, scrollPrev, canScrollPrev } = useCarousel()\r\n\r\n return (\r\n <Button\r\n data-slot=\"carousel-previous\"\r\n variant={variant}\r\n size={size}\r\n className={cn(\r\n \"absolute touch-manipulation rounded-full\",\r\n orientation === \"horizontal\"\r\n ? \"top-1/2 -left-12 -translate-y-1/2\"\r\n : \"-top-12 left-1/2 -translate-x-1/2 rotate-90\",\r\n className\r\n )}\r\n disabled={!canScrollPrev}\r\n onClick={scrollPrev}\r\n {...props}\r\n >\r\n <ChevronLeftIcon className=\"cn-rtl-flip\" />\r\n <span className=\"sr-only\">Previous slide</span>\r\n </Button>\r\n )\r\n}\r\n\r\nfunction CarouselNext({\r\n className,\r\n variant = \"outline\",\r\n size = \"icon-sm\",\r\n ...props\r\n}: React.ComponentProps<typeof Button>) {\r\n const { orientation, scrollNext, canScrollNext } = useCarousel()\r\n\r\n return (\r\n <Button\r\n data-slot=\"carousel-next\"\r\n variant={variant}\r\n size={size}\r\n className={cn(\r\n \"absolute touch-manipulation rounded-full\",\r\n orientation === \"horizontal\"\r\n ? \"top-1/2 -right-12 -translate-y-1/2\"\r\n : \"-bottom-12 left-1/2 -translate-x-1/2 rotate-90\",\r\n className\r\n )}\r\n disabled={!canScrollNext}\r\n onClick={scrollNext}\r\n {...props}\r\n >\r\n <ChevronRightIcon className=\"cn-rtl-flip\" />\r\n <span className=\"sr-only\">Next slide</span>\r\n </Button>\r\n )\r\n}\r\n\r\nexport {\r\n type CarouselApi,\r\n Carousel,\r\n CarouselContent,\r\n CarouselItem,\r\n CarouselPrevious,\r\n CarouselNext,\r\n useCarousel,\r\n}\r\n"
|
|
436
|
+
}
|
|
437
|
+
]
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
"name": "chart",
|
|
441
|
+
"type": "components:ui",
|
|
442
|
+
"frameworks": [
|
|
443
|
+
"react",
|
|
444
|
+
"nextjs"
|
|
445
|
+
],
|
|
446
|
+
"dependencies": [
|
|
447
|
+
"recharts",
|
|
448
|
+
"lucide-react"
|
|
449
|
+
],
|
|
450
|
+
"registryDependencies": [],
|
|
451
|
+
"files": [
|
|
452
|
+
{
|
|
453
|
+
"name": "chart.tsx",
|
|
454
|
+
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport * as RechartsPrimitive from \"recharts\"\r\nimport type { TooltipValueType } from \"recharts\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\n// Format: { THEME_NAME: CSS_SELECTOR }\r\nconst THEMES = { light: \"\", dark: \".dark\" } as const\r\n\r\nconst INITIAL_DIMENSION = { width: 320, height: 200 } as const\r\ntype TooltipNameType = number | string\r\n\r\nexport type ChartConfig = Record<\r\n string,\r\n {\r\n label?: React.ReactNode\r\n icon?: React.ComponentType\r\n } & (\r\n | { color?: string; theme?: never }\r\n | { color?: never; theme: Record<keyof typeof THEMES, string> }\r\n )\r\n>\r\n\r\ntype ChartContextProps = {\r\n config: ChartConfig\r\n}\r\n\r\nconst ChartContext = React.createContext<ChartContextProps | null>(null)\r\n\r\nfunction useChart() {\r\n const context = React.useContext(ChartContext)\r\n\r\n if (!context) {\r\n throw new Error(\"useChart must be used within a <ChartContainer />\")\r\n }\r\n\r\n return context\r\n}\r\n\r\nfunction ChartContainer({\r\n id,\r\n className,\r\n children,\r\n config,\r\n initialDimension = INITIAL_DIMENSION,\r\n ...props\r\n}: React.ComponentProps<\"div\"> & {\r\n config: ChartConfig\r\n children: React.ComponentProps<\r\n typeof RechartsPrimitive.ResponsiveContainer\r\n >[\"children\"]\r\n initialDimension?: {\r\n width: number\r\n height: number\r\n }\r\n}) {\r\n const uniqueId = React.useId()\r\n const chartId = `chart-${id ?? uniqueId.replace(/:/g, \"\")}`\r\n\r\n return (\r\n <ChartContext.Provider value={{ config }}>\r\n <div\r\n data-slot=\"chart\"\r\n data-chart={chartId}\r\n className={cn(\r\n \"flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n <ChartStyle id={chartId} config={config} />\r\n <RechartsPrimitive.ResponsiveContainer\r\n initialDimension={initialDimension}\r\n >\r\n {children}\r\n </RechartsPrimitive.ResponsiveContainer>\r\n </div>\r\n </ChartContext.Provider>\r\n )\r\n}\r\n\r\nconst ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {\r\n const colorConfig = Object.entries(config).filter(\r\n ([, config]) => config.theme ?? config.color\r\n )\r\n\r\n if (!colorConfig.length) {\r\n return null\r\n }\r\n\r\n return (\r\n <style\r\n dangerouslySetInnerHTML={{\r\n __html: Object.entries(THEMES)\r\n .map(\r\n ([theme, prefix]) => `\r\n${prefix} [data-chart=${id}] {\r\n${colorConfig\r\n .map(([key, itemConfig]) => {\r\n const color =\r\n itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ??\r\n itemConfig.color\r\n return color ? ` --color-${key}: ${color};` : null\r\n })\r\n .join(\"\\n\")}\r\n}\r\n`\r\n )\r\n .join(\"\\n\"),\r\n }}\r\n />\r\n )\r\n}\r\n\r\nconst ChartTooltip = RechartsPrimitive.Tooltip\r\n\r\nfunction ChartTooltipContent({\r\n active,\r\n payload,\r\n className,\r\n indicator = \"dot\",\r\n hideLabel = false,\r\n hideIndicator = false,\r\n label,\r\n labelFormatter,\r\n labelClassName,\r\n formatter,\r\n color,\r\n nameKey,\r\n labelKey,\r\n}: React.ComponentProps<typeof RechartsPrimitive.Tooltip> &\r\n React.ComponentProps<\"div\"> & {\r\n hideLabel?: boolean\r\n hideIndicator?: boolean\r\n indicator?: \"line\" | \"dot\" | \"dashed\"\r\n nameKey?: string\r\n labelKey?: string\r\n } & Omit<\r\n RechartsPrimitive.DefaultTooltipContentProps<\r\n TooltipValueType,\r\n TooltipNameType\r\n >,\r\n \"accessibilityLayer\"\r\n >) {\r\n const { config } = useChart()\r\n\r\n const tooltipLabel = React.useMemo(() => {\r\n if (hideLabel || !payload?.length) {\r\n return null\r\n }\r\n\r\n const [item] = payload\r\n const key = `${labelKey ?? item?.dataKey ?? item?.name ?? \"value\"}`\r\n const itemConfig = getPayloadConfigFromPayload(config, item, key)\r\n const value =\r\n !labelKey && typeof label === \"string\"\r\n ? (config[label]?.label ?? label)\r\n : itemConfig?.label\r\n\r\n if (labelFormatter) {\r\n return (\r\n <div className={cn(\"font-medium\", labelClassName)}>\r\n {labelFormatter(value, payload)}\r\n </div>\r\n )\r\n }\r\n\r\n if (!value) {\r\n return null\r\n }\r\n\r\n return <div className={cn(\"font-medium\", labelClassName)}>{value}</div>\r\n }, [\r\n label,\r\n labelFormatter,\r\n payload,\r\n hideLabel,\r\n labelClassName,\r\n config,\r\n labelKey,\r\n ])\r\n\r\n if (!active || !payload?.length) {\r\n return null\r\n }\r\n\r\n const nestLabel = payload.length === 1 && indicator !== \"dot\"\r\n\r\n return (\r\n <div\r\n className={cn(\r\n \"grid min-w-32 items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl\",\r\n className\r\n )}\r\n >\r\n {!nestLabel ? tooltipLabel : null}\r\n <div className=\"grid gap-1.5\">\r\n {payload\r\n .filter((item) => item.type !== \"none\")\r\n .map((item, index) => {\r\n const key = `${nameKey ?? item.name ?? item.dataKey ?? \"value\"}`\r\n const itemConfig = getPayloadConfigFromPayload(config, item, key)\r\n const indicatorColor = color ?? item.payload?.fill ?? item.color\r\n\r\n return (\r\n <div\r\n key={index}\r\n className={cn(\r\n \"flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground\",\r\n indicator === \"dot\" && \"items-center\"\r\n )}\r\n >\r\n {formatter && item?.value !== undefined && item.name ? (\r\n formatter(item.value, item.name, item, index, item.payload)\r\n ) : (\r\n <>\r\n {itemConfig?.icon ? (\r\n <itemConfig.icon />\r\n ) : (\r\n !hideIndicator && (\r\n <div\r\n className={cn(\r\n \"shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)\",\r\n {\r\n \"h-2.5 w-2.5\": indicator === \"dot\",\r\n \"w-1\": indicator === \"line\",\r\n \"w-0 border-[1.5px] border-dashed bg-transparent\":\r\n indicator === \"dashed\",\r\n \"my-0.5\": nestLabel && indicator === \"dashed\",\r\n }\r\n )}\r\n style={\r\n {\r\n \"--color-bg\": indicatorColor,\r\n \"--color-border\": indicatorColor,\r\n } as React.CSSProperties\r\n }\r\n />\r\n )\r\n )}\r\n <div\r\n className={cn(\r\n \"flex flex-1 justify-between leading-none\",\r\n nestLabel ? \"items-end\" : \"items-center\"\r\n )}\r\n >\r\n <div className=\"grid gap-1.5\">\r\n {nestLabel ? tooltipLabel : null}\r\n <span className=\"text-muted-foreground\">\r\n {itemConfig?.label ?? item.name}\r\n </span>\r\n </div>\r\n {item.value != null && (\r\n <span className=\"font-mono font-medium text-foreground tabular-nums\">\r\n {typeof item.value === \"number\"\r\n ? item.value.toLocaleString()\r\n : String(item.value)}\r\n </span>\r\n )}\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n )\r\n })}\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nconst ChartLegend = RechartsPrimitive.Legend\r\n\r\nfunction ChartLegendContent({\r\n className,\r\n hideIcon = false,\r\n payload,\r\n verticalAlign = \"bottom\",\r\n nameKey,\r\n}: React.ComponentProps<\"div\"> & {\r\n hideIcon?: boolean\r\n nameKey?: string\r\n} & RechartsPrimitive.DefaultLegendContentProps) {\r\n const { config } = useChart()\r\n\r\n if (!payload?.length) {\r\n return null\r\n }\r\n\r\n return (\r\n <div\r\n className={cn(\r\n \"flex items-center justify-center gap-4\",\r\n verticalAlign === \"top\" ? \"pb-3\" : \"pt-3\",\r\n className\r\n )}\r\n >\r\n {payload\r\n .filter((item) => item.type !== \"none\")\r\n .map((item, index) => {\r\n const key = `${nameKey ?? item.dataKey ?? \"value\"}`\r\n const itemConfig = getPayloadConfigFromPayload(config, item, key)\r\n\r\n return (\r\n <div\r\n key={index}\r\n className={cn(\r\n \"flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground\"\r\n )}\r\n >\r\n {itemConfig?.icon && !hideIcon ? (\r\n <itemConfig.icon />\r\n ) : (\r\n <div\r\n className=\"h-2 w-2 shrink-0 rounded-[2px]\"\r\n style={{\r\n backgroundColor: item.color,\r\n }}\r\n />\r\n )}\r\n {itemConfig?.label}\r\n </div>\r\n )\r\n })}\r\n </div>\r\n )\r\n}\r\n\r\nfunction getPayloadConfigFromPayload(\r\n config: ChartConfig,\r\n payload: unknown,\r\n key: string\r\n) {\r\n if (typeof payload !== \"object\" || payload === null) {\r\n return undefined\r\n }\r\n\r\n const payloadPayload =\r\n \"payload\" in payload &&\r\n typeof payload.payload === \"object\" &&\r\n payload.payload !== null\r\n ? payload.payload\r\n : undefined\r\n\r\n let configLabelKey: string = key\r\n\r\n if (\r\n key in payload &&\r\n typeof payload[key as keyof typeof payload] === \"string\"\r\n ) {\r\n configLabelKey = payload[key as keyof typeof payload] as string\r\n } else if (\r\n payloadPayload &&\r\n key in payloadPayload &&\r\n typeof payloadPayload[key as keyof typeof payloadPayload] === \"string\"\r\n ) {\r\n configLabelKey = payloadPayload[\r\n key as keyof typeof payloadPayload\r\n ] as string\r\n }\r\n\r\n return configLabelKey in config ? config[configLabelKey] : config[key]\r\n}\r\n\r\nexport {\r\n ChartContainer,\r\n ChartTooltip,\r\n ChartTooltipContent,\r\n ChartLegend,\r\n ChartLegendContent,\r\n ChartStyle,\r\n}\r\n"
|
|
120
455
|
}
|
|
121
456
|
]
|
|
122
457
|
},
|
|
123
458
|
{
|
|
124
459
|
"name": "checkbox",
|
|
460
|
+
"type": "components:ui",
|
|
461
|
+
"frameworks": [
|
|
462
|
+
"react",
|
|
463
|
+
"nextjs",
|
|
464
|
+
"vue",
|
|
465
|
+
"nuxt",
|
|
466
|
+
"solid",
|
|
467
|
+
"svelte",
|
|
468
|
+
"astro",
|
|
469
|
+
"remix"
|
|
470
|
+
],
|
|
125
471
|
"dependencies": [
|
|
126
472
|
"@base-ui/react"
|
|
127
473
|
],
|
|
474
|
+
"registryDependencies": [],
|
|
128
475
|
"files": [
|
|
129
476
|
{
|
|
130
477
|
"name": "checkbox.tsx",
|
|
131
|
-
"content": "\"use client\"\r\n\r\nimport
|
|
478
|
+
"content": "\"use client\"\r\n\r\nimport { Checkbox as CheckboxPrimitive } from \"@base-ui/react/checkbox\"\r\nimport { CheckIcon } from \"lucide-react\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction Checkbox({ className, ...props }: CheckboxPrimitive.Root.Props) {\r\n return (\r\n <CheckboxPrimitive.Root\r\n data-slot=\"checkbox\"\r\n className={cn(\r\n \"peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input transition-colors outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n <CheckboxPrimitive.Indicator\r\n data-slot=\"checkbox-indicator\"\r\n className=\"grid place-content-center text-current transition-none [&>svg]:size-3.5\"\r\n >\r\n <CheckIcon />\r\n </CheckboxPrimitive.Indicator>\r\n </CheckboxPrimitive.Root>\r\n )\r\n}\r\n\r\nexport { Checkbox }\r\n"
|
|
132
479
|
}
|
|
133
480
|
]
|
|
134
481
|
},
|
|
135
482
|
{
|
|
136
483
|
"name": "collapsible",
|
|
484
|
+
"type": "components:ui",
|
|
485
|
+
"frameworks": [
|
|
486
|
+
"react",
|
|
487
|
+
"nextjs",
|
|
488
|
+
"vue",
|
|
489
|
+
"nuxt",
|
|
490
|
+
"solid",
|
|
491
|
+
"svelte",
|
|
492
|
+
"astro",
|
|
493
|
+
"remix"
|
|
494
|
+
],
|
|
137
495
|
"dependencies": [
|
|
138
496
|
"@base-ui/react"
|
|
139
497
|
],
|
|
498
|
+
"registryDependencies": [],
|
|
140
499
|
"files": [
|
|
141
500
|
{
|
|
142
501
|
"name": "collapsible.tsx",
|
|
143
|
-
"content": "\"use client\"\r\n\r\nimport
|
|
502
|
+
"content": "\"use client\"\r\n\r\nimport { Collapsible as CollapsiblePrimitive } from \"@base-ui/react/collapsible\"\r\n\r\nfunction Collapsible({ ...props }: CollapsiblePrimitive.Root.Props) {\r\n return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\r\n}\r\n\r\nfunction CollapsibleTrigger({ ...props }: CollapsiblePrimitive.Trigger.Props) {\r\n return (\r\n <CollapsiblePrimitive.Trigger data-slot=\"collapsible-trigger\" {...props} />\r\n )\r\n}\r\n\r\nfunction CollapsibleContent({ ...props }: CollapsiblePrimitive.Panel.Props) {\r\n return (\r\n <CollapsiblePrimitive.Panel data-slot=\"collapsible-content\" {...props} />\r\n )\r\n}\r\n\r\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\r\n"
|
|
144
503
|
}
|
|
145
504
|
]
|
|
146
505
|
},
|
|
147
506
|
{
|
|
148
507
|
"name": "context-menu",
|
|
508
|
+
"type": "components:ui",
|
|
509
|
+
"frameworks": [
|
|
510
|
+
"react",
|
|
511
|
+
"nextjs",
|
|
512
|
+
"vue",
|
|
513
|
+
"nuxt",
|
|
514
|
+
"solid",
|
|
515
|
+
"svelte",
|
|
516
|
+
"astro",
|
|
517
|
+
"remix"
|
|
518
|
+
],
|
|
149
519
|
"dependencies": [
|
|
150
520
|
"@base-ui/react"
|
|
151
521
|
],
|
|
522
|
+
"registryDependencies": [],
|
|
152
523
|
"files": [
|
|
153
524
|
{
|
|
154
525
|
"name": "context-menu.tsx",
|
|
155
|
-
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport {
|
|
526
|
+
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { ContextMenu as ContextMenuPrimitive } from \"@base-ui/react/context-menu\"\r\nimport { CheckIcon, ChevronRightIcon } from \"lucide-react\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction ContextMenu({ ...props }: ContextMenuPrimitive.Root.Props) {\r\n return <ContextMenuPrimitive.Root data-slot=\"context-menu\" {...props} />\r\n}\r\n\r\nfunction ContextMenuPortal({ ...props }: ContextMenuPrimitive.Portal.Props) {\r\n return (\r\n <ContextMenuPrimitive.Portal data-slot=\"context-menu-portal\" {...props} />\r\n )\r\n}\r\n\r\nfunction ContextMenuTrigger({\r\n className,\r\n ...props\r\n}: ContextMenuPrimitive.Trigger.Props) {\r\n return (\r\n <ContextMenuPrimitive.Trigger\r\n data-slot=\"context-menu-trigger\"\r\n className={cn(\"select-none\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction ContextMenuContent({\r\n className,\r\n align = \"start\",\r\n alignOffset = 4,\r\n side = \"right\",\r\n sideOffset = 0,\r\n ...props\r\n}: ContextMenuPrimitive.Popup.Props &\r\n Pick<\r\n ContextMenuPrimitive.Positioner.Props,\r\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\r\n >) {\r\n return (\r\n <ContextMenuPrimitive.Portal>\r\n <ContextMenuPrimitive.Positioner\r\n className=\"isolate z-50 outline-none\"\r\n align={align}\r\n alignOffset={alignOffset}\r\n side={side}\r\n sideOffset={sideOffset}\r\n >\r\n <ContextMenuPrimitive.Popup\r\n data-slot=\"context-menu-content\"\r\n className={cn(\"z-50 max-h-(--available-height) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\", className )}\r\n {...props}\r\n />\r\n </ContextMenuPrimitive.Positioner>\r\n </ContextMenuPrimitive.Portal>\r\n )\r\n}\r\n\r\nfunction ContextMenuGroup({ ...props }: ContextMenuPrimitive.Group.Props) {\r\n return (\r\n <ContextMenuPrimitive.Group data-slot=\"context-menu-group\" {...props} />\r\n )\r\n}\r\n\r\nfunction ContextMenuLabel({\r\n className,\r\n inset,\r\n ...props\r\n}: ContextMenuPrimitive.GroupLabel.Props & {\r\n inset?: boolean\r\n}) {\r\n return (\r\n <ContextMenuPrimitive.GroupLabel\r\n data-slot=\"context-menu-label\"\r\n data-inset={inset}\r\n className={cn(\r\n \"px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction ContextMenuItem({\r\n className,\r\n inset,\r\n variant = \"default\",\r\n ...props\r\n}: ContextMenuPrimitive.Item.Props & {\r\n inset?: boolean\r\n variant?: \"default\" | \"destructive\"\r\n}) {\r\n return (\r\n <ContextMenuPrimitive.Item\r\n data-slot=\"context-menu-item\"\r\n data-inset={inset}\r\n data-variant={variant}\r\n className={cn(\r\n \"group/context-menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 focus:*:[svg]:text-accent-foreground data-[variant=destructive]:*:[svg]:text-destructive\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction ContextMenuSub({ ...props }: ContextMenuPrimitive.SubmenuRoot.Props) {\r\n return (\r\n <ContextMenuPrimitive.SubmenuRoot data-slot=\"context-menu-sub\" {...props} />\r\n )\r\n}\r\n\r\nfunction ContextMenuSubTrigger({\r\n className,\r\n inset,\r\n children,\r\n ...props\r\n}: ContextMenuPrimitive.SubmenuTrigger.Props & {\r\n inset?: boolean\r\n}) {\r\n return (\r\n <ContextMenuPrimitive.SubmenuTrigger\r\n data-slot=\"context-menu-sub-trigger\"\r\n data-inset={inset}\r\n className={cn(\r\n \"flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-7 data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n {children}\r\n <ChevronRightIcon className=\"cn-rtl-flip ml-auto\" />\r\n </ContextMenuPrimitive.SubmenuTrigger>\r\n )\r\n}\r\n\r\nfunction ContextMenuSubContent({\r\n ...props\r\n}: React.ComponentProps<typeof ContextMenuContent>) {\r\n return (\r\n <ContextMenuContent\r\n data-slot=\"context-menu-sub-content\"\r\n className=\"shadow-lg\"\r\n side=\"right\"\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction ContextMenuCheckboxItem({\r\n className,\r\n children,\r\n checked,\r\n inset,\r\n ...props\r\n}: ContextMenuPrimitive.CheckboxItem.Props & {\r\n inset?: boolean\r\n}) {\r\n return (\r\n <ContextMenuPrimitive.CheckboxItem\r\n data-slot=\"context-menu-checkbox-item\"\r\n data-inset={inset}\r\n className={cn(\r\n \"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\r\n className\r\n )}\r\n checked={checked}\r\n {...props}\r\n >\r\n <span className=\"pointer-events-none absolute right-2\">\r\n <ContextMenuPrimitive.CheckboxItemIndicator>\r\n <CheckIcon />\r\n </ContextMenuPrimitive.CheckboxItemIndicator>\r\n </span>\r\n {children}\r\n </ContextMenuPrimitive.CheckboxItem>\r\n )\r\n}\r\n\r\nfunction ContextMenuRadioGroup({\r\n ...props\r\n}: ContextMenuPrimitive.RadioGroup.Props) {\r\n return (\r\n <ContextMenuPrimitive.RadioGroup\r\n data-slot=\"context-menu-radio-group\"\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction ContextMenuRadioItem({\r\n className,\r\n children,\r\n inset,\r\n ...props\r\n}: ContextMenuPrimitive.RadioItem.Props & {\r\n inset?: boolean\r\n}) {\r\n return (\r\n <ContextMenuPrimitive.RadioItem\r\n data-slot=\"context-menu-radio-item\"\r\n data-inset={inset}\r\n className={cn(\r\n \"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n <span className=\"pointer-events-none absolute right-2\">\r\n <ContextMenuPrimitive.RadioItemIndicator>\r\n <CheckIcon />\r\n </ContextMenuPrimitive.RadioItemIndicator>\r\n </span>\r\n {children}\r\n </ContextMenuPrimitive.RadioItem>\r\n )\r\n}\r\n\r\nfunction ContextMenuSeparator({\r\n className,\r\n ...props\r\n}: ContextMenuPrimitive.Separator.Props) {\r\n return (\r\n <ContextMenuPrimitive.Separator\r\n data-slot=\"context-menu-separator\"\r\n className={cn(\"-mx-1 my-1 h-px bg-border\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction ContextMenuShortcut({\r\n className,\r\n ...props\r\n}: React.ComponentProps<\"span\">) {\r\n return (\r\n <span\r\n data-slot=\"context-menu-shortcut\"\r\n className={cn(\r\n \"ml-auto text-xs tracking-widest text-muted-foreground group-focus/context-menu-item:text-accent-foreground\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport {\r\n ContextMenu,\r\n ContextMenuTrigger,\r\n ContextMenuContent,\r\n ContextMenuItem,\r\n ContextMenuCheckboxItem,\r\n ContextMenuRadioItem,\r\n ContextMenuLabel,\r\n ContextMenuSeparator,\r\n ContextMenuShortcut,\r\n ContextMenuGroup,\r\n ContextMenuPortal,\r\n ContextMenuSub,\r\n ContextMenuSubContent,\r\n ContextMenuSubTrigger,\r\n ContextMenuRadioGroup,\r\n}\r\n"
|
|
156
527
|
}
|
|
157
528
|
]
|
|
158
529
|
},
|
|
159
530
|
{
|
|
160
531
|
"name": "dialog",
|
|
532
|
+
"type": "components:ui",
|
|
533
|
+
"frameworks": [
|
|
534
|
+
"react",
|
|
535
|
+
"nextjs",
|
|
536
|
+
"vue",
|
|
537
|
+
"nuxt",
|
|
538
|
+
"solid",
|
|
539
|
+
"svelte",
|
|
540
|
+
"astro",
|
|
541
|
+
"remix"
|
|
542
|
+
],
|
|
161
543
|
"dependencies": [
|
|
162
544
|
"@base-ui/react"
|
|
163
545
|
],
|
|
546
|
+
"registryDependencies": [],
|
|
164
547
|
"files": [
|
|
165
548
|
{
|
|
166
549
|
"name": "dialog.tsx",
|
|
167
|
-
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { Dialog as
|
|
550
|
+
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { Dialog as DialogPrimitive } from \"@base-ui/react/dialog\"\r\nimport { XIcon } from \"lucide-react\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\nimport { Button } from \"@/button\"\r\n\r\nfunction Dialog({ ...props }: DialogPrimitive.Root.Props) {\r\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />\r\n}\r\n\r\nfunction DialogTrigger({ ...props }: DialogPrimitive.Trigger.Props) {\r\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />\r\n}\r\n\r\nfunction DialogPortal({ ...props }: DialogPrimitive.Portal.Props) {\r\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />\r\n}\r\n\r\nfunction DialogClose({ ...props }: DialogPrimitive.Close.Props) {\r\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />\r\n}\r\n\r\nfunction DialogOverlay({\r\n className,\r\n ...props\r\n}: DialogPrimitive.Backdrop.Props) {\r\n return (\r\n <DialogPrimitive.Backdrop\r\n data-slot=\"dialog-overlay\"\r\n className={cn(\r\n \"fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction DialogContent({\r\n className,\r\n children,\r\n showCloseButton = true,\r\n ...props\r\n}: DialogPrimitive.Popup.Props & {\r\n showCloseButton?: boolean\r\n}) {\r\n return (\r\n <DialogPortal>\r\n <DialogOverlay />\r\n <DialogPrimitive.Popup\r\n data-slot=\"dialog-content\"\r\n className={cn(\r\n \"fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-sm text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n {children}\r\n {showCloseButton && (\r\n <DialogPrimitive.Close data-slot=\"dialog-close\" render={<Button variant=\"ghost\" className=\"absolute top-2 right-2\" size=\"icon-sm\"><XIcon /><span className=\"sr-only\">Close</span></Button>} />\r\n )}\r\n </DialogPrimitive.Popup>\r\n </DialogPortal>\r\n )\r\n}\r\n\r\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"dialog-header\"\r\n className={cn(\"flex flex-col gap-2\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction DialogFooter({\r\n className,\r\n showCloseButton = false,\r\n children,\r\n ...props\r\n}: React.ComponentProps<\"div\"> & {\r\n showCloseButton?: boolean\r\n}) {\r\n return (\r\n <div\r\n data-slot=\"dialog-footer\"\r\n className={cn(\r\n \"-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 sm:flex-row sm:justify-end\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n {children}\r\n {showCloseButton && (\r\n <DialogPrimitive.Close render={<Button variant=\"outline\">Close</Button>} />\r\n )}\r\n </div>\r\n )\r\n}\r\n\r\nfunction DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {\r\n return (\r\n <DialogPrimitive.Title\r\n data-slot=\"dialog-title\"\r\n className={cn(\r\n \"cn-font-heading text-base leading-none font-medium\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction DialogDescription({\r\n className,\r\n ...props\r\n}: DialogPrimitive.Description.Props) {\r\n return (\r\n <DialogPrimitive.Description\r\n data-slot=\"dialog-description\"\r\n className={cn(\r\n \"text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport {\r\n Dialog,\r\n DialogClose,\r\n DialogContent,\r\n DialogDescription,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogOverlay,\r\n DialogPortal,\r\n DialogTitle,\r\n DialogTrigger,\r\n}\r\n"
|
|
168
551
|
}
|
|
169
552
|
]
|
|
170
553
|
},
|
|
171
554
|
{
|
|
172
555
|
"name": "drawer",
|
|
556
|
+
"type": "components:ui",
|
|
557
|
+
"frameworks": [
|
|
558
|
+
"react",
|
|
559
|
+
"nextjs",
|
|
560
|
+
"vue",
|
|
561
|
+
"nuxt",
|
|
562
|
+
"solid",
|
|
563
|
+
"svelte",
|
|
564
|
+
"astro",
|
|
565
|
+
"remix"
|
|
566
|
+
],
|
|
173
567
|
"dependencies": [
|
|
174
568
|
"@base-ui/react"
|
|
175
569
|
],
|
|
570
|
+
"registryDependencies": [],
|
|
176
571
|
"files": [
|
|
177
572
|
{
|
|
178
573
|
"name": "drawer.tsx",
|
|
179
|
-
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport {
|
|
574
|
+
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { Drawer as DrawerPrimitive } from \"vaul\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction Drawer({\r\n ...props\r\n}: React.ComponentProps<typeof DrawerPrimitive.Root>) {\r\n return <DrawerPrimitive.Root data-slot=\"drawer\" {...props} />\r\n}\r\n\r\nfunction DrawerTrigger({\r\n ...props\r\n}: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {\r\n return <DrawerPrimitive.Trigger data-slot=\"drawer-trigger\" {...props} />\r\n}\r\n\r\nfunction DrawerPortal({\r\n ...props\r\n}: React.ComponentProps<typeof DrawerPrimitive.Portal>) {\r\n return <DrawerPrimitive.Portal data-slot=\"drawer-portal\" {...props} />\r\n}\r\n\r\nfunction DrawerClose({\r\n ...props\r\n}: React.ComponentProps<typeof DrawerPrimitive.Close>) {\r\n return <DrawerPrimitive.Close data-slot=\"drawer-close\" {...props} />\r\n}\r\n\r\nfunction DrawerOverlay({\r\n className,\r\n ...props\r\n}: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {\r\n return (\r\n <DrawerPrimitive.Overlay\r\n data-slot=\"drawer-overlay\"\r\n className={cn(\r\n \"fixed inset-0 z-50 bg-black/10 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction DrawerContent({\r\n className,\r\n children,\r\n ...props\r\n}: React.ComponentProps<typeof DrawerPrimitive.Content>) {\r\n return (\r\n <DrawerPortal data-slot=\"drawer-portal\">\r\n <DrawerOverlay />\r\n <DrawerPrimitive.Content\r\n data-slot=\"drawer-content\"\r\n className={cn(\r\n \"group/drawer-content fixed z-50 flex h-auto flex-col bg-popover text-sm text-popover-foreground data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-xl data-[vaul-drawer-direction=bottom]:border-t data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:rounded-r-xl data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:rounded-l-xl data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-xl data-[vaul-drawer-direction=top]:border-b data-[vaul-drawer-direction=left]:sm:max-w-sm data-[vaul-drawer-direction=right]:sm:max-w-sm\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n <div className=\"mx-auto mt-4 hidden h-1 w-[100px] shrink-0 rounded-full bg-muted group-data-[vaul-drawer-direction=bottom]/drawer-content:block\" />\r\n {children}\r\n </DrawerPrimitive.Content>\r\n </DrawerPortal>\r\n )\r\n}\r\n\r\nfunction DrawerHeader({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"drawer-header\"\r\n className={cn(\r\n \"flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-0.5 md:text-left\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction DrawerFooter({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"drawer-footer\"\r\n className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction DrawerTitle({\r\n className,\r\n ...props\r\n}: React.ComponentProps<typeof DrawerPrimitive.Title>) {\r\n return (\r\n <DrawerPrimitive.Title\r\n data-slot=\"drawer-title\"\r\n className={cn(\r\n \"cn-font-heading text-base font-medium text-foreground\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction DrawerDescription({\r\n className,\r\n ...props\r\n}: React.ComponentProps<typeof DrawerPrimitive.Description>) {\r\n return (\r\n <DrawerPrimitive.Description\r\n data-slot=\"drawer-description\"\r\n className={cn(\"text-sm text-muted-foreground\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport {\r\n Drawer,\r\n DrawerPortal,\r\n DrawerOverlay,\r\n DrawerTrigger,\r\n DrawerClose,\r\n DrawerContent,\r\n DrawerHeader,\r\n DrawerFooter,\r\n DrawerTitle,\r\n DrawerDescription,\r\n}\r\n"
|
|
180
575
|
}
|
|
181
576
|
]
|
|
182
577
|
},
|
|
183
578
|
{
|
|
184
579
|
"name": "dropdown-menu",
|
|
580
|
+
"type": "components:ui",
|
|
581
|
+
"frameworks": [
|
|
582
|
+
"react",
|
|
583
|
+
"nextjs",
|
|
584
|
+
"vue",
|
|
585
|
+
"nuxt",
|
|
586
|
+
"solid",
|
|
587
|
+
"svelte",
|
|
588
|
+
"astro",
|
|
589
|
+
"remix"
|
|
590
|
+
],
|
|
185
591
|
"dependencies": [
|
|
186
592
|
"@base-ui/react"
|
|
187
593
|
],
|
|
594
|
+
"registryDependencies": [],
|
|
188
595
|
"files": [
|
|
189
596
|
{
|
|
190
597
|
"name": "dropdown-menu.tsx",
|
|
191
|
-
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { Menu as
|
|
598
|
+
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { Menu as MenuPrimitive } from \"@base-ui/react/menu\"\r\nimport { CheckIcon, ChevronRightIcon } from \"lucide-react\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction DropdownMenu({ ...props }: MenuPrimitive.Root.Props) {\r\n return <MenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\r\n}\r\n\r\nfunction DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) {\r\n return <MenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\r\n}\r\n\r\nfunction DropdownMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) {\r\n return <MenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />\r\n}\r\n\r\nfunction DropdownMenuContent({\r\n align = \"start\",\r\n alignOffset = 0,\r\n side = \"bottom\",\r\n sideOffset = 4,\r\n className,\r\n ...props\r\n}: MenuPrimitive.Popup.Props &\r\n Pick<\r\n MenuPrimitive.Positioner.Props,\r\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\r\n >) {\r\n return (\r\n <MenuPrimitive.Portal>\r\n <MenuPrimitive.Positioner\r\n className=\"isolate z-50 outline-none\"\r\n align={align}\r\n alignOffset={alignOffset}\r\n side={side}\r\n sideOffset={sideOffset}\r\n >\r\n <MenuPrimitive.Popup\r\n data-slot=\"dropdown-menu-content\"\r\n className={cn(\"z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95\", className )}\r\n {...props}\r\n />\r\n </MenuPrimitive.Positioner>\r\n </MenuPrimitive.Portal>\r\n )\r\n}\r\n\r\nfunction DropdownMenuGroup({ ...props }: MenuPrimitive.Group.Props) {\r\n return <MenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\r\n}\r\n\r\nfunction DropdownMenuLabel({\r\n className,\r\n inset,\r\n ...props\r\n}: MenuPrimitive.GroupLabel.Props & {\r\n inset?: boolean\r\n}) {\r\n return (\r\n <MenuPrimitive.GroupLabel\r\n data-slot=\"dropdown-menu-label\"\r\n data-inset={inset}\r\n className={cn(\r\n \"px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction DropdownMenuItem({\r\n className,\r\n inset,\r\n variant = \"default\",\r\n ...props\r\n}: MenuPrimitive.Item.Props & {\r\n inset?: boolean\r\n variant?: \"default\" | \"destructive\"\r\n}) {\r\n return (\r\n <MenuPrimitive.Item\r\n data-slot=\"dropdown-menu-item\"\r\n data-inset={inset}\r\n data-variant={variant}\r\n className={cn(\r\n \"group/dropdown-menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {\r\n return <MenuPrimitive.SubmenuRoot data-slot=\"dropdown-menu-sub\" {...props} />\r\n}\r\n\r\nfunction DropdownMenuSubTrigger({\r\n className,\r\n inset,\r\n children,\r\n ...props\r\n}: MenuPrimitive.SubmenuTrigger.Props & {\r\n inset?: boolean\r\n}) {\r\n return (\r\n <MenuPrimitive.SubmenuTrigger\r\n data-slot=\"dropdown-menu-sub-trigger\"\r\n data-inset={inset}\r\n className={cn(\r\n \"flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-popup-open:bg-accent data-popup-open:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n {children}\r\n <ChevronRightIcon className=\"cn-rtl-flip ml-auto\" />\r\n </MenuPrimitive.SubmenuTrigger>\r\n )\r\n}\r\n\r\nfunction DropdownMenuSubContent({\r\n align = \"start\",\r\n alignOffset = -3,\r\n side = \"right\",\r\n sideOffset = 0,\r\n className,\r\n ...props\r\n}: React.ComponentProps<typeof DropdownMenuContent>) {\r\n return (\r\n <DropdownMenuContent\r\n data-slot=\"dropdown-menu-sub-content\"\r\n className={cn(\"w-auto min-w-[96px] rounded-lg bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\", className )}\r\n align={align}\r\n alignOffset={alignOffset}\r\n side={side}\r\n sideOffset={sideOffset}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction DropdownMenuCheckboxItem({\r\n className,\r\n children,\r\n checked,\r\n inset,\r\n ...props\r\n}: MenuPrimitive.CheckboxItem.Props & {\r\n inset?: boolean\r\n}) {\r\n return (\r\n <MenuPrimitive.CheckboxItem\r\n data-slot=\"dropdown-menu-checkbox-item\"\r\n data-inset={inset}\r\n className={cn(\r\n \"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\r\n className\r\n )}\r\n checked={checked}\r\n {...props}\r\n >\r\n <span\r\n className=\"pointer-events-none absolute right-2 flex items-center justify-center\"\r\n data-slot=\"dropdown-menu-checkbox-item-indicator\"\r\n >\r\n <MenuPrimitive.CheckboxItemIndicator>\r\n <CheckIcon />\r\n </MenuPrimitive.CheckboxItemIndicator>\r\n </span>\r\n {children}\r\n </MenuPrimitive.CheckboxItem>\r\n )\r\n}\r\n\r\nfunction DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {\r\n return (\r\n <MenuPrimitive.RadioGroup\r\n data-slot=\"dropdown-menu-radio-group\"\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction DropdownMenuRadioItem({\r\n className,\r\n children,\r\n inset,\r\n ...props\r\n}: MenuPrimitive.RadioItem.Props & {\r\n inset?: boolean\r\n}) {\r\n return (\r\n <MenuPrimitive.RadioItem\r\n data-slot=\"dropdown-menu-radio-item\"\r\n data-inset={inset}\r\n className={cn(\r\n \"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n <span\r\n className=\"pointer-events-none absolute right-2 flex items-center justify-center\"\r\n data-slot=\"dropdown-menu-radio-item-indicator\"\r\n >\r\n <MenuPrimitive.RadioItemIndicator>\r\n <CheckIcon />\r\n </MenuPrimitive.RadioItemIndicator>\r\n </span>\r\n {children}\r\n </MenuPrimitive.RadioItem>\r\n )\r\n}\r\n\r\nfunction DropdownMenuSeparator({\r\n className,\r\n ...props\r\n}: MenuPrimitive.Separator.Props) {\r\n return (\r\n <MenuPrimitive.Separator\r\n data-slot=\"dropdown-menu-separator\"\r\n className={cn(\"-mx-1 my-1 h-px bg-border\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction DropdownMenuShortcut({\r\n className,\r\n ...props\r\n}: React.ComponentProps<\"span\">) {\r\n return (\r\n <span\r\n data-slot=\"dropdown-menu-shortcut\"\r\n className={cn(\r\n \"ml-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport {\r\n DropdownMenu,\r\n DropdownMenuPortal,\r\n DropdownMenuTrigger,\r\n DropdownMenuContent,\r\n DropdownMenuGroup,\r\n DropdownMenuLabel,\r\n DropdownMenuItem,\r\n DropdownMenuCheckboxItem,\r\n DropdownMenuRadioGroup,\r\n DropdownMenuRadioItem,\r\n DropdownMenuSeparator,\r\n DropdownMenuShortcut,\r\n DropdownMenuSub,\r\n DropdownMenuSubTrigger,\r\n DropdownMenuSubContent,\r\n}\r\n"
|
|
192
599
|
}
|
|
193
600
|
]
|
|
194
601
|
},
|
|
195
602
|
{
|
|
196
603
|
"name": "hover-card",
|
|
604
|
+
"type": "components:ui",
|
|
605
|
+
"frameworks": [
|
|
606
|
+
"react",
|
|
607
|
+
"nextjs",
|
|
608
|
+
"vue",
|
|
609
|
+
"nuxt",
|
|
610
|
+
"solid",
|
|
611
|
+
"svelte",
|
|
612
|
+
"astro",
|
|
613
|
+
"remix"
|
|
614
|
+
],
|
|
197
615
|
"dependencies": [
|
|
198
616
|
"@base-ui/react"
|
|
199
617
|
],
|
|
618
|
+
"registryDependencies": [],
|
|
200
619
|
"files": [
|
|
201
620
|
{
|
|
202
621
|
"name": "hover-card.tsx",
|
|
203
|
-
"content": "\"use client\"\r\n\r\nimport
|
|
622
|
+
"content": "\"use client\"\r\n\r\nimport { PreviewCard as PreviewCardPrimitive } from \"@base-ui/react/preview-card\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction HoverCard({ ...props }: PreviewCardPrimitive.Root.Props) {\r\n return <PreviewCardPrimitive.Root data-slot=\"hover-card\" {...props} />\r\n}\r\n\r\nfunction HoverCardTrigger({ ...props }: PreviewCardPrimitive.Trigger.Props) {\r\n return (\r\n <PreviewCardPrimitive.Trigger data-slot=\"hover-card-trigger\" {...props} />\r\n )\r\n}\r\n\r\nfunction HoverCardContent({\r\n className,\r\n side = \"bottom\",\r\n sideOffset = 4,\r\n align = \"center\",\r\n alignOffset = 4,\r\n ...props\r\n}: PreviewCardPrimitive.Popup.Props &\r\n Pick<\r\n PreviewCardPrimitive.Positioner.Props,\r\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\r\n >) {\r\n return (\r\n <PreviewCardPrimitive.Portal data-slot=\"hover-card-portal\">\r\n <PreviewCardPrimitive.Positioner\r\n align={align}\r\n alignOffset={alignOffset}\r\n side={side}\r\n sideOffset={sideOffset}\r\n className=\"isolate z-50\"\r\n >\r\n <PreviewCardPrimitive.Popup\r\n data-slot=\"hover-card-content\"\r\n className={cn(\r\n \"z-50 w-64 origin-(--transform-origin) rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n </PreviewCardPrimitive.Positioner>\r\n </PreviewCardPrimitive.Portal>\r\n )\r\n}\r\n\r\nexport { HoverCard, HoverCardTrigger, HoverCardContent }\r\n"
|
|
204
623
|
}
|
|
205
624
|
]
|
|
206
625
|
},
|
|
207
626
|
{
|
|
208
627
|
"name": "input-group",
|
|
628
|
+
"type": "components:ui",
|
|
629
|
+
"frameworks": [
|
|
630
|
+
"react",
|
|
631
|
+
"nextjs",
|
|
632
|
+
"vue",
|
|
633
|
+
"nuxt",
|
|
634
|
+
"solid",
|
|
635
|
+
"svelte",
|
|
636
|
+
"astro",
|
|
637
|
+
"remix"
|
|
638
|
+
],
|
|
209
639
|
"dependencies": [],
|
|
640
|
+
"registryDependencies": [],
|
|
210
641
|
"files": [
|
|
211
642
|
{
|
|
212
643
|
"name": "input-group.tsx",
|
|
213
|
-
"content": "
|
|
644
|
+
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { cva, type VariantProps } from \"class-variance-authority\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\nimport { Button } from \"@/button\"\r\nimport { Input } from \"@/input\"\r\nimport { Textarea } from \"@/textarea\"\r\n\r\nfunction InputGroup({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"input-group\"\r\n role=\"group\"\r\n className={cn(\r\n \"group/input-group relative flex h-8 w-full min-w-0 items-center rounded-lg border border-input transition-colors outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:bg-input/50 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-disabled:bg-input/80 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nconst inputGroupAddonVariants = cva(\r\n \"flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4\",\r\n {\r\n variants: {\r\n align: {\r\n \"inline-start\":\r\n \"order-first pl-2 has-[>button]:ml-[-0.3rem] has-[>kbd]:ml-[-0.15rem]\",\r\n \"inline-end\":\r\n \"order-last pr-2 has-[>button]:mr-[-0.3rem] has-[>kbd]:mr-[-0.15rem]\",\r\n \"block-start\":\r\n \"order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2\",\r\n \"block-end\":\r\n \"order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2\",\r\n },\r\n },\r\n defaultVariants: {\r\n align: \"inline-start\",\r\n },\r\n }\r\n)\r\n\r\nfunction InputGroupAddon({\r\n className,\r\n align = \"inline-start\",\r\n ...props\r\n}: React.ComponentProps<\"div\"> & VariantProps<typeof inputGroupAddonVariants>) {\r\n return (\r\n <div\r\n role=\"group\"\r\n data-slot=\"input-group-addon\"\r\n data-align={align}\r\n className={cn(inputGroupAddonVariants({ align }), className)}\r\n onClick={(e) => {\r\n if ((e.target as HTMLElement).closest(\"button\")) {\r\n return\r\n }\r\n e.currentTarget.parentElement?.querySelector(\"input\")?.focus()\r\n }}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nconst inputGroupButtonVariants = cva(\r\n \"flex items-center gap-2 text-sm shadow-none\",\r\n {\r\n variants: {\r\n size: {\r\n xs: \"h-6 gap-1 rounded-[calc(var(--radius)-3px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5\",\r\n sm: \"\",\r\n \"icon-xs\":\r\n \"size-6 rounded-[calc(var(--radius)-3px)] p-0 has-[>svg]:p-0\",\r\n \"icon-sm\": \"size-8 p-0 has-[>svg]:p-0\",\r\n },\r\n },\r\n defaultVariants: {\r\n size: \"xs\",\r\n },\r\n }\r\n)\r\n\r\nfunction InputGroupButton({\r\n className,\r\n type = \"button\",\r\n variant = \"ghost\",\r\n size = \"xs\",\r\n ...props\r\n}: Omit<React.ComponentProps<typeof Button>, \"size\" | \"type\"> &\r\n VariantProps<typeof inputGroupButtonVariants> & {\r\n type?: \"button\" | \"submit\" | \"reset\"\r\n }) {\r\n return (\r\n <Button\r\n type={type}\r\n data-size={size}\r\n variant={variant}\r\n className={cn(inputGroupButtonVariants({ size }), className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction InputGroupText({ className, ...props }: React.ComponentProps<\"span\">) {\r\n return (\r\n <span\r\n className={cn(\r\n \"flex items-center gap-2 text-sm text-muted-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction InputGroupInput({\r\n className,\r\n ...props\r\n}: React.ComponentProps<\"input\">) {\r\n return (\r\n <Input\r\n data-slot=\"input-group-control\"\r\n className={cn(\r\n \"flex-1 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction InputGroupTextarea({\r\n className,\r\n ...props\r\n}: React.ComponentProps<\"textarea\">) {\r\n return (\r\n <Textarea\r\n data-slot=\"input-group-control\"\r\n className={cn(\r\n \"flex-1 resize-none rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport {\r\n InputGroup,\r\n InputGroupAddon,\r\n InputGroupButton,\r\n InputGroupText,\r\n InputGroupInput,\r\n InputGroupTextarea,\r\n}\r\n"
|
|
214
645
|
}
|
|
215
646
|
]
|
|
216
647
|
},
|
|
217
648
|
{
|
|
218
649
|
"name": "input-otp",
|
|
650
|
+
"type": "components:ui",
|
|
651
|
+
"frameworks": [
|
|
652
|
+
"react",
|
|
653
|
+
"nextjs",
|
|
654
|
+
"vue",
|
|
655
|
+
"nuxt",
|
|
656
|
+
"solid",
|
|
657
|
+
"svelte",
|
|
658
|
+
"astro",
|
|
659
|
+
"remix"
|
|
660
|
+
],
|
|
219
661
|
"dependencies": [],
|
|
662
|
+
"registryDependencies": [],
|
|
220
663
|
"files": [
|
|
221
664
|
{
|
|
222
665
|
"name": "input-otp.tsx",
|
|
223
|
-
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport {
|
|
666
|
+
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { OTPInput, OTPInputContext } from \"input-otp\"\r\nimport { MinusIcon } from \"lucide-react\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction InputOTP({\r\n className,\r\n containerClassName,\r\n ...props\r\n}: React.ComponentProps<typeof OTPInput> & {\r\n containerClassName?: string\r\n}) {\r\n return (\r\n <OTPInput\r\n data-slot=\"input-otp\"\r\n containerClassName={cn(\r\n \"cn-input-otp flex items-center has-disabled:opacity-50\",\r\n containerClassName\r\n )}\r\n spellCheck={false}\r\n className={cn(\"disabled:cursor-not-allowed\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction InputOTPGroup({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"input-otp-group\"\r\n className={cn(\r\n \"flex items-center rounded-lg has-aria-invalid:border-destructive has-aria-invalid:ring-3 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction InputOTPSlot({\r\n index,\r\n className,\r\n ...props\r\n}: React.ComponentProps<\"div\"> & {\r\n index: number\r\n}) {\r\n const inputOTPContext = React.useContext(OTPInputContext)\r\n const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {}\r\n\r\n return (\r\n <div\r\n data-slot=\"input-otp-slot\"\r\n data-active={isActive}\r\n className={cn(\r\n \"relative flex size-8 items-center justify-center border-y border-r border-input text-sm transition-all outline-none first:rounded-l-lg first:border-l last:rounded-r-lg aria-invalid:border-destructive data-[active=true]:z-10 data-[active=true]:border-ring data-[active=true]:ring-3 data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:border-destructive data-[active=true]:aria-invalid:ring-destructive/20 dark:bg-input/30 dark:data-[active=true]:aria-invalid:ring-destructive/40\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n {char}\r\n {hasFakeCaret && (\r\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center\">\r\n <div className=\"h-4 w-px animate-caret-blink bg-foreground duration-1000\" />\r\n </div>\r\n )}\r\n </div>\r\n )\r\n}\r\n\r\nfunction InputOTPSeparator({ ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"input-otp-separator\"\r\n className=\"flex items-center [&_svg:not([class*='size-'])]:size-4\"\r\n role=\"separator\"\r\n {...props}\r\n >\r\n <MinusIcon />\r\n </div>\r\n )\r\n}\r\n\r\nexport { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator }\r\n"
|
|
224
667
|
}
|
|
225
668
|
]
|
|
226
669
|
},
|
|
227
670
|
{
|
|
228
671
|
"name": "input",
|
|
672
|
+
"type": "components:ui",
|
|
673
|
+
"frameworks": [
|
|
674
|
+
"react",
|
|
675
|
+
"nextjs",
|
|
676
|
+
"vue",
|
|
677
|
+
"nuxt",
|
|
678
|
+
"solid",
|
|
679
|
+
"svelte",
|
|
680
|
+
"astro",
|
|
681
|
+
"remix"
|
|
682
|
+
],
|
|
229
683
|
"dependencies": [],
|
|
684
|
+
"registryDependencies": [],
|
|
230
685
|
"files": [
|
|
231
686
|
{
|
|
232
687
|
"name": "input.tsx",
|
|
233
|
-
"content": "import * as React from \"react\"\r\nimport {
|
|
688
|
+
"content": "import * as React from \"react\"\r\nimport { Input as InputPrimitive } from \"@base-ui/react/input\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\r\n return (\r\n <InputPrimitive\r\n type={type}\r\n data-slot=\"input\"\r\n className={cn(\r\n \"h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport { Input }\r\n"
|
|
234
689
|
}
|
|
235
690
|
]
|
|
236
691
|
},
|
|
237
692
|
{
|
|
238
693
|
"name": "kbd",
|
|
239
|
-
"
|
|
240
|
-
|
|
694
|
+
"type": "components:ui",
|
|
695
|
+
"frameworks": [
|
|
696
|
+
"react",
|
|
697
|
+
"nextjs",
|
|
698
|
+
"vue",
|
|
699
|
+
"nuxt",
|
|
700
|
+
"solid",
|
|
701
|
+
"svelte",
|
|
702
|
+
"astro",
|
|
703
|
+
"remix"
|
|
241
704
|
],
|
|
705
|
+
"dependencies": [],
|
|
706
|
+
"registryDependencies": [],
|
|
242
707
|
"files": [
|
|
243
708
|
{
|
|
244
709
|
"name": "kbd.tsx",
|
|
245
|
-
"content": "import
|
|
710
|
+
"content": "import { cn } from \"@/lib/utils\"\r\n\r\nfunction Kbd({ className, ...props }: React.ComponentProps<\"kbd\">) {\r\n return (\r\n <kbd\r\n data-slot=\"kbd\"\r\n className={cn(\r\n \"pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-sm bg-muted px-1 font-sans text-xs font-medium text-muted-foreground select-none in-data-[slot=tooltip-content]:bg-background/20 in-data-[slot=tooltip-content]:text-background dark:in-data-[slot=tooltip-content]:bg-background/10 [&_svg:not([class*='size-'])]:size-3\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction KbdGroup({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <kbd\r\n data-slot=\"kbd-group\"\r\n className={cn(\"inline-flex items-center gap-1\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport { Kbd, KbdGroup }\r\n"
|
|
246
711
|
}
|
|
247
712
|
]
|
|
248
713
|
},
|
|
249
714
|
{
|
|
250
715
|
"name": "label",
|
|
716
|
+
"type": "components:ui",
|
|
717
|
+
"frameworks": [
|
|
718
|
+
"react",
|
|
719
|
+
"nextjs",
|
|
720
|
+
"vue",
|
|
721
|
+
"nuxt",
|
|
722
|
+
"solid",
|
|
723
|
+
"svelte",
|
|
724
|
+
"astro",
|
|
725
|
+
"remix"
|
|
726
|
+
],
|
|
251
727
|
"dependencies": [],
|
|
728
|
+
"registryDependencies": [],
|
|
252
729
|
"files": [
|
|
253
730
|
{
|
|
254
731
|
"name": "label.tsx",
|
|
255
|
-
"content": "
|
|
256
|
-
}
|
|
257
|
-
]
|
|
258
|
-
},
|
|
259
|
-
{
|
|
260
|
-
"name": "number-field",
|
|
261
|
-
"dependencies": [
|
|
262
|
-
"@base-ui/react"
|
|
263
|
-
],
|
|
264
|
-
"files": [
|
|
265
|
-
{
|
|
266
|
-
"name": "number-field.tsx",
|
|
267
|
-
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { NumberField as BaseNumberField } from \"@base-ui/react/number-field\"\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nexport interface NumberFieldProps extends React.ComponentPropsWithoutRef<typeof BaseNumberField.Root> {\r\n label?: string\r\n}\r\n\r\nconst NumberField = React.forwardRef<HTMLDivElement, NumberFieldProps>(\r\n ({ className, label, ...props }, ref) => {\r\n return (\r\n <BaseNumberField.Root ref={ref} className={cn(\"flex flex-col gap-1.5 w-full max-w-50\", className)} {...props}>\r\n {label && <label className=\"text-sm font-medium text-foreground\">{label}</label>}\r\n \r\n <div className=\"relative flex items-center border border-border rounded-md bg-background shadow-sm focus-within:ring-2 focus-within:ring-ring\">\r\n {/* Decrement Button */}\r\n <BaseNumberField.Decrement className=\"flex items-center justify-center h-9 w-9 text-muted-foreground transition-colors hover:bg-muted data-disabled:opacity-30 border-r border-border\">\r\n −\r\n </BaseNumberField.Decrement>\r\n\r\n {/* Core Input Element */}\r\n <BaseNumberField.Input className=\"w-full text-center bg-transparent text-sm font-medium text-foreground outline-none placeholder:text-muted-foreground py-1.5\" />\r\n\r\n {/* Increment Button */}\r\n <BaseNumberField.Increment className=\"flex items-center justify-center h-9 w-9 text-muted-foreground transition-colors hover:bg-muted data-disabled:opacity-30 border-l border-border\">\r\n +\r\n </BaseNumberField.Increment>\r\n </div>\r\n </BaseNumberField.Root>\r\n )\r\n }\r\n)\r\n\r\nNumberField.displayName = \"NumberField\"\r\n\r\nexport { NumberField }"
|
|
732
|
+
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction Label({ className, ...props }: React.ComponentProps<\"label\">) {\r\n return (\r\n <label\r\n data-slot=\"label\"\r\n className={cn(\r\n \"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport { Label }\r\n"
|
|
268
733
|
}
|
|
269
734
|
]
|
|
270
735
|
},
|
|
271
736
|
{
|
|
272
737
|
"name": "pagination",
|
|
738
|
+
"type": "components:ui",
|
|
739
|
+
"frameworks": [
|
|
740
|
+
"react",
|
|
741
|
+
"nextjs",
|
|
742
|
+
"vue",
|
|
743
|
+
"nuxt",
|
|
744
|
+
"solid",
|
|
745
|
+
"svelte",
|
|
746
|
+
"astro",
|
|
747
|
+
"remix"
|
|
748
|
+
],
|
|
273
749
|
"dependencies": [],
|
|
750
|
+
"registryDependencies": [],
|
|
274
751
|
"files": [
|
|
275
752
|
{
|
|
276
753
|
"name": "pagination.tsx",
|
|
277
|
-
"content": "import * as React from \"react\"\r\nimport { cn } from \"@/lib/utils\"\r\n\r\
|
|
754
|
+
"content": "import * as React from \"react\"\r\nimport {\r\n ChevronLeftIcon,\r\n ChevronRightIcon,\r\n MoreHorizontalIcon,\r\n} from \"lucide-react\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\nimport { Button } from \"@/button\"\r\n\r\nfunction Pagination({ className, ...props }: React.ComponentProps<\"nav\">) {\r\n return (\r\n <nav\r\n role=\"navigation\"\r\n aria-label=\"pagination\"\r\n data-slot=\"pagination\"\r\n className={cn(\"mx-auto flex w-full justify-center\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction PaginationContent({\r\n className,\r\n ...props\r\n}: React.ComponentProps<\"ul\">) {\r\n return (\r\n <ul\r\n data-slot=\"pagination-content\"\r\n className={cn(\"flex items-center gap-0.5\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction PaginationItem({ ...props }: React.ComponentProps<\"li\">) {\r\n return <li data-slot=\"pagination-item\" {...props} />\r\n}\r\n\r\ntype PaginationLinkProps = {\r\n isActive?: boolean\r\n} & Pick<React.ComponentProps<typeof Button>, \"size\"> &\r\n React.ComponentProps<\"a\">\r\n\r\nfunction PaginationLink({\r\n className,\r\n isActive,\r\n size = \"icon\",\r\n ...props\r\n}: PaginationLinkProps) {\r\n return (\r\n <Button\r\n variant={isActive ? \"outline\" : \"ghost\"}\r\n size={size}\r\n className={cn(className)}\r\n nativeButton={false}\r\n render={\r\n <a\r\n aria-current={isActive ? \"page\" : undefined}\r\n data-slot=\"pagination-link\"\r\n data-active={isActive}\r\n {...props}\r\n />\r\n }\r\n />\r\n )\r\n}\r\n\r\nfunction PaginationPrevious({\r\n className,\r\n text = \"Previous\",\r\n ...props\r\n}: React.ComponentProps<typeof PaginationLink> & { text?: string }) {\r\n return (\r\n <PaginationLink\r\n aria-label=\"Go to previous page\"\r\n size=\"default\"\r\n className={cn(\"pl-1.5!\", className)}\r\n {...props}\r\n >\r\n <ChevronLeftIcon data-icon=\"inline-start\" className=\"cn-rtl-flip\" />\r\n <span className=\"hidden sm:block\">{text}</span>\r\n </PaginationLink>\r\n )\r\n}\r\n\r\nfunction PaginationNext({\r\n className,\r\n text = \"Next\",\r\n ...props\r\n}: React.ComponentProps<typeof PaginationLink> & { text?: string }) {\r\n return (\r\n <PaginationLink\r\n aria-label=\"Go to next page\"\r\n size=\"default\"\r\n className={cn(\"pr-1.5!\", className)}\r\n {...props}\r\n >\r\n <span className=\"hidden sm:block\">{text}</span>\r\n <ChevronRightIcon data-icon=\"inline-end\" className=\"cn-rtl-flip\" />\r\n </PaginationLink>\r\n )\r\n}\r\n\r\nfunction PaginationEllipsis({\r\n className,\r\n ...props\r\n}: React.ComponentProps<\"span\">) {\r\n return (\r\n <span\r\n aria-hidden\r\n data-slot=\"pagination-ellipsis\"\r\n className={cn(\r\n \"flex size-8 items-center justify-center [&_svg:not([class*='size-'])]:size-4\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n <MoreHorizontalIcon />\r\n <span className=\"sr-only\">More pages</span>\r\n </span>\r\n )\r\n}\r\n\r\nexport {\r\n Pagination,\r\n PaginationContent,\r\n PaginationEllipsis,\r\n PaginationItem,\r\n PaginationLink,\r\n PaginationNext,\r\n PaginationPrevious,\r\n}\r\n"
|
|
278
755
|
}
|
|
279
756
|
]
|
|
280
757
|
},
|
|
281
758
|
{
|
|
282
759
|
"name": "popover",
|
|
760
|
+
"type": "components:ui",
|
|
761
|
+
"frameworks": [
|
|
762
|
+
"react",
|
|
763
|
+
"nextjs",
|
|
764
|
+
"vue",
|
|
765
|
+
"nuxt",
|
|
766
|
+
"solid",
|
|
767
|
+
"svelte",
|
|
768
|
+
"astro",
|
|
769
|
+
"remix"
|
|
770
|
+
],
|
|
283
771
|
"dependencies": [
|
|
284
772
|
"@base-ui/react"
|
|
285
773
|
],
|
|
774
|
+
"registryDependencies": [],
|
|
286
775
|
"files": [
|
|
287
776
|
{
|
|
288
777
|
"name": "popover.tsx",
|
|
289
|
-
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { Popover as
|
|
778
|
+
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { Popover as PopoverPrimitive } from \"@base-ui/react/popover\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction Popover({ ...props }: PopoverPrimitive.Root.Props) {\r\n return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />\r\n}\r\n\r\nfunction PopoverTrigger({ ...props }: PopoverPrimitive.Trigger.Props) {\r\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />\r\n}\r\n\r\nfunction PopoverContent({\r\n className,\r\n align = \"center\",\r\n alignOffset = 0,\r\n side = \"bottom\",\r\n sideOffset = 4,\r\n ...props\r\n}: PopoverPrimitive.Popup.Props &\r\n Pick<\r\n PopoverPrimitive.Positioner.Props,\r\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\r\n >) {\r\n return (\r\n <PopoverPrimitive.Portal>\r\n <PopoverPrimitive.Positioner\r\n align={align}\r\n alignOffset={alignOffset}\r\n side={side}\r\n sideOffset={sideOffset}\r\n className=\"isolate z-50\"\r\n >\r\n <PopoverPrimitive.Popup\r\n data-slot=\"popover-content\"\r\n className={cn(\r\n \"z-50 flex w-72 origin-(--transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n </PopoverPrimitive.Positioner>\r\n </PopoverPrimitive.Portal>\r\n )\r\n}\r\n\r\nfunction PopoverHeader({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"popover-header\"\r\n className={cn(\"flex flex-col gap-0.5 text-sm\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction PopoverTitle({ className, ...props }: PopoverPrimitive.Title.Props) {\r\n return (\r\n <PopoverPrimitive.Title\r\n data-slot=\"popover-title\"\r\n className={cn(\"font-medium\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction PopoverDescription({\r\n className,\r\n ...props\r\n}: PopoverPrimitive.Description.Props) {\r\n return (\r\n <PopoverPrimitive.Description\r\n data-slot=\"popover-description\"\r\n className={cn(\"text-muted-foreground\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport {\r\n Popover,\r\n PopoverContent,\r\n PopoverDescription,\r\n PopoverHeader,\r\n PopoverTitle,\r\n PopoverTrigger,\r\n}\r\n"
|
|
290
779
|
}
|
|
291
780
|
]
|
|
292
781
|
},
|
|
293
782
|
{
|
|
294
783
|
"name": "progress",
|
|
784
|
+
"type": "components:ui",
|
|
785
|
+
"frameworks": [
|
|
786
|
+
"react",
|
|
787
|
+
"nextjs",
|
|
788
|
+
"vue",
|
|
789
|
+
"nuxt",
|
|
790
|
+
"solid",
|
|
791
|
+
"svelte",
|
|
792
|
+
"astro",
|
|
793
|
+
"remix"
|
|
794
|
+
],
|
|
295
795
|
"dependencies": [
|
|
296
796
|
"@base-ui/react"
|
|
297
797
|
],
|
|
798
|
+
"registryDependencies": [],
|
|
298
799
|
"files": [
|
|
299
800
|
{
|
|
300
801
|
"name": "progress.tsx",
|
|
301
|
-
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport {
|
|
802
|
+
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { Popover as PopoverPrimitive } from \"@base-ui/react/popover\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction Popover({ ...props }: PopoverPrimitive.Root.Props) {\r\n return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />\r\n}\r\n\r\nfunction PopoverTrigger({ ...props }: PopoverPrimitive.Trigger.Props) {\r\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />\r\n}\r\n\r\nfunction PopoverContent({\r\n className,\r\n align = \"center\",\r\n alignOffset = 0,\r\n side = \"bottom\",\r\n sideOffset = 4,\r\n ...props\r\n}: PopoverPrimitive.Popup.Props &\r\n Pick<\r\n PopoverPrimitive.Positioner.Props,\r\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\r\n >) {\r\n return (\r\n <PopoverPrimitive.Portal>\r\n <PopoverPrimitive.Positioner\r\n align={align}\r\n alignOffset={alignOffset}\r\n side={side}\r\n sideOffset={sideOffset}\r\n className=\"isolate z-50\"\r\n >\r\n <PopoverPrimitive.Popup\r\n data-slot=\"popover-content\"\r\n className={cn(\r\n \"z-50 flex w-72 origin-(--transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n </PopoverPrimitive.Positioner>\r\n </PopoverPrimitive.Portal>\r\n )\r\n}\r\n\r\nfunction PopoverHeader({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"popover-header\"\r\n className={cn(\"flex flex-col gap-0.5 text-sm\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction PopoverTitle({ className, ...props }: PopoverPrimitive.Title.Props) {\r\n return (\r\n <PopoverPrimitive.Title\r\n data-slot=\"popover-title\"\r\n className={cn(\"font-medium\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction PopoverDescription({\r\n className,\r\n ...props\r\n}: PopoverPrimitive.Description.Props) {\r\n return (\r\n <PopoverPrimitive.Description\r\n data-slot=\"popover-description\"\r\n className={cn(\"text-muted-foreground\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport {\r\n Popover,\r\n PopoverContent,\r\n PopoverDescription,\r\n PopoverHeader,\r\n PopoverTitle,\r\n PopoverTrigger,\r\n}\r\n"
|
|
302
803
|
}
|
|
303
804
|
]
|
|
304
805
|
},
|
|
305
806
|
{
|
|
306
807
|
"name": "radio-group",
|
|
808
|
+
"type": "components:ui",
|
|
809
|
+
"frameworks": [
|
|
810
|
+
"react",
|
|
811
|
+
"nextjs",
|
|
812
|
+
"vue",
|
|
813
|
+
"nuxt",
|
|
814
|
+
"solid",
|
|
815
|
+
"svelte",
|
|
816
|
+
"astro",
|
|
817
|
+
"remix"
|
|
818
|
+
],
|
|
307
819
|
"dependencies": [
|
|
308
820
|
"@base-ui/react"
|
|
309
821
|
],
|
|
822
|
+
"registryDependencies": [],
|
|
310
823
|
"files": [
|
|
311
824
|
{
|
|
312
825
|
"name": "radio-group.tsx",
|
|
313
|
-
"content": "\"use client\"\
|
|
826
|
+
"content": "\"use client\"\n\nimport { Radio as RadioPrimitive } from \"@base-ui/react/radio\"\nimport { RadioGroup as RadioGroupPrimitive } from \"@base-ui/react/radio-group\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction RadioGroup({ className, ...props }: RadioGroupPrimitive.Props) {\n return (\n <RadioGroupPrimitive\n data-slot=\"radio-group\"\n className={cn(\"grid w-full gap-2\", className)}\n {...props}\n />\n )\n}\n\nfunction RadioGroupItem({ className, ...props }: RadioPrimitive.Root.Props) {\n return (\n <RadioPrimitive.Root\n data-slot=\"radio-group-item\"\n className={cn(\n \"group/radio-group-item peer relative flex aspect-square size-4 shrink-0 rounded-full border border-input outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary\",\n className\n )}\n {...props}\n >\n <RadioPrimitive.Indicator\n data-slot=\"radio-group-indicator\"\n className=\"flex size-4 items-center justify-center\"\n >\n <span className=\"absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-primary-foreground\" />\n </RadioPrimitive.Indicator>\n </RadioPrimitive.Root>\n )\n}\n\nexport { RadioGroup, RadioGroupItem }\n"
|
|
314
827
|
}
|
|
315
828
|
]
|
|
316
829
|
},
|
|
317
830
|
{
|
|
318
831
|
"name": "scroll-area",
|
|
832
|
+
"type": "components:ui",
|
|
833
|
+
"frameworks": [
|
|
834
|
+
"react",
|
|
835
|
+
"nextjs",
|
|
836
|
+
"vue",
|
|
837
|
+
"nuxt",
|
|
838
|
+
"solid",
|
|
839
|
+
"svelte",
|
|
840
|
+
"astro",
|
|
841
|
+
"remix"
|
|
842
|
+
],
|
|
319
843
|
"dependencies": [
|
|
320
844
|
"@base-ui/react"
|
|
321
845
|
],
|
|
846
|
+
"registryDependencies": [],
|
|
322
847
|
"files": [
|
|
323
848
|
{
|
|
324
849
|
"name": "scroll-area.tsx",
|
|
325
|
-
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { ScrollArea as
|
|
850
|
+
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { ScrollArea as ScrollAreaPrimitive } from \"@base-ui/react/scroll-area\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction ScrollArea({\r\n className,\r\n children,\r\n ...props\r\n}: ScrollAreaPrimitive.Root.Props) {\r\n return (\r\n <ScrollAreaPrimitive.Root\r\n data-slot=\"scroll-area\"\r\n className={cn(\"relative\", className)}\r\n {...props}\r\n >\r\n <ScrollAreaPrimitive.Viewport\r\n data-slot=\"scroll-area-viewport\"\r\n className=\"size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1\"\r\n >\r\n {children}\r\n </ScrollAreaPrimitive.Viewport>\r\n <ScrollBar />\r\n <ScrollAreaPrimitive.Corner />\r\n </ScrollAreaPrimitive.Root>\r\n )\r\n}\r\n\r\nfunction ScrollBar({\r\n className,\r\n orientation = \"vertical\",\r\n ...props\r\n}: ScrollAreaPrimitive.Scrollbar.Props) {\r\n return (\r\n <ScrollAreaPrimitive.Scrollbar\r\n data-slot=\"scroll-area-scrollbar\"\r\n data-orientation={orientation}\r\n orientation={orientation}\r\n className={cn(\r\n \"flex touch-none p-px transition-colors select-none data-horizontal:h-2.5 data-horizontal:flex-col data-horizontal:border-t data-horizontal:border-t-transparent data-vertical:h-full data-vertical:w-2.5 data-vertical:border-l data-vertical:border-l-transparent\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n <ScrollAreaPrimitive.Thumb\r\n data-slot=\"scroll-area-thumb\"\r\n className=\"relative flex-1 rounded-full bg-border\"\r\n />\r\n </ScrollAreaPrimitive.Scrollbar>\r\n )\r\n}\r\n\r\nexport { ScrollArea, ScrollBar }\r\n"
|
|
326
851
|
}
|
|
327
852
|
]
|
|
328
853
|
},
|
|
329
854
|
{
|
|
330
855
|
"name": "select",
|
|
856
|
+
"type": "components:ui",
|
|
857
|
+
"frameworks": [
|
|
858
|
+
"react",
|
|
859
|
+
"nextjs",
|
|
860
|
+
"vue",
|
|
861
|
+
"nuxt",
|
|
862
|
+
"solid",
|
|
863
|
+
"svelte",
|
|
864
|
+
"astro",
|
|
865
|
+
"remix"
|
|
866
|
+
],
|
|
331
867
|
"dependencies": [
|
|
332
868
|
"@base-ui/react"
|
|
333
869
|
],
|
|
870
|
+
"registryDependencies": [],
|
|
334
871
|
"files": [
|
|
335
872
|
{
|
|
336
873
|
"name": "select.tsx",
|
|
337
|
-
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { Select as
|
|
874
|
+
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { Select as SelectPrimitive } from \"@base-ui/react/select\"\r\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nconst Select = SelectPrimitive.Root\r\n\r\nfunction SelectGroup({ className, ...props }: SelectPrimitive.Group.Props) {\r\n return (\r\n <SelectPrimitive.Group\r\n data-slot=\"select-group\"\r\n className={cn(\"scroll-my-1 p-1\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {\r\n return (\r\n <SelectPrimitive.Value\r\n data-slot=\"select-value\"\r\n className={cn(\"flex flex-1 text-left\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction SelectTrigger({\r\n className,\r\n size = \"default\",\r\n children,\r\n ...props\r\n}: SelectPrimitive.Trigger.Props & {\r\n size?: \"sm\" | \"default\"\r\n}) {\r\n return (\r\n <SelectPrimitive.Trigger\r\n data-slot=\"select-trigger\"\r\n data-size={size}\r\n className={cn(\r\n \"flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n {children}\r\n <SelectPrimitive.Icon\r\n render={\r\n <ChevronDownIcon className=\"pointer-events-none size-4 text-muted-foreground\" />\r\n }\r\n />\r\n </SelectPrimitive.Trigger>\r\n )\r\n}\r\n\r\nfunction SelectContent({\r\n className,\r\n children,\r\n side = \"bottom\",\r\n sideOffset = 4,\r\n align = \"center\",\r\n alignOffset = 0,\r\n alignItemWithTrigger = true,\r\n ...props\r\n}: SelectPrimitive.Popup.Props &\r\n Pick<\r\n SelectPrimitive.Positioner.Props,\r\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\" | \"alignItemWithTrigger\"\r\n >) {\r\n return (\r\n <SelectPrimitive.Portal>\r\n <SelectPrimitive.Positioner\r\n side={side}\r\n sideOffset={sideOffset}\r\n align={align}\r\n alignOffset={alignOffset}\r\n alignItemWithTrigger={alignItemWithTrigger}\r\n className=\"isolate z-50\"\r\n >\r\n <SelectPrimitive.Popup\r\n data-slot=\"select-content\"\r\n data-align-trigger={alignItemWithTrigger}\r\n className={cn(\"relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\", className )}\r\n {...props}\r\n >\r\n <SelectScrollUpButton />\r\n <SelectPrimitive.List>{children}</SelectPrimitive.List>\r\n <SelectScrollDownButton />\r\n </SelectPrimitive.Popup>\r\n </SelectPrimitive.Positioner>\r\n </SelectPrimitive.Portal>\r\n )\r\n}\r\n\r\nfunction SelectLabel({\r\n className,\r\n ...props\r\n}: SelectPrimitive.GroupLabel.Props) {\r\n return (\r\n <SelectPrimitive.GroupLabel\r\n data-slot=\"select-label\"\r\n className={cn(\"px-1.5 py-1 text-xs text-muted-foreground\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction SelectItem({\r\n className,\r\n children,\r\n ...props\r\n}: SelectPrimitive.Item.Props) {\r\n return (\r\n <SelectPrimitive.Item\r\n data-slot=\"select-item\"\r\n className={cn(\r\n \"relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n <SelectPrimitive.ItemText className=\"flex flex-1 shrink-0 gap-2 whitespace-nowrap\">\r\n {children}\r\n </SelectPrimitive.ItemText>\r\n <SelectPrimitive.ItemIndicator render={<span className=\"pointer-events-none absolute right-2 flex size-4 items-center justify-center\"><CheckIcon className=\"pointer-events-none\" /></span>} />\r\n </SelectPrimitive.Item>\r\n )\r\n}\r\n\r\nfunction SelectSeparator({\r\n className,\r\n ...props\r\n}: SelectPrimitive.Separator.Props) {\r\n return (\r\n <SelectPrimitive.Separator\r\n data-slot=\"select-separator\"\r\n className={cn(\"pointer-events-none -mx-1 my-1 h-px bg-border\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction SelectScrollUpButton({\r\n className,\r\n ...props\r\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpArrow>) {\r\n return (\r\n <SelectPrimitive.ScrollUpArrow\r\n data-slot=\"select-scroll-up-button\"\r\n className={cn(\r\n \"top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n <ChevronUpIcon />\r\n </SelectPrimitive.ScrollUpArrow>\r\n )\r\n}\r\n\r\nfunction SelectScrollDownButton({\r\n className,\r\n ...props\r\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownArrow>) {\r\n return (\r\n <SelectPrimitive.ScrollDownArrow\r\n data-slot=\"select-scroll-down-button\"\r\n className={cn(\r\n \"bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n <ChevronDownIcon />\r\n </SelectPrimitive.ScrollDownArrow>\r\n )\r\n}\r\n\r\nexport {\r\n Select,\r\n SelectContent,\r\n SelectGroup,\r\n SelectItem,\r\n SelectLabel,\r\n SelectScrollDownButton,\r\n SelectScrollUpButton,\r\n SelectSeparator,\r\n SelectTrigger,\r\n SelectValue,\r\n}\r\n"
|
|
338
875
|
}
|
|
339
876
|
]
|
|
340
877
|
},
|
|
341
878
|
{
|
|
342
879
|
"name": "separator",
|
|
880
|
+
"type": "components:ui",
|
|
881
|
+
"frameworks": [
|
|
882
|
+
"react",
|
|
883
|
+
"nextjs",
|
|
884
|
+
"vue",
|
|
885
|
+
"nuxt",
|
|
886
|
+
"solid",
|
|
887
|
+
"svelte",
|
|
888
|
+
"astro",
|
|
889
|
+
"remix"
|
|
890
|
+
],
|
|
891
|
+
"dependencies": [],
|
|
892
|
+
"registryDependencies": [],
|
|
893
|
+
"files": [
|
|
894
|
+
{
|
|
895
|
+
"name": "separator.tsx",
|
|
896
|
+
"content": "\"use client\"\r\n\r\nimport { Separator as SeparatorPrimitive } from \"@base-ui/react/separator\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction Separator({\r\n className,\r\n orientation = \"horizontal\",\r\n ...props\r\n}: SeparatorPrimitive.Props) {\r\n return (\r\n <SeparatorPrimitive\r\n data-slot=\"separator\"\r\n orientation={orientation}\r\n className={cn(\r\n \"shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport { Separator }\r\n"
|
|
897
|
+
}
|
|
898
|
+
]
|
|
899
|
+
},
|
|
900
|
+
{
|
|
901
|
+
"name": "sheet",
|
|
902
|
+
"type": "components:ui",
|
|
903
|
+
"frameworks": [
|
|
904
|
+
"react",
|
|
905
|
+
"nextjs",
|
|
906
|
+
"remix"
|
|
907
|
+
],
|
|
343
908
|
"dependencies": [
|
|
344
909
|
"@base-ui/react"
|
|
345
910
|
],
|
|
911
|
+
"registryDependencies": [],
|
|
346
912
|
"files": [
|
|
347
913
|
{
|
|
348
|
-
"name": "
|
|
349
|
-
"content": "
|
|
914
|
+
"name": "sheet.tsx",
|
|
915
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Dialog as SheetPrimitive } from \"@base-ui/react/dialog\"\nimport { XIcon } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Sheet = SheetPrimitive.Root\nconst SheetTrigger = SheetPrimitive.Trigger\nconst SheetClose = SheetPrimitive.Close\nconst SheetPortal = SheetPrimitive.Portal\n\nfunction SheetOverlay({\n className,\n ...props\n}: SheetPrimitive.Backdrop.Props) {\n return (\n <SheetPrimitive.Backdrop\n data-slot=\"sheet-overlay\"\n className={cn(\n \"fixed inset-0 z-50 bg-black/10 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nconst SHEET_SIDES = [\"top\", \"right\", \"bottom\", \"left\"] as const\ntype SheetSide = (typeof SHEET_SIDES)[number]\n\nfunction SheetContent({\n className,\n children,\n side = \"right\",\n ...props\n}: SheetPrimitive.Popup.Props & {\n side?: SheetSide\n}) {\n return (\n <SheetPortal>\n <SheetOverlay />\n <SheetPrimitive.Popup\n data-slot=\"sheet-content\"\n className={cn(\n \"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-open:animate-in data-closed:animate-out\",\n side === \"right\" &&\n \"inset-y-0 right-0 h-full w-3/4 border-l data-open:slide-in-from-right-full data-closed:slide-out-to-right-full sm:max-w-sm\",\n side === \"left\" &&\n \"inset-y-0 left-0 h-full w-3/4 border-r data-open:slide-in-from-left-full data-closed:slide-out-to-left-full sm:max-w-sm\",\n side === \"top\" &&\n \"inset-x-0 top-0 border-b data-open:slide-in-from-top-full data-closed:slide-out-to-top-full\",\n side === \"bottom\" &&\n \"inset-x-0 bottom-0 border-t data-open:slide-in-from-bottom-full data-closed:slide-out-to-bottom-full\",\n className\n )}\n {...props}\n >\n {children}\n <SheetPrimitive.Close\n data-slot=\"sheet-close\"\n className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary\"\n >\n <XIcon className=\"h-4 w-4\" />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n </SheetPrimitive.Popup>\n </SheetPortal>\n )\n}\n\nfunction SheetHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn(\n \"flex flex-col gap-2 text-center sm:text-left\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SheetFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\n \"flex flex-col-reverse sm:flex-row sm:justify-end sm:gap-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SheetTitle({\n className,\n ...props\n}: SheetPrimitive.Title.Props) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn(\n \"cn-font-heading text-lg font-semibold text-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SheetDescription({\n className,\n ...props\n}: SheetPrimitive.Description.Props) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Sheet,\n SheetPortal,\n SheetOverlay,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n}\n"
|
|
350
916
|
}
|
|
351
917
|
]
|
|
352
918
|
},
|
|
353
919
|
{
|
|
354
920
|
"name": "sidebar",
|
|
921
|
+
"type": "components:ui",
|
|
922
|
+
"frameworks": [
|
|
923
|
+
"react",
|
|
924
|
+
"nextjs",
|
|
925
|
+
"vue",
|
|
926
|
+
"nuxt",
|
|
927
|
+
"solid",
|
|
928
|
+
"svelte",
|
|
929
|
+
"astro",
|
|
930
|
+
"remix"
|
|
931
|
+
],
|
|
355
932
|
"dependencies": [],
|
|
933
|
+
"registryDependencies": [],
|
|
356
934
|
"files": [
|
|
357
935
|
{
|
|
358
936
|
"name": "sidebar.tsx",
|
|
359
|
-
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nconst SidebarContext = React.createContext<{\r\n isCollapsed: boolean\r\n setIsCollapsed: React.Dispatch<React.SetStateAction<boolean>>\r\n} | null>(null)\r\n\r\nfunction useSidebar() {\r\n const context = React.useContext(SidebarContext)\r\n if (!context) throw new Error(\"useSidebar must be used within a SidebarProvider\")\r\n return context\r\n}\r\n\r\nconst SidebarProvider = ({\r\n children,\r\n className,\r\n ...props\r\n}: React.HTMLAttributes<HTMLDivElement>) => {\r\n const [isCollapsed, setIsCollapsed] = React.useState(false)\r\n\r\n return (\r\n <SidebarContext.Provider value={{ isCollapsed, setIsCollapsed }}>\r\n <div\r\n className={cn(\r\n \"flex min-h-screen w-full bg-muted/50 text-foreground\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n {children}\r\n </div>\r\n </SidebarContext.Provider>\r\n )\r\n}\r\nSidebarProvider.displayName = \"SidebarProvider\"\r\n\r\nconst Sidebar = React.forwardRef<\r\n HTMLDivElement,\r\n React.HTMLAttributes<HTMLDivElement>\r\n>(({ className, children, ...props }, ref) => {\r\n const { isCollapsed } = useSidebar()\r\n\r\n return (\r\n <aside\r\n ref={ref}\r\n className={cn(\r\n \"h-screen border-r border-border bg-background transition-all duration-300 ease-in-out flex flex-col shrink-0 sticky top-0 z-20\",\r\n isCollapsed ? \"w-16\" : \"w-64\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n {children}\r\n </aside>\r\n )\r\n})\r\nSidebar.displayName = \"Sidebar\"\r\n\r\nconst SidebarTrigger = React.forwardRef<\r\n HTMLButtonElement,\r\n React.ButtonHTMLAttributes<HTMLButtonElement>\r\n>(({ className, ...props }, ref) => {\r\n const { isCollapsed, setIsCollapsed } = useSidebar()\r\n\r\n return (\r\n <button\r\n ref={ref}\r\n onClick={() => setIsCollapsed(!isCollapsed)}\r\n className={cn(\r\n \"inline-flex h-8 w-8 items-center justify-center rounded-md border border-border bg-background text-muted-foreground hover:text-foreground shadow-2xs cursor-pointer focus-visible:outline-hidden\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"16\"\r\n height=\"16\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n className={cn(\"transition-transform duration-200\", isCollapsed && \"rotate-180\")}\r\n >\r\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\r\n <path d=\"M9 3v18\" />\r\n </svg>\r\n </button>\r\n )\r\n})\r\nSidebarTrigger.displayName = \"SidebarTrigger\"\r\n\r\nconst SidebarContent = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\r\n <div className={cn(\"flex-1 overflow-y-auto p-3 space-y-1.5\", className)} {...props} />\r\n)\r\nSidebarContent.displayName = \"SidebarContent\"\r\n\r\nconst SidebarGroup = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\r\n <div className={cn(\"flex flex-col space-y-1\", className)} {...props} />\r\n)\r\nSidebarGroup.displayName = \"SidebarGroup\"\r\n\r\nconst SidebarGroupLabel = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => {\r\n const { isCollapsed } = useSidebar()\r\n if (isCollapsed) return null\r\n return (\r\n <div\r\n className={cn(\r\n \"px-2 py-1.5 text-xs font-semibold uppercase tracking-wider text-muted-foreground select-none\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\nSidebarGroupLabel.displayName = \"SidebarGroupLabel\"\r\n\r\nconst SidebarItem = React.forwardRef<\r\n HTMLButtonElement,\r\n React.ButtonHTMLAttributes<HTMLButtonElement> & { isActive?: boolean }\r\n>(({ className, isActive, children, ...props }, ref) => {\r\n const { isCollapsed } = useSidebar()\r\n\r\n return (\r\n <button\r\n ref={ref}\r\n className={cn(\r\n \"flex w-full items-center rounded-lg px-3 py-2 text-sm font-medium transition-all cursor-pointer group text-left select-none relative\",\r\n isActive\r\n ? \"bg-primary text-primary-foreground shadow-xs\"\r\n : \"text-muted-foreground hover:bg-muted hover:text-foreground\",\r\n isCollapsed && \"justify-center px-0 h-10\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n {children}\r\n </button>\r\n )\r\n})\r\nSidebarItem.displayName = \"SidebarItem\"\r\n\r\nexport {\r\n SidebarProvider,\r\n Sidebar,\r\n SidebarTrigger,\r\n SidebarContent,\r\n SidebarGroup,\r\n SidebarGroupLabel,\r\n SidebarItem,\r\n useSidebar,\r\n}"
|
|
937
|
+
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { mergeProps } from \"@base-ui/react/merge-props\"\r\nimport { useRender } from \"@base-ui/react/use-render\"\r\nimport { cva, type VariantProps } from \"class-variance-authority\"\r\nimport { PanelLeftIcon } from \"lucide-react\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\nimport { useIsMobile } from \"@/hooks/use-mobile\"\r\nimport { Button } from \"@/components/ui/button\"\r\nimport { Input } from \"@/components/ui/input\"\r\nimport { Separator } from \"@/components/ui/separator\"\r\nimport {\r\n Sheet,\r\n SheetContent,\r\n SheetDescription,\r\n SheetHeader,\r\n SheetTitle,\r\n} from \"@/components/ui/sheet\"\r\nimport { Skeleton } from \"@/components/ui/skeleton\"\r\nimport {\r\n Tooltip,\r\n TooltipContent,\r\n TooltipTrigger,\r\n} from \"@/components/ui/tooltip\"\r\n\r\nconst SIDEBAR_COOKIE_NAME = \"sidebar_state\"\r\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7\r\nconst SIDEBAR_WIDTH = \"16rem\"\r\nconst SIDEBAR_WIDTH_MOBILE = \"18rem\"\r\nconst SIDEBAR_WIDTH_ICON = \"3rem\"\r\nconst SIDEBAR_KEYBOARD_SHORTCUT = \"b\"\r\n\r\ntype SidebarContextProps = {\r\n state: \"expanded\" | \"collapsed\"\r\n open: boolean\r\n setOpen: (open: boolean) => void\r\n openMobile: boolean\r\n setOpenMobile: (open: boolean) => void\r\n isMobile: boolean\r\n toggleSidebar: () => void\r\n}\r\n\r\nconst SidebarContext = React.createContext<SidebarContextProps | null>(null)\r\n\r\nfunction useSidebar() {\r\n const context = React.useContext(SidebarContext)\r\n if (!context) {\r\n throw new Error(\"useSidebar must be used within a SidebarProvider.\")\r\n }\r\n\r\n return context\r\n}\r\n\r\nfunction SidebarProvider({\r\n defaultOpen = true,\r\n open: openProp,\r\n onOpenChange: setOpenProp,\r\n className,\r\n style,\r\n children,\r\n ...props\r\n}: React.ComponentProps<\"div\"> & {\r\n defaultOpen?: boolean\r\n open?: boolean\r\n onOpenChange?: (open: boolean) => void\r\n}) {\r\n const isMobile = useIsMobile()\r\n const [openMobile, setOpenMobile] = React.useState(false)\r\n\r\n // This is the internal state of the sidebar.\r\n // We use openProp and setOpenProp for control from outside the component.\r\n const [_open, _setOpen] = React.useState(defaultOpen)\r\n const open = openProp ?? _open\r\n const setOpen = React.useCallback(\r\n (value: boolean | ((value: boolean) => boolean)) => {\r\n const openState = typeof value === \"function\" ? value(open) : value\r\n if (setOpenProp) {\r\n setOpenProp(openState)\r\n } else {\r\n _setOpen(openState)\r\n }\r\n\r\n // This sets the cookie to keep the sidebar state.\r\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`\r\n },\r\n [setOpenProp, open]\r\n )\r\n\r\n // Helper to toggle the sidebar.\r\n const toggleSidebar = React.useCallback(() => {\r\n return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)\r\n }, [isMobile, setOpen, setOpenMobile])\r\n\r\n // Adds a keyboard shortcut to toggle the sidebar.\r\n React.useEffect(() => {\r\n const handleKeyDown = (event: KeyboardEvent) => {\r\n if (\r\n event.key === SIDEBAR_KEYBOARD_SHORTCUT &&\r\n (event.metaKey || event.ctrlKey)\r\n ) {\r\n event.preventDefault()\r\n toggleSidebar()\r\n }\r\n }\r\n\r\n window.addEventListener(\"keydown\", handleKeyDown)\r\n return () => window.removeEventListener(\"keydown\", handleKeyDown)\r\n }, [toggleSidebar])\r\n\r\n // We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\r\n // This makes it easier to style the sidebar with Tailwind classes.\r\n const state = open ? \"expanded\" : \"collapsed\"\r\n\r\n const contextValue = React.useMemo<SidebarContextProps>(\r\n () => ({\r\n state,\r\n open,\r\n setOpen,\r\n isMobile,\r\n openMobile,\r\n setOpenMobile,\r\n toggleSidebar,\r\n }),\r\n [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]\r\n )\r\n\r\n return (\r\n <SidebarContext.Provider value={contextValue}>\r\n <div\r\n data-slot=\"sidebar-wrapper\"\r\n style={\r\n {\r\n \"--sidebar-width\": SIDEBAR_WIDTH,\r\n \"--sidebar-width-icon\": SIDEBAR_WIDTH_ICON,\r\n ...style,\r\n } as React.CSSProperties\r\n }\r\n className={cn(\r\n \"group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n {children}\r\n </div>\r\n </SidebarContext.Provider>\r\n )\r\n}\r\n\r\nfunction Sidebar({\r\n side = \"left\",\r\n variant = \"sidebar\",\r\n collapsible = \"offcanvas\",\r\n className,\r\n children,\r\n dir,\r\n ...props\r\n}: React.ComponentProps<\"div\"> & {\r\n side?: \"left\" | \"right\"\r\n variant?: \"sidebar\" | \"floating\" | \"inset\"\r\n collapsible?: \"offcanvas\" | \"icon\" | \"none\"\r\n}) {\r\n const { isMobile, state, openMobile, setOpenMobile } = useSidebar()\r\n\r\n if (collapsible === \"none\") {\r\n return (\r\n <div\r\n data-slot=\"sidebar\"\r\n className={cn(\r\n \"flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n {children}\r\n </div>\r\n )\r\n }\r\n\r\n if (isMobile) {\r\n return (\r\n <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>\r\n <SheetContent\r\n dir={dir}\r\n data-sidebar=\"sidebar\"\r\n data-slot=\"sidebar\"\r\n data-mobile=\"true\"\r\n className=\"w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden\"\r\n style={\r\n {\r\n \"--sidebar-width\": SIDEBAR_WIDTH_MOBILE,\r\n } as React.CSSProperties\r\n }\r\n side={side}\r\n >\r\n <SheetHeader className=\"sr-only\">\r\n <SheetTitle>Sidebar</SheetTitle>\r\n <SheetDescription>Displays the mobile sidebar.</SheetDescription>\r\n </SheetHeader>\r\n <div className=\"flex h-full w-full flex-col\">{children}</div>\r\n </SheetContent>\r\n </Sheet>\r\n )\r\n }\r\n\r\n return (\r\n <div\r\n className=\"group peer hidden text-sidebar-foreground md:block\"\r\n data-state={state}\r\n data-collapsible={state === \"collapsed\" ? collapsible : \"\"}\r\n data-variant={variant}\r\n data-side={side}\r\n data-slot=\"sidebar\"\r\n >\r\n {/* This is what handles the sidebar gap on desktop */}\r\n <div\r\n data-slot=\"sidebar-gap\"\r\n className={cn(\r\n \"relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear\",\r\n \"group-data-[collapsible=offcanvas]:w-0\",\r\n \"group-data-[side=right]:rotate-180\",\r\n variant === \"floating\" || variant === \"inset\"\r\n ? \"group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]\"\r\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon)\"\r\n )}\r\n />\r\n <div\r\n data-slot=\"sidebar-container\"\r\n data-side={side}\r\n className={cn(\r\n \"fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear data-[side=left]:left-0 data-[side=left]:group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)] data-[side=right]:right-0 data-[side=right]:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)] md:flex\",\r\n // Adjust the padding for floating and inset variants.\r\n variant === \"floating\" || variant === \"inset\"\r\n ? \"p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]\"\r\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n <div\r\n data-sidebar=\"sidebar\"\r\n data-slot=\"sidebar-inner\"\r\n className=\"flex size-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 group-data-[variant=floating]:ring-sidebar-border\"\r\n >\r\n {children}\r\n </div>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nfunction SidebarTrigger({\r\n className,\r\n onClick,\r\n ...props\r\n}: React.ComponentProps<typeof Button>) {\r\n const { toggleSidebar } = useSidebar()\r\n\r\n return (\r\n <Button\r\n data-sidebar=\"trigger\"\r\n data-slot=\"sidebar-trigger\"\r\n variant=\"ghost\"\r\n size=\"icon-sm\"\r\n className={cn(className)}\r\n onClick={(event) => {\r\n onClick?.(event)\r\n toggleSidebar()\r\n }}\r\n {...props}\r\n >\r\n <PanelLeftIcon className=\"cn-rtl-flip\" />\r\n <span className=\"sr-only\">Toggle Sidebar</span>\r\n </Button>\r\n )\r\n}\r\n\r\nfunction SidebarRail({ className, ...props }: React.ComponentProps<\"button\">) {\r\n const { toggleSidebar } = useSidebar()\r\n\r\n return (\r\n <button\r\n data-sidebar=\"rail\"\r\n data-slot=\"sidebar-rail\"\r\n aria-label=\"Toggle Sidebar\"\r\n tabIndex={-1}\r\n onClick={toggleSidebar}\r\n title=\"Toggle Sidebar\"\r\n className={cn(\r\n \"absolute inset-y-0 z-20 hidden w-4 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:start-1/2 after:w-[2px] hover:after:bg-sidebar-border sm:flex ltr:-translate-x-1/2 rtl:-translate-x-1/2\",\r\n \"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize\",\r\n \"[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize\",\r\n \"group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full hover:group-data-[collapsible=offcanvas]:bg-sidebar\",\r\n \"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2\",\r\n \"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction SidebarInset({ className, ...props }: React.ComponentProps<\"main\">) {\r\n return (\r\n <main\r\n data-slot=\"sidebar-inset\"\r\n className={cn(\r\n \"relative flex w-full flex-1 flex-col bg-background md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction SidebarInput({\r\n className,\r\n ...props\r\n}: React.ComponentProps<typeof Input>) {\r\n return (\r\n <Input\r\n data-slot=\"sidebar-input\"\r\n data-sidebar=\"input\"\r\n className={cn(\"h-8 w-full bg-background shadow-none\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction SidebarHeader({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"sidebar-header\"\r\n data-sidebar=\"header\"\r\n className={cn(\"flex flex-col gap-2 p-2\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction SidebarFooter({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"sidebar-footer\"\r\n data-sidebar=\"footer\"\r\n className={cn(\"flex flex-col gap-2 p-2\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction SidebarSeparator({\r\n className,\r\n ...props\r\n}: React.ComponentProps<typeof Separator>) {\r\n return (\r\n <Separator\r\n data-slot=\"sidebar-separator\"\r\n data-sidebar=\"separator\"\r\n className={cn(\"mx-2 w-auto bg-sidebar-border\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction SidebarContent({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"sidebar-content\"\r\n data-sidebar=\"content\"\r\n className={cn(\r\n \"no-scrollbar flex min-h-0 flex-1 flex-col gap-0 overflow-auto group-data-[collapsible=icon]:overflow-hidden\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction SidebarGroup({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"sidebar-group\"\r\n data-sidebar=\"group\"\r\n className={cn(\"relative flex w-full min-w-0 flex-col p-2\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction SidebarGroupLabel({\r\n className,\r\n render,\r\n ...props\r\n}: useRender.ComponentProps<\"div\"> & React.ComponentProps<\"div\">) {\r\n return useRender({\r\n defaultTagName: \"div\",\r\n props: mergeProps<\"div\">(\r\n {\r\n className: cn(\r\n \"flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 ring-sidebar-ring outline-hidden transition-[margin,opacity] duration-200 ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\r\n className\r\n ),\r\n },\r\n props\r\n ),\r\n render,\r\n state: {\r\n slot: \"sidebar-group-label\",\r\n sidebar: \"group-label\",\r\n },\r\n })\r\n}\r\n\r\nfunction SidebarGroupAction({\r\n className,\r\n render,\r\n ...props\r\n}: useRender.ComponentProps<\"button\"> & React.ComponentProps<\"button\">) {\r\n return useRender({\r\n defaultTagName: \"button\",\r\n props: mergeProps<\"button\">(\r\n {\r\n className: cn(\r\n \"absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0\",\r\n className\r\n ),\r\n },\r\n props\r\n ),\r\n render,\r\n state: {\r\n slot: \"sidebar-group-action\",\r\n sidebar: \"group-action\",\r\n },\r\n })\r\n}\r\n\r\nfunction SidebarGroupContent({\r\n className,\r\n ...props\r\n}: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"sidebar-group-content\"\r\n data-sidebar=\"group-content\"\r\n className={cn(\"w-full text-sm\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction SidebarMenu({ className, ...props }: React.ComponentProps<\"ul\">) {\r\n return (\r\n <ul\r\n data-slot=\"sidebar-menu\"\r\n data-sidebar=\"menu\"\r\n className={cn(\"flex w-full min-w-0 flex-col gap-0\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction SidebarMenuItem({ className, ...props }: React.ComponentProps<\"li\">) {\r\n return (\r\n <li\r\n data-slot=\"sidebar-menu-item\"\r\n data-sidebar=\"menu-item\"\r\n className={cn(\"group/menu-item relative\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nconst sidebarMenuButtonVariants = cva(\r\n \"peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:font-medium data-active:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate\",\r\n {\r\n variants: {\r\n variant: {\r\n default: \"hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\r\n outline:\r\n \"bg-background shadow-[0_0_0_1px_var(--sidebar-border)] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_var(--sidebar-accent)]\",\r\n },\r\n size: {\r\n default: \"h-8 text-sm\",\r\n sm: \"h-7 text-xs\",\r\n lg: \"h-12 text-sm group-data-[collapsible=icon]:p-0!\",\r\n },\r\n },\r\n defaultVariants: {\r\n variant: \"default\",\r\n size: \"default\",\r\n },\r\n }\r\n)\r\n\r\nfunction SidebarMenuButton({\r\n render,\r\n isActive = false,\r\n variant = \"default\",\r\n size = \"default\",\r\n tooltip,\r\n className,\r\n ...props\r\n}: useRender.ComponentProps<\"button\"> &\r\n React.ComponentProps<\"button\"> & {\r\n isActive?: boolean\r\n tooltip?: string | React.ComponentProps<typeof TooltipContent>\r\n } & VariantProps<typeof sidebarMenuButtonVariants>) {\r\n const { isMobile, state } = useSidebar()\r\n const comp = useRender({\r\n defaultTagName: \"button\",\r\n props: mergeProps<\"button\">(\r\n {\r\n className: cn(sidebarMenuButtonVariants({ variant, size }), className),\r\n },\r\n props\r\n ),\r\n render: !tooltip ? render : <TooltipTrigger render={render} />,\r\n state: {\r\n slot: \"sidebar-menu-button\",\r\n sidebar: \"menu-button\",\r\n size,\r\n active: isActive,\r\n },\r\n })\r\n\r\n if (!tooltip) {\r\n return comp\r\n }\r\n\r\n if (typeof tooltip === \"string\") {\r\n tooltip = {\r\n children: tooltip,\r\n }\r\n }\r\n\r\n return (\r\n <Tooltip>\r\n {comp}\r\n <TooltipContent\r\n side=\"right\"\r\n align=\"center\"\r\n hidden={state !== \"collapsed\" || isMobile}\r\n {...tooltip}\r\n />\r\n </Tooltip>\r\n )\r\n}\r\n\r\nfunction SidebarMenuAction({\r\n className,\r\n render,\r\n showOnHover = false,\r\n ...props\r\n}: useRender.ComponentProps<\"button\"> &\r\n React.ComponentProps<\"button\"> & {\r\n showOnHover?: boolean\r\n }) {\r\n return useRender({\r\n defaultTagName: \"button\",\r\n props: mergeProps<\"button\">(\r\n {\r\n className: cn(\r\n \"absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0\",\r\n showOnHover &&\r\n \"group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-active/menu-button:text-sidebar-accent-foreground aria-expanded:opacity-100 md:opacity-0\",\r\n className\r\n ),\r\n },\r\n props\r\n ),\r\n render,\r\n state: {\r\n slot: \"sidebar-menu-action\",\r\n sidebar: \"menu-action\",\r\n },\r\n })\r\n}\r\n\r\nfunction SidebarMenuBadge({\r\n className,\r\n ...props\r\n}: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"sidebar-menu-badge\"\r\n data-sidebar=\"menu-badge\"\r\n className={cn(\r\n \"pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium text-sidebar-foreground tabular-nums select-none group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 peer-data-active/menu-button:text-sidebar-accent-foreground\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction SidebarMenuSkeleton({\r\n className,\r\n showIcon = false,\r\n ...props\r\n}: React.ComponentProps<\"div\"> & {\r\n showIcon?: boolean\r\n}) {\r\n // Random width between 50 to 90%.\r\n const [width] = React.useState(() => {\r\n return `${Math.floor(Math.random() * 40) + 50}%`\r\n })\r\n\r\n return (\r\n <div\r\n data-slot=\"sidebar-menu-skeleton\"\r\n data-sidebar=\"menu-skeleton\"\r\n className={cn(\"flex h-8 items-center gap-2 rounded-md px-2\", className)}\r\n {...props}\r\n >\r\n {showIcon && (\r\n <Skeleton\r\n className=\"size-4 rounded-md\"\r\n data-sidebar=\"menu-skeleton-icon\"\r\n />\r\n )}\r\n <Skeleton\r\n className=\"h-4 max-w-(--skeleton-width) flex-1\"\r\n data-sidebar=\"menu-skeleton-text\"\r\n style={\r\n {\r\n \"--skeleton-width\": width,\r\n } as React.CSSProperties\r\n }\r\n />\r\n </div>\r\n )\r\n}\r\n\r\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<\"ul\">) {\r\n return (\r\n <ul\r\n data-slot=\"sidebar-menu-sub\"\r\n data-sidebar=\"menu-sub\"\r\n className={cn(\r\n \"mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5 group-data-[collapsible=icon]:hidden\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction SidebarMenuSubItem({\r\n className,\r\n ...props\r\n}: React.ComponentProps<\"li\">) {\r\n return (\r\n <li\r\n data-slot=\"sidebar-menu-sub-item\"\r\n data-sidebar=\"menu-sub-item\"\r\n className={cn(\"group/menu-sub-item relative\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction SidebarMenuSubButton({\r\n render,\r\n size = \"md\",\r\n isActive = false,\r\n className,\r\n ...props\r\n}: useRender.ComponentProps<\"a\"> &\r\n React.ComponentProps<\"a\"> & {\r\n size?: \"sm\" | \"md\"\r\n isActive?: boolean\r\n }) {\r\n return useRender({\r\n defaultTagName: \"a\",\r\n props: mergeProps<\"a\">(\r\n {\r\n className: cn(\r\n \"flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground ring-sidebar-ring outline-hidden group-data-[collapsible=icon]:hidden hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[size=md]:text-sm data-[size=sm]:text-xs data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground\",\r\n className\r\n ),\r\n },\r\n props\r\n ),\r\n render,\r\n state: {\r\n slot: \"sidebar-menu-sub-button\",\r\n sidebar: \"menu-sub-button\",\r\n size,\r\n active: isActive,\r\n },\r\n })\r\n}\r\n\r\nexport {\r\n Sidebar,\r\n SidebarContent,\r\n SidebarFooter,\r\n SidebarGroup,\r\n SidebarGroupAction,\r\n SidebarGroupContent,\r\n SidebarGroupLabel,\r\n SidebarHeader,\r\n SidebarInput,\r\n SidebarInset,\r\n SidebarMenu,\r\n SidebarMenuAction,\r\n SidebarMenuBadge,\r\n SidebarMenuButton,\r\n SidebarMenuItem,\r\n SidebarMenuSkeleton,\r\n SidebarMenuSub,\r\n SidebarMenuSubButton,\r\n SidebarMenuSubItem,\r\n SidebarProvider,\r\n SidebarRail,\r\n SidebarSeparator,\r\n SidebarTrigger,\r\n useSidebar,\r\n}\r\n"
|
|
360
938
|
}
|
|
361
939
|
]
|
|
362
940
|
},
|
|
363
941
|
{
|
|
364
942
|
"name": "skeleton",
|
|
943
|
+
"type": "components:ui",
|
|
944
|
+
"frameworks": [
|
|
945
|
+
"react",
|
|
946
|
+
"nextjs",
|
|
947
|
+
"vue",
|
|
948
|
+
"nuxt",
|
|
949
|
+
"solid",
|
|
950
|
+
"svelte",
|
|
951
|
+
"astro",
|
|
952
|
+
"remix"
|
|
953
|
+
],
|
|
365
954
|
"dependencies": [],
|
|
955
|
+
"registryDependencies": [],
|
|
366
956
|
"files": [
|
|
367
957
|
{
|
|
368
958
|
"name": "skeleton.tsx",
|
|
369
|
-
"content": "import
|
|
959
|
+
"content": "import { cn } from \"@/lib/utils\"\r\n\r\nfunction Skeleton({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n <div\r\n data-slot=\"skeleton\"\r\n className={cn(\"animate-pulse rounded-md bg-muted\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport { Skeleton }\r\n"
|
|
370
960
|
}
|
|
371
961
|
]
|
|
372
962
|
},
|
|
373
963
|
{
|
|
374
964
|
"name": "slider",
|
|
965
|
+
"type": "components:ui",
|
|
966
|
+
"frameworks": [
|
|
967
|
+
"react",
|
|
968
|
+
"nextjs",
|
|
969
|
+
"vue",
|
|
970
|
+
"nuxt",
|
|
971
|
+
"solid",
|
|
972
|
+
"svelte",
|
|
973
|
+
"astro",
|
|
974
|
+
"remix"
|
|
975
|
+
],
|
|
375
976
|
"dependencies": [
|
|
376
977
|
"@base-ui/react"
|
|
377
978
|
],
|
|
979
|
+
"registryDependencies": [],
|
|
378
980
|
"files": [
|
|
379
981
|
{
|
|
380
982
|
"name": "slider.tsx",
|
|
381
|
-
"content": "
|
|
983
|
+
"content": "import { Slider as SliderPrimitive } from \"@base-ui/react/slider\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction Slider({\r\n className,\r\n defaultValue,\r\n value,\r\n min = 0,\r\n max = 100,\r\n ...props\r\n}: SliderPrimitive.Root.Props) {\r\n const _values = Array.isArray(value)\r\n ? value\r\n : Array.isArray(defaultValue)\r\n ? defaultValue\r\n : [min, max]\r\n\r\n return (\r\n <SliderPrimitive.Root\r\n className={cn(\"data-horizontal:w-full data-vertical:h-full\", className)}\r\n data-slot=\"slider\"\r\n defaultValue={defaultValue}\r\n value={value}\r\n min={min}\r\n max={max}\r\n thumbAlignment=\"edge\"\r\n {...props}\r\n >\r\n <SliderPrimitive.Control className=\"relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:min-h-40 data-vertical:w-auto data-vertical:flex-col\">\r\n <SliderPrimitive.Track\r\n data-slot=\"slider-track\"\r\n className=\"relative grow overflow-hidden rounded-full bg-muted select-none data-horizontal:h-1 data-horizontal:w-full data-vertical:h-full data-vertical:w-1\"\r\n >\r\n <SliderPrimitive.Indicator\r\n data-slot=\"slider-range\"\r\n className=\"bg-primary select-none data-horizontal:h-full data-vertical:w-full\"\r\n />\r\n </SliderPrimitive.Track>\r\n {Array.from({ length: _values.length }, (_, index) => (\r\n <SliderPrimitive.Thumb\r\n data-slot=\"slider-thumb\"\r\n key={index}\r\n className=\"relative block size-3 shrink-0 rounded-full border border-ring bg-white ring-ring/50 transition-[color,box-shadow] select-none after:absolute after:-inset-2 hover:ring-3 focus-visible:ring-3 focus-visible:outline-hidden active:ring-3 disabled:pointer-events-none disabled:opacity-50\"\r\n />\r\n ))}\r\n </SliderPrimitive.Control>\r\n </SliderPrimitive.Root>\r\n )\r\n}\r\n\r\nexport { Slider }\r\n"
|
|
382
984
|
}
|
|
383
985
|
]
|
|
384
986
|
},
|
|
385
987
|
{
|
|
386
988
|
"name": "sonner",
|
|
989
|
+
"type": "components:ui",
|
|
990
|
+
"frameworks": [
|
|
991
|
+
"react",
|
|
992
|
+
"nextjs",
|
|
993
|
+
"vue",
|
|
994
|
+
"nuxt",
|
|
995
|
+
"solid",
|
|
996
|
+
"svelte",
|
|
997
|
+
"astro",
|
|
998
|
+
"remix"
|
|
999
|
+
],
|
|
387
1000
|
"dependencies": [],
|
|
1001
|
+
"registryDependencies": [],
|
|
388
1002
|
"files": [
|
|
389
1003
|
{
|
|
390
1004
|
"name": "sonner.tsx",
|
|
391
|
-
"content": "\"use client\"\r\n\r\nimport
|
|
1005
|
+
"content": "\"use client\"\r\n\r\nimport {\r\n CircleCheckIcon,\r\n InfoIcon,\r\n Loader2Icon,\r\n OctagonXIcon,\r\n TriangleAlertIcon,\r\n} from \"lucide-react\"\r\nimport { useTheme } from \"next-themes\"\r\nimport { Toaster as Sonner, type ToasterProps } from \"sonner\"\r\n\r\nconst Toaster = ({ ...props }: ToasterProps) => {\r\n const { theme = \"system\" } = useTheme()\r\n\r\n return (\r\n <Sonner\r\n theme={theme as ToasterProps[\"theme\"]}\r\n className=\"toaster group\"\r\n icons={{\r\n success: <CircleCheckIcon className=\"size-4\" />,\r\n info: <InfoIcon className=\"size-4\" />,\r\n warning: <TriangleAlertIcon className=\"size-4\" />,\r\n error: <OctagonXIcon className=\"size-4\" />,\r\n loading: <Loader2Icon className=\"size-4 animate-spin\" />,\r\n }}\r\n style={\r\n {\r\n \"--normal-bg\": \"var(--popover)\",\r\n \"--normal-text\": \"var(--popover-foreground)\",\r\n \"--normal-border\": \"var(--border)\",\r\n \"--border-radius\": \"var(--radius)\",\r\n } as React.CSSProperties\r\n }\r\n toastOptions={{\r\n classNames: {\r\n toast: \"cn-toast\",\r\n },\r\n }}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport { Toaster }\r\n"
|
|
392
1006
|
}
|
|
393
1007
|
]
|
|
394
1008
|
},
|
|
395
1009
|
{
|
|
396
1010
|
"name": "spinner",
|
|
1011
|
+
"type": "components:ui",
|
|
1012
|
+
"frameworks": [
|
|
1013
|
+
"react",
|
|
1014
|
+
"nextjs",
|
|
1015
|
+
"vue",
|
|
1016
|
+
"nuxt",
|
|
1017
|
+
"solid",
|
|
1018
|
+
"svelte",
|
|
1019
|
+
"astro",
|
|
1020
|
+
"remix"
|
|
1021
|
+
],
|
|
397
1022
|
"dependencies": [],
|
|
1023
|
+
"registryDependencies": [],
|
|
398
1024
|
"files": [
|
|
399
1025
|
{
|
|
400
1026
|
"name": "spinner.tsx",
|
|
401
|
-
"content": "import
|
|
1027
|
+
"content": "import { Loader2Icon } from \"lucide-react\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction Spinner({ className, ...props }: React.ComponentProps<\"svg\">) {\r\n return (\r\n <Loader2Icon\r\n role=\"status\"\r\n aria-label=\"Loading\"\r\n className={cn(\"size-4 animate-spin\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport { Spinner }\r\n"
|
|
402
1028
|
}
|
|
403
1029
|
]
|
|
404
1030
|
},
|
|
405
1031
|
{
|
|
406
1032
|
"name": "switch",
|
|
1033
|
+
"type": "components:ui",
|
|
1034
|
+
"frameworks": [
|
|
1035
|
+
"react",
|
|
1036
|
+
"nextjs",
|
|
1037
|
+
"vue",
|
|
1038
|
+
"nuxt",
|
|
1039
|
+
"solid",
|
|
1040
|
+
"svelte",
|
|
1041
|
+
"astro",
|
|
1042
|
+
"remix"
|
|
1043
|
+
],
|
|
407
1044
|
"dependencies": [
|
|
408
1045
|
"@base-ui/react"
|
|
409
1046
|
],
|
|
1047
|
+
"registryDependencies": [],
|
|
410
1048
|
"files": [
|
|
411
1049
|
{
|
|
412
1050
|
"name": "switch.tsx",
|
|
413
|
-
"content": "\"use client\"\r\n\r\nimport
|
|
1051
|
+
"content": "\"use client\"\r\n\r\nimport { Switch as SwitchPrimitive } from \"@base-ui/react/switch\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction Switch({\r\n className,\r\n size = \"default\",\r\n ...props\r\n}: SwitchPrimitive.Root.Props & {\r\n size?: \"sm\" | \"default\"\r\n}) {\r\n return (\r\n <SwitchPrimitive.Root\r\n data-slot=\"switch\"\r\n data-size={size}\r\n className={cn(\r\n \"peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n <SwitchPrimitive.Thumb\r\n data-slot=\"switch-thumb\"\r\n className=\"pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] dark:data-checked:bg-primary-foreground group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-unchecked:bg-foreground\"\r\n />\r\n </SwitchPrimitive.Root>\r\n )\r\n}\r\n\r\nexport { Switch }\r\n"
|
|
414
1052
|
}
|
|
415
1053
|
]
|
|
416
1054
|
},
|
|
417
1055
|
{
|
|
418
1056
|
"name": "table",
|
|
1057
|
+
"type": "components:ui",
|
|
1058
|
+
"frameworks": [
|
|
1059
|
+
"react",
|
|
1060
|
+
"nextjs",
|
|
1061
|
+
"vue",
|
|
1062
|
+
"nuxt",
|
|
1063
|
+
"solid",
|
|
1064
|
+
"svelte",
|
|
1065
|
+
"astro",
|
|
1066
|
+
"remix"
|
|
1067
|
+
],
|
|
419
1068
|
"dependencies": [],
|
|
1069
|
+
"registryDependencies": [],
|
|
420
1070
|
"files": [
|
|
421
1071
|
{
|
|
422
1072
|
"name": "table.tsx",
|
|
423
|
-
"content": "
|
|
1073
|
+
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction Table({ className, ...props }: React.ComponentProps<\"table\">) {\r\n return (\r\n <div\r\n data-slot=\"table-container\"\r\n className=\"relative w-full overflow-x-auto\"\r\n >\r\n <table\r\n data-slot=\"table\"\r\n className={cn(\"w-full caption-bottom text-sm\", className)}\r\n {...props}\r\n />\r\n </div>\r\n )\r\n}\r\n\r\nfunction TableHeader({ className, ...props }: React.ComponentProps<\"thead\">) {\r\n return (\r\n <thead\r\n data-slot=\"table-header\"\r\n className={cn(\"[&_tr]:border-b\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction TableBody({ className, ...props }: React.ComponentProps<\"tbody\">) {\r\n return (\r\n <tbody\r\n data-slot=\"table-body\"\r\n className={cn(\"[&_tr:last-child]:border-0\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction TableFooter({ className, ...props }: React.ComponentProps<\"tfoot\">) {\r\n return (\r\n <tfoot\r\n data-slot=\"table-footer\"\r\n className={cn(\r\n \"border-t bg-muted/50 font-medium [&>tr]:last:border-b-0\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction TableRow({ className, ...props }: React.ComponentProps<\"tr\">) {\r\n return (\r\n <tr\r\n data-slot=\"table-row\"\r\n className={cn(\r\n \"border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction TableHead({ className, ...props }: React.ComponentProps<\"th\">) {\r\n return (\r\n <th\r\n data-slot=\"table-head\"\r\n className={cn(\r\n \"h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction TableCell({ className, ...props }: React.ComponentProps<\"td\">) {\r\n return (\r\n <td\r\n data-slot=\"table-cell\"\r\n className={cn(\r\n \"p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction TableCaption({\r\n className,\r\n ...props\r\n}: React.ComponentProps<\"caption\">) {\r\n return (\r\n <caption\r\n data-slot=\"table-caption\"\r\n className={cn(\"mt-4 text-sm text-muted-foreground\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport {\r\n Table,\r\n TableHeader,\r\n TableBody,\r\n TableFooter,\r\n TableHead,\r\n TableRow,\r\n TableCell,\r\n TableCaption,\r\n}\r\n"
|
|
424
1074
|
}
|
|
425
1075
|
]
|
|
426
1076
|
},
|
|
427
1077
|
{
|
|
428
1078
|
"name": "tabs",
|
|
1079
|
+
"type": "components:ui",
|
|
1080
|
+
"frameworks": [
|
|
1081
|
+
"react",
|
|
1082
|
+
"nextjs",
|
|
1083
|
+
"vue",
|
|
1084
|
+
"nuxt",
|
|
1085
|
+
"solid",
|
|
1086
|
+
"svelte",
|
|
1087
|
+
"astro",
|
|
1088
|
+
"remix"
|
|
1089
|
+
],
|
|
429
1090
|
"dependencies": [
|
|
430
1091
|
"@base-ui/react"
|
|
431
1092
|
],
|
|
1093
|
+
"registryDependencies": [],
|
|
432
1094
|
"files": [
|
|
433
1095
|
{
|
|
434
1096
|
"name": "tabs.tsx",
|
|
435
|
-
"content": "\"use client\"\r\n\r\nimport
|
|
1097
|
+
"content": "\"use client\"\r\n\r\nimport { Tabs as TabsPrimitive } from \"@base-ui/react/tabs\"\r\nimport { cva, type VariantProps } from \"class-variance-authority\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction Tabs({\r\n className,\r\n orientation = \"horizontal\",\r\n ...props\r\n}: TabsPrimitive.Root.Props) {\r\n return (\r\n <TabsPrimitive.Root\r\n data-slot=\"tabs\"\r\n data-orientation={orientation}\r\n className={cn(\r\n \"group/tabs flex gap-2 data-horizontal:flex-col\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nconst tabsListVariants = cva(\r\n \"group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none\",\r\n {\r\n variants: {\r\n variant: {\r\n default: \"bg-muted\",\r\n line: \"gap-1 bg-transparent\",\r\n },\r\n },\r\n defaultVariants: {\r\n variant: \"default\",\r\n },\r\n }\r\n)\r\n\r\nfunction TabsList({\r\n className,\r\n variant = \"default\",\r\n ...props\r\n}: TabsPrimitive.List.Props & VariantProps<typeof tabsListVariants>) {\r\n return (\r\n <TabsPrimitive.List\r\n data-slot=\"tabs-list\"\r\n data-variant={variant}\r\n className={cn(tabsListVariants({ variant }), className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction TabsTrigger({ className, ...props }: TabsPrimitive.Tab.Props) {\r\n return (\r\n <TabsPrimitive.Tab\r\n data-slot=\"tabs-trigger\"\r\n className={cn(\r\n \"relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 aria-disabled:pointer-events-none aria-disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\r\n \"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent\",\r\n \"data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground\",\r\n \"after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction TabsContent({ className, ...props }: TabsPrimitive.Panel.Props) {\r\n return (\r\n <TabsPrimitive.Panel\r\n data-slot=\"tabs-content\"\r\n className={cn(\"flex-1 text-sm outline-none\", className)}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants }\r\n"
|
|
436
1098
|
}
|
|
437
1099
|
]
|
|
438
1100
|
},
|
|
439
1101
|
{
|
|
440
1102
|
"name": "textarea",
|
|
1103
|
+
"type": "components:ui",
|
|
1104
|
+
"frameworks": [
|
|
1105
|
+
"react",
|
|
1106
|
+
"nextjs",
|
|
1107
|
+
"vue",
|
|
1108
|
+
"nuxt",
|
|
1109
|
+
"solid",
|
|
1110
|
+
"svelte",
|
|
1111
|
+
"astro",
|
|
1112
|
+
"remix"
|
|
1113
|
+
],
|
|
441
1114
|
"dependencies": [],
|
|
1115
|
+
"registryDependencies": [],
|
|
442
1116
|
"files": [
|
|
443
1117
|
{
|
|
444
1118
|
"name": "textarea.tsx",
|
|
445
|
-
"content": "import * as React from \"react\"\r\nimport { cn } from \"@/lib/utils\"\r\n\r\
|
|
446
|
-
}
|
|
447
|
-
]
|
|
448
|
-
},
|
|
449
|
-
{
|
|
450
|
-
"name": "toast",
|
|
451
|
-
"dependencies": [],
|
|
452
|
-
"files": [
|
|
453
|
-
{
|
|
454
|
-
"name": "toast.tsx",
|
|
455
|
-
"content": "\"use client\"\r\n\r\nimport * as React from \"react\"\r\nimport { cn } from \"@/lib/utils\"\r\n\r\ninterface ToastMessage {\r\n id: string\r\n title?: string\r\n description?: string\r\n variant?: \"default\" | \"destructive\"\r\n}\r\n\r\nconst ToastContext = React.createContext<{\r\n toast: (props: Omit<ToastMessage, \"id\">) => void\r\n} | null>(null)\r\n\r\nexport function useToast() {\r\n const context = React.useContext(ToastContext)\r\n if (!context) throw new Error(\"useToast must be used within a ToastProvider\")\r\n return context\r\n}\r\n\r\nexport const ToastProvider = ({ children }: { children: React.ReactNode }) => {\r\n const [toasts, setToasts] = React.useState<ToastMessage[]>([])\r\n\r\n const toast = React.useCallback(({ title, description, variant = \"default\" }: Omit<ToastMessage, \"id\">) => {\r\n const id = Math.random().toString(36).substring(2, 9)\r\n setToasts((prev) => [...prev, { id, title, description, variant }])\r\n\r\n setTimeout(() => {\r\n setToasts((prev) => prev.filter((t) => t.id !== id))\r\n }, 4000)\r\n }, [])\r\n\r\n return (\r\n <ToastContext.Provider value={{ toast }}>\r\n {children}\r\n <div className=\"fixed bottom-0 right-0 z-50 flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px] gap-2\">\r\n {toasts.map((t) => (\r\n <div\r\n key={t.id}\r\n className={cn(\r\n \"group relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-4 pr-8 shadow-lg transition-all duration-300 ease-out\",\r\n t.variant === \"default\" && \"bg-background border-border text-foreground\",\r\n t.variant === \"destructive\" && \"destructive group border-destructive bg-destructive text-destructive-foreground\"\r\n )}\r\n >\r\n <div className=\"grid gap-1\">\r\n {t.title && <div className=\"text-sm font-semibold\">{t.title}</div>}\r\n {t.description && <div className={cn(\"text-xs opacity-90\", t.variant === \"default\" ? \"text-muted-foreground\" : \"text-primary-foreground\")}>{t.description}</div>}\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n </ToastContext.Provider>\r\n )\r\n}"
|
|
1119
|
+
"content": "import * as React from \"react\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\r\n return (\r\n <textarea\r\n data-slot=\"textarea\"\r\n className={cn(\r\n \"flex field-sizing-content min-h-16 w-full rounded-lg border border-input bg-transparent px-2.5 py-2 text-base transition-colors outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40\",\r\n className\r\n )}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport { Textarea }\r\n"
|
|
456
1120
|
}
|
|
457
1121
|
]
|
|
458
1122
|
},
|
|
459
1123
|
{
|
|
460
1124
|
"name": "toggle-group",
|
|
1125
|
+
"type": "components:ui",
|
|
1126
|
+
"frameworks": [
|
|
1127
|
+
"react",
|
|
1128
|
+
"nextjs",
|
|
1129
|
+
"vue",
|
|
1130
|
+
"nuxt",
|
|
1131
|
+
"solid",
|
|
1132
|
+
"svelte",
|
|
1133
|
+
"astro",
|
|
1134
|
+
"remix"
|
|
1135
|
+
],
|
|
461
1136
|
"dependencies": [
|
|
462
1137
|
"@base-ui/react"
|
|
463
1138
|
],
|
|
1139
|
+
"registryDependencies": [],
|
|
464
1140
|
"files": [
|
|
465
1141
|
{
|
|
466
1142
|
"name": "toggle-group.tsx",
|
|
467
|
-
"content": "\"use client\"\
|
|
1143
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Toggle as TogglePrimitive } from \"@base-ui/react/toggle\"\nimport { ToggleGroup as ToggleGroupPrimitive } from \"@base-ui/react/toggle-group\"\nimport { type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\nimport { toggleVariants } from \"@/toggle\"\n\nconst ToggleGroupContext = React.createContext<\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: \"horizontal\" | \"vertical\"\n }\n>({\n size: \"default\",\n variant: \"default\",\n spacing: 2,\n orientation: \"horizontal\",\n})\n\nfunction ToggleGroup({\n className,\n variant,\n size,\n spacing = 2,\n orientation = \"horizontal\",\n children,\n ...props\n}: ToggleGroupPrimitive.Props &\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: \"horizontal\" | \"vertical\"\n }) {\n return (\n <ToggleGroupPrimitive\n data-slot=\"toggle-group\"\n data-variant={variant}\n data-size={size}\n data-spacing={spacing}\n data-orientation={orientation}\n style={{ \"--gap\": spacing } as React.CSSProperties}\n className={cn(\n \"group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] rounded-lg data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-vertical:flex-col data-vertical:items-stretch\",\n className\n )}\n {...props}\n >\n <ToggleGroupContext.Provider\n value={{ variant, size, spacing, orientation }}\n >\n {children}\n </ToggleGroupContext.Provider>\n </ToggleGroupPrimitive>\n )\n}\n\nfunction ToggleGroupItem({\n className,\n children,\n variant = \"default\",\n size = \"default\",\n ...props\n}: TogglePrimitive.Props & VariantProps<typeof toggleVariants>) {\n const context = React.useContext(ToggleGroupContext)\n\n return (\n <TogglePrimitive\n data-slot=\"toggle-group-item\"\n data-variant={context.variant || variant}\n data-size={context.size || size}\n data-spacing={context.spacing}\n className={cn(\n \"shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 focus:z-10 focus-visible:z-10 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-end]:pr-1.5 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-start]:pl-1.5 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-lg group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-lg group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-lg group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-lg group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t\",\n toggleVariants({\n variant: context.variant || variant,\n size: context.size || size,\n }),\n className\n )}\n {...props}\n >\n {children}\n </TogglePrimitive>\n )\n}\n\nexport { ToggleGroup, ToggleGroupItem }\n"
|
|
468
1144
|
}
|
|
469
1145
|
]
|
|
470
1146
|
},
|
|
471
1147
|
{
|
|
472
1148
|
"name": "toggle",
|
|
1149
|
+
"type": "components:ui",
|
|
1150
|
+
"frameworks": [
|
|
1151
|
+
"react",
|
|
1152
|
+
"nextjs",
|
|
1153
|
+
"vue",
|
|
1154
|
+
"nuxt",
|
|
1155
|
+
"solid",
|
|
1156
|
+
"svelte",
|
|
1157
|
+
"astro",
|
|
1158
|
+
"remix"
|
|
1159
|
+
],
|
|
473
1160
|
"dependencies": [
|
|
474
1161
|
"@base-ui/react",
|
|
475
1162
|
"class-variance-authority"
|
|
476
1163
|
],
|
|
1164
|
+
"registryDependencies": [],
|
|
477
1165
|
"files": [
|
|
478
1166
|
{
|
|
479
1167
|
"name": "toggle.tsx",
|
|
480
|
-
"content": "\"use client\"\r\n\r\nimport
|
|
1168
|
+
"content": "\"use client\"\r\n\r\nimport { Toggle as TogglePrimitive } from \"@base-ui/react/toggle\"\r\nimport { cva, type VariantProps } from \"class-variance-authority\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nconst toggleVariants = cva(\r\n \"group/toggle inline-flex items-center justify-center gap-1 rounded-lg text-sm font-medium whitespace-nowrap transition-all outline-none hover:bg-muted hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 aria-pressed:bg-muted data-[state=on]:bg-muted dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\r\n {\r\n variants: {\r\n variant: {\r\n default: \"bg-transparent\",\r\n outline: \"border border-input bg-transparent hover:bg-muted\",\r\n },\r\n size: {\r\n default:\r\n \"h-8 min-w-8 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\r\n sm: \"h-7 min-w-7 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5\",\r\n lg: \"h-9 min-w-9 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\r\n },\r\n },\r\n defaultVariants: {\r\n variant: \"default\",\r\n size: \"default\",\r\n },\r\n }\r\n)\r\n\r\nfunction Toggle({\r\n className,\r\n variant = \"default\",\r\n size = \"default\",\r\n ...props\r\n}: TogglePrimitive.Props & VariantProps<typeof toggleVariants>) {\r\n return (\r\n <TogglePrimitive\r\n data-slot=\"toggle\"\r\n className={cn(toggleVariants({ variant, size, className }))}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nexport { Toggle, toggleVariants }\r\n"
|
|
481
1169
|
}
|
|
482
1170
|
]
|
|
483
1171
|
},
|
|
484
1172
|
{
|
|
485
1173
|
"name": "tooltip",
|
|
1174
|
+
"type": "components:ui",
|
|
1175
|
+
"frameworks": [
|
|
1176
|
+
"react",
|
|
1177
|
+
"nextjs",
|
|
1178
|
+
"vue",
|
|
1179
|
+
"nuxt",
|
|
1180
|
+
"solid",
|
|
1181
|
+
"svelte",
|
|
1182
|
+
"astro",
|
|
1183
|
+
"remix"
|
|
1184
|
+
],
|
|
486
1185
|
"dependencies": [
|
|
487
1186
|
"@base-ui/react"
|
|
488
1187
|
],
|
|
1188
|
+
"registryDependencies": [],
|
|
489
1189
|
"files": [
|
|
490
1190
|
{
|
|
491
1191
|
"name": "tooltip.tsx",
|
|
492
|
-
"content": "\"use client\"\r\n\r\nimport
|
|
1192
|
+
"content": "\"use client\"\r\n\r\nimport { Tooltip as TooltipPrimitive } from \"@base-ui/react/tooltip\"\r\n\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nfunction TooltipProvider({\r\n delay = 0,\r\n ...props\r\n}: TooltipPrimitive.Provider.Props) {\r\n return (\r\n <TooltipPrimitive.Provider\r\n data-slot=\"tooltip-provider\"\r\n delay={delay}\r\n {...props}\r\n />\r\n )\r\n}\r\n\r\nfunction Tooltip({ ...props }: TooltipPrimitive.Root.Props) {\r\n return <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\r\n}\r\n\r\nfunction TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {\r\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\r\n}\r\n\r\nfunction TooltipContent({\r\n className,\r\n side = \"top\",\r\n sideOffset = 4,\r\n align = \"center\",\r\n alignOffset = 0,\r\n children,\r\n ...props\r\n}: TooltipPrimitive.Popup.Props &\r\n Pick<\r\n TooltipPrimitive.Positioner.Props,\r\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\r\n >) {\r\n return (\r\n <TooltipPrimitive.Portal>\r\n <TooltipPrimitive.Positioner\r\n align={align}\r\n alignOffset={alignOffset}\r\n side={side}\r\n sideOffset={sideOffset}\r\n className=\"isolate z-50\"\r\n >\r\n <TooltipPrimitive.Popup\r\n data-slot=\"tooltip-content\"\r\n className={cn(\r\n \"z-50 inline-flex w-fit max-w-xs origin-(--transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pr-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\r\n className\r\n )}\r\n {...props}\r\n >\r\n {children}\r\n <TooltipPrimitive.Arrow className=\"z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-left-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-right-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5\" />\r\n </TooltipPrimitive.Popup>\r\n </TooltipPrimitive.Positioner>\r\n </TooltipPrimitive.Portal>\r\n )\r\n}\r\n\r\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\r\n"
|
|
493
1193
|
}
|
|
494
1194
|
]
|
|
495
1195
|
},
|
|
496
1196
|
{
|
|
497
1197
|
"name": "typography",
|
|
1198
|
+
"type": "components:ui",
|
|
1199
|
+
"frameworks": [
|
|
1200
|
+
"react",
|
|
1201
|
+
"nextjs",
|
|
1202
|
+
"vue",
|
|
1203
|
+
"nuxt",
|
|
1204
|
+
"solid",
|
|
1205
|
+
"svelte",
|
|
1206
|
+
"astro",
|
|
1207
|
+
"remix"
|
|
1208
|
+
],
|
|
498
1209
|
"dependencies": [],
|
|
1210
|
+
"registryDependencies": [],
|
|
499
1211
|
"files": [
|
|
500
1212
|
{
|
|
501
1213
|
"name": "typography.tsx",
|
|
502
|
-
"content": "import * as React from \"react\"\r\nimport { cn } from \"@/lib/utils\"\r\n\r\
|
|
1214
|
+
"content": "import * as React from \"react\"\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nexport function TypographyH1() {\r\n return (\r\n <h1 className=\"scroll-m-20 text-center text-4xl font-extrabold tracking-tight text-balance\">\r\n Taxing Laughter: The Joke Tax Chronicles\r\n </h1>\r\n )\r\n}\r\n\r\n\r\nexport function TypographyH2() {\r\n return (\r\n <h2 className=\"scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight first:mt-0\">\r\n The People of the Kingdom\r\n </h2>\r\n )\r\n}\r\n\r\n\r\nexport function TypographyH3() {\r\n return (\r\n <h3 className=\"scroll-m-20 text-2xl font-semibold tracking-tight\">\r\n The Joke Tax\r\n </h3>\r\n )\r\n}\r\n\r\nexport function TypographyH4() {\r\n return (\r\n <h4 className=\"scroll-m-20 text-xl font-semibold tracking-tight\">\r\n People stopped telling jokes\r\n </h4>\r\n )\r\n}\r\n\r\nexport function TypographyP() {\r\n return (\r\n <p className=\"leading-7 [&:not(:first-child)]:mt-6\">\r\n The king, seeing how much happier his subjects were, realized the error of\r\n his ways and repealed the joke tax.\r\n </p>\r\n )\r\n}\r\n\r\nexport function TypographyBlockquote() {\r\n return (\r\n <blockquote className=\"mt-6 border-l-2 pl-6 italic\">\r\n "After all," he said, "everyone enjoys a good joke, so\r\n it's only fair that they should pay for the privilege."\r\n </blockquote>\r\n )\r\n}\r\n\r\nexport function TypographyTable() {\r\n return (\r\n <div className=\"my-6 w-full overflow-y-auto\">\r\n <table className=\"w-full\">\r\n <thead>\r\n <tr className=\"m-0 border-t p-0 even:bg-muted\">\r\n <th className=\"border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right\">\r\n King's Treasury\r\n </th>\r\n <th className=\"border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right\">\r\n People's happiness\r\n </th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr className=\"m-0 border-t p-0 even:bg-muted\">\r\n <td className=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\">\r\n Empty\r\n </td>\r\n <td className=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\">\r\n Overflowing\r\n </td>\r\n </tr>\r\n <tr className=\"m-0 border-t p-0 even:bg-muted\">\r\n <td className=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\">\r\n Modest\r\n </td>\r\n <td className=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\">\r\n Satisfied\r\n </td>\r\n </tr>\r\n <tr className=\"m-0 border-t p-0 even:bg-muted\">\r\n <td className=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\">\r\n Full\r\n </td>\r\n <td className=\"border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\">\r\n Ecstatic\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n )\r\n}\r\n\r\nexport function TypographyList() {\r\n return (\r\n <ul className=\"my-6 ml-6 list-disc [&>li]:mt-2\">\r\n <li>1st level of puns: 5 gold coins</li>\r\n <li>2nd level of jokes: 10 gold coins</li>\r\n <li>3rd level of one-liners : 20 gold coins</li>\r\n </ul>\r\n )\r\n}\r\n\r\nexport function TypographyInlineCode() {\r\n return (\r\n <code className=\"relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold\">\r\n @radix-ui/react-alert-dialog\r\n </code>\r\n )\r\n}\r\n\r\n\r\nexport function TypographyLead() {\r\n return (\r\n <p className=\"text-xl text-muted-foreground\">\r\n A modal dialog that interrupts the user with important content and expects\r\n a response.\r\n </p>\r\n )\r\n}\r\n\r\nexport function TypographyLarge() {\r\n return <div className=\"text-lg font-semibold\">Are you absolutely sure?</div>\r\n}\r\n\r\nexport function TypographySmall() {\r\n return (\r\n <small className=\"text-sm leading-none font-medium\">Email address</small>\r\n )\r\n}\r\n\r\n\r\nexport function TypographyMuted() {\r\n return (\r\n <p className=\"text-sm text-muted-foreground\">Enter your email address.</p>\r\n )\r\n}\r\n\r\n\r\n"
|
|
1215
|
+
}
|
|
1216
|
+
]
|
|
1217
|
+
},
|
|
1218
|
+
{
|
|
1219
|
+
"name": "use-mobile",
|
|
1220
|
+
"type": "components:hook",
|
|
1221
|
+
"frameworks": [
|
|
1222
|
+
"react",
|
|
1223
|
+
"nextjs",
|
|
1224
|
+
"vue",
|
|
1225
|
+
"nuxt",
|
|
1226
|
+
"solid",
|
|
1227
|
+
"svelte",
|
|
1228
|
+
"astro",
|
|
1229
|
+
"remix"
|
|
1230
|
+
],
|
|
1231
|
+
"dependencies": [],
|
|
1232
|
+
"registryDependencies": [],
|
|
1233
|
+
"files": [
|
|
1234
|
+
{
|
|
1235
|
+
"name": "hooks/use-mobile.ts",
|
|
1236
|
+
"content": "import * as React from \"react\"\n\nconst MOBILE_BREAKPOINT = 768\n\nexport function useIsMobile() {\n const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)\n\n React.useEffect(() => {\n const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)\n const onChange = () => {\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)\n }\n mql.addEventListener(\"change\", onChange)\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)\n return () => mql.removeEventListener(\"change\", onChange)\n }, [])\n\n return !!isMobile\n}\n"
|
|
1237
|
+
}
|
|
1238
|
+
]
|
|
1239
|
+
},
|
|
1240
|
+
{
|
|
1241
|
+
"name": "dashboard-01",
|
|
1242
|
+
"type": "components:block",
|
|
1243
|
+
"frameworks": [
|
|
1244
|
+
"react",
|
|
1245
|
+
"nextjs",
|
|
1246
|
+
"vue",
|
|
1247
|
+
"nuxt",
|
|
1248
|
+
"solid",
|
|
1249
|
+
"svelte",
|
|
1250
|
+
"astro",
|
|
1251
|
+
"remix"
|
|
1252
|
+
],
|
|
1253
|
+
"dependencies": [
|
|
1254
|
+
"@base-ui/react",
|
|
1255
|
+
"lucide-react"
|
|
1256
|
+
],
|
|
1257
|
+
"registryDependencies": [
|
|
1258
|
+
"sidebar",
|
|
1259
|
+
"card",
|
|
1260
|
+
"button",
|
|
1261
|
+
"avatar"
|
|
1262
|
+
],
|
|
1263
|
+
"files": [
|
|
1264
|
+
{
|
|
1265
|
+
"name": "blocks/dashboard-01.tsx",
|
|
1266
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nexport function Dashboard01() {\n return (\n <div className=\"flex min-h-screen\">\n <aside className=\"w-64 border-r border-border bg-background p-4\">\n <div className=\"text-lg font-bold text-foreground mb-8\">Static UI</div>\n <nav className=\"space-y-1\">\n {[\"Overview\", \"Analytics\", \"Customers\", \"Settings\"].map((item) => (\n <a key={item} href=\"#\" className=\"block rounded-md px-3 py-2 text-sm font-medium text-muted-foreground hover:bg-accent hover:text-accent-foreground transition-colors\">{item}</a>\n ))}\n </nav>\n </aside>\n <main className=\"flex-1 p-6\">\n <header className=\"mb-6\">\n <h1 className=\"text-2xl font-bold text-foreground\">Dashboard</h1>\n <p className=\"text-sm text-muted-foreground\">Welcome back, here is your overview.</p>\n </header>\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4 mb-6\">\n {[\n { label: \"Total Revenue\", value: \"$45,231\", change: \"+20.1%\" },\n { label: \"Active Users\", value: \"2,350\", change: \"+180.1%\" },\n { label: \"Sales\", value: \"12,234\", change: \"+19%\" },\n ].map((stat) => (\n <div key={stat.label} className=\"rounded-xl border border-border bg-card p-4 text-card-foreground shadow-xs\">\n <p className=\"text-sm text-muted-foreground\">{stat.label}</p>\n <p className=\"text-2xl font-bold text-foreground\">{stat.value}</p>\n <p className=\"text-xs text-green-500\">{stat.change}</p>\n </div>\n ))}\n </div>\n </main>\n </div>\n )\n}\n"
|
|
1267
|
+
}
|
|
1268
|
+
]
|
|
1269
|
+
},
|
|
1270
|
+
{
|
|
1271
|
+
"name": "dashboard-02",
|
|
1272
|
+
"type": "components:block",
|
|
1273
|
+
"frameworks": [
|
|
1274
|
+
"react",
|
|
1275
|
+
"nextjs",
|
|
1276
|
+
"vue",
|
|
1277
|
+
"nuxt",
|
|
1278
|
+
"solid",
|
|
1279
|
+
"svelte",
|
|
1280
|
+
"astro",
|
|
1281
|
+
"remix"
|
|
1282
|
+
],
|
|
1283
|
+
"dependencies": [
|
|
1284
|
+
"@base-ui/react",
|
|
1285
|
+
"lucide-react"
|
|
1286
|
+
],
|
|
1287
|
+
"registryDependencies": [
|
|
1288
|
+
"sidebar",
|
|
1289
|
+
"card",
|
|
1290
|
+
"tabs",
|
|
1291
|
+
"select",
|
|
1292
|
+
"button"
|
|
1293
|
+
],
|
|
1294
|
+
"files": [
|
|
1295
|
+
{
|
|
1296
|
+
"name": "blocks/dashboard-02.tsx",
|
|
1297
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nexport function Dashboard02() {\n return (\n <div className=\"flex min-h-screen\">\n <aside className=\"w-64 border-r border-border bg-background p-4\">\n <div className=\"text-lg font-bold text-foreground mb-8\">Static UI</div>\n <nav className=\"space-y-1\">\n {[\"Overview\", \"Analytics\", \"Reports\", \"Settings\"].map((item) => (\n <a key={item} href=\"#\" className=\"block rounded-md px-3 py-2 text-sm font-medium text-muted-foreground hover:bg-accent hover:text-accent-foreground transition-colors\">{item}</a>\n ))}\n </nav>\n </aside>\n <main className=\"flex-1 p-6\">\n <header className=\"flex items-center justify-between mb-6\">\n <div>\n <h1 className=\"text-2xl font-bold text-foreground\">Analytics</h1>\n <p className=\"text-sm text-muted-foreground\">Track your performance metrics.</p>\n </div>\n <select className=\"h-9 rounded-md border border-border bg-background px-3 text-sm text-foreground\">\n <option>Last 7 days</option>\n <option>Last 30 days</option>\n <option>Last 90 days</option>\n </select>\n </header>\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-4 mb-6\">\n <div className=\"rounded-xl border border-border bg-card p-4 text-card-foreground shadow-xs\">\n <p className=\"text-sm text-muted-foreground mb-2\">Page Views</p>\n <p className=\"text-3xl font-bold text-foreground\">54,321</p>\n <div className=\"mt-4 h-32 flex items-end gap-2\">\n {[40, 65, 45, 80, 55, 90, 70].map((h, i) => (\n <div key={i} className=\"flex-1 bg-primary/20 rounded-t-sm\" style={{ height: `${h}%` }} />\n ))}\n </div>\n </div>\n <div className=\"rounded-xl border border-border bg-card p-4 text-card-foreground shadow-xs\">\n <p className=\"text-sm text-muted-foreground mb-2\">Conversion Rate</p>\n <p className=\"text-3xl font-bold text-foreground\">3.24%</p>\n <div className=\"mt-4 h-32 flex items-end gap-2\">\n {[30, 50, 35, 60, 45, 70, 55].map((h, i) => (\n <div key={i} className=\"flex-1 bg-green-500/20 rounded-t-sm\" style={{ height: `${h}%` }} />\n ))}\n </div>\n </div>\n </div>\n </main>\n </div>\n )\n}\n"
|
|
1298
|
+
}
|
|
1299
|
+
]
|
|
1300
|
+
},
|
|
1301
|
+
{
|
|
1302
|
+
"name": "feature-01",
|
|
1303
|
+
"type": "components:block",
|
|
1304
|
+
"frameworks": [
|
|
1305
|
+
"react",
|
|
1306
|
+
"nextjs",
|
|
1307
|
+
"vue",
|
|
1308
|
+
"nuxt",
|
|
1309
|
+
"solid",
|
|
1310
|
+
"svelte",
|
|
1311
|
+
"astro",
|
|
1312
|
+
"remix"
|
|
1313
|
+
],
|
|
1314
|
+
"dependencies": [
|
|
1315
|
+
"@base-ui/react",
|
|
1316
|
+
"lucide-react"
|
|
1317
|
+
],
|
|
1318
|
+
"registryDependencies": [
|
|
1319
|
+
"card"
|
|
1320
|
+
],
|
|
1321
|
+
"files": [
|
|
1322
|
+
{
|
|
1323
|
+
"name": "blocks/feature-01.tsx",
|
|
1324
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nexport function Feature01() {\n const features = [\n { title: \"Accessible\", description: \"Built on Base UI with full ARIA support and keyboard navigation out of the box.\" },\n { title: \"Customizable\", description: \"Style with Tailwind CSS v4 classes. No opinionated themes to override.\" },\n { title: \"Lightweight\", description: \"Copy what you need. Zero unnecessary dependencies in your bundle.\" },\n ]\n return (\n <section className=\"py-16 px-4 bg-muted/30\">\n <div className=\"max-w-4xl mx-auto\">\n <div className=\"text-center mb-10\">\n <h2 className=\"text-3xl font-bold text-foreground\">Why Static UI?</h2>\n <p className=\"text-muted-foreground mt-2\">Everything you need to build modern interfaces</p>\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-6\">\n {features.map((f) => (\n <div key={f.title} className=\"rounded-xl border border-border bg-card p-6 text-card-foreground shadow-xs\">\n <h3 className=\"font-semibold text-foreground\">{f.title}</h3>\n <p className=\"mt-2 text-sm text-muted-foreground\">{f.description}</p>\n </div>\n ))}\n </div>\n </div>\n </section>\n )\n}\n"
|
|
1325
|
+
}
|
|
1326
|
+
]
|
|
1327
|
+
},
|
|
1328
|
+
{
|
|
1329
|
+
"name": "feature-02",
|
|
1330
|
+
"type": "components:block",
|
|
1331
|
+
"frameworks": [
|
|
1332
|
+
"react",
|
|
1333
|
+
"nextjs",
|
|
1334
|
+
"vue",
|
|
1335
|
+
"nuxt",
|
|
1336
|
+
"solid",
|
|
1337
|
+
"svelte",
|
|
1338
|
+
"astro",
|
|
1339
|
+
"remix"
|
|
1340
|
+
],
|
|
1341
|
+
"dependencies": [
|
|
1342
|
+
"@base-ui/react",
|
|
1343
|
+
"lucide-react"
|
|
1344
|
+
],
|
|
1345
|
+
"registryDependencies": [
|
|
1346
|
+
"card"
|
|
1347
|
+
],
|
|
1348
|
+
"files": [
|
|
1349
|
+
{
|
|
1350
|
+
"name": "blocks/feature-02.tsx",
|
|
1351
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nexport function Feature02() {\n const features = [\n { title: \"Seamless integration\", description: \"Drop into any Next.js, Vite, or Remix project. No build tool configuration needed.\" },\n { title: \"Consistent design\", description: \"Every component uses the same Tailwind CSS variable tokens for a unified look.\" },\n { title: \"Community driven\", description: \"Open source and free. Contributions, issues, and feedback are always welcome.\" },\n ]\n return (\n <section className=\"py-16 px-4\">\n <div className=\"max-w-4xl mx-auto space-y-12\">\n {features.map((f, i) => (\n <div key={f.title} className={`flex flex-col ${i % 2 === 0 ? \"md:flex-row\" : \"md:flex-row-reverse\"} gap-6 items-center`}>\n <div className=\"flex-1\">\n <h3 className=\"text-xl font-semibold text-foreground\">{f.title}</h3>\n <p className=\"mt-2 text-muted-foreground\">{f.description}</p>\n </div>\n <div className=\"flex-1 rounded-xl border border-border bg-card p-8 text-card-foreground shadow-xs aspect-video flex items-center justify-center\">\n <p className=\"text-muted-foreground text-sm\">Illustration</p>\n </div>\n </div>\n ))}\n </div>\n </section>\n )\n}\n"
|
|
1352
|
+
}
|
|
1353
|
+
]
|
|
1354
|
+
},
|
|
1355
|
+
{
|
|
1356
|
+
"name": "hero-01",
|
|
1357
|
+
"type": "components:block",
|
|
1358
|
+
"frameworks": [
|
|
1359
|
+
"react",
|
|
1360
|
+
"nextjs",
|
|
1361
|
+
"vue",
|
|
1362
|
+
"nuxt",
|
|
1363
|
+
"solid",
|
|
1364
|
+
"svelte",
|
|
1365
|
+
"astro",
|
|
1366
|
+
"remix"
|
|
1367
|
+
],
|
|
1368
|
+
"dependencies": [
|
|
1369
|
+
"@base-ui/react",
|
|
1370
|
+
"lucide-react"
|
|
1371
|
+
],
|
|
1372
|
+
"registryDependencies": [
|
|
1373
|
+
"button",
|
|
1374
|
+
"badge"
|
|
1375
|
+
],
|
|
1376
|
+
"files": [
|
|
1377
|
+
{
|
|
1378
|
+
"name": "blocks/hero-01.tsx",
|
|
1379
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nexport function Hero01() {\n return (\n <section className=\"py-24 px-4 text-center\">\n <div className=\"max-w-2xl mx-auto\">\n <span className=\"inline-flex items-center rounded-full border border-border bg-background px-2.5 py-0.5 text-xs font-semibold text-foreground mb-4\">New release v2.0</span>\n <h1 className=\"text-4xl font-bold tracking-tight text-foreground sm:text-5xl\">Build beautiful interfaces with Static UI</h1>\n <p className=\"mt-4 text-lg text-muted-foreground\">A modern component library built on Base UI and Tailwind CSS v4. Open source and ready to use.</p>\n <div className=\"mt-8 flex items-center justify-center gap-4\">\n <button className=\"inline-flex h-10 items-center justify-center rounded-md bg-primary px-6 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors\">Get started</button>\n <button className=\"inline-flex h-10 items-center justify-center rounded-md border border-border bg-background px-6 py-2 text-sm font-medium text-foreground hover:bg-muted transition-colors\">Learn more</button>\n </div>\n </div>\n </section>\n )\n}\n"
|
|
1380
|
+
}
|
|
1381
|
+
]
|
|
1382
|
+
},
|
|
1383
|
+
{
|
|
1384
|
+
"name": "hero-02",
|
|
1385
|
+
"type": "components:block",
|
|
1386
|
+
"frameworks": [
|
|
1387
|
+
"react",
|
|
1388
|
+
"nextjs",
|
|
1389
|
+
"vue",
|
|
1390
|
+
"nuxt",
|
|
1391
|
+
"solid",
|
|
1392
|
+
"svelte",
|
|
1393
|
+
"astro",
|
|
1394
|
+
"remix"
|
|
1395
|
+
],
|
|
1396
|
+
"dependencies": [
|
|
1397
|
+
"@base-ui/react",
|
|
1398
|
+
"lucide-react"
|
|
1399
|
+
],
|
|
1400
|
+
"registryDependencies": [
|
|
1401
|
+
"button",
|
|
1402
|
+
"badge"
|
|
1403
|
+
],
|
|
1404
|
+
"files": [
|
|
1405
|
+
{
|
|
1406
|
+
"name": "blocks/hero-02.tsx",
|
|
1407
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nexport function Hero02() {\n return (\n <section className=\"py-16 px-4\">\n <div className=\"max-w-5xl mx-auto grid md:grid-cols-2 gap-8 items-center\">\n <div>\n <span className=\"inline-flex items-center rounded-full border border-border bg-background px-2.5 py-0.5 text-xs font-semibold text-foreground mb-4\">Featured</span>\n <h1 className=\"text-3xl font-bold tracking-tight text-foreground sm:text-4xl\">Design faster with pre-built components</h1>\n <p className=\"mt-4 text-muted-foreground\">Stop writing repetitive UI code. Static UI gives you accessible, customizable components that you can copy and paste into your projects.</p>\n <div className=\"mt-6 flex gap-3\">\n <button className=\"inline-flex h-10 items-center justify-center rounded-md bg-primary px-6 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors\">Browse components</button>\n <button className=\"inline-flex h-10 items-center justify-center rounded-md border border-border bg-background px-6 py-2 text-sm font-medium text-foreground hover:bg-muted transition-colors\">View on GitHub</button>\n </div>\n </div>\n <div className=\"rounded-xl border border-border bg-card p-8 text-card-foreground shadow-xs aspect-[4/3] flex items-center justify-center\">\n <p className=\"text-muted-foreground\">Preview</p>\n </div>\n </div>\n </section>\n )\n}\n"
|
|
1408
|
+
}
|
|
1409
|
+
]
|
|
1410
|
+
},
|
|
1411
|
+
{
|
|
1412
|
+
"name": "login-01",
|
|
1413
|
+
"type": "components:block",
|
|
1414
|
+
"frameworks": [
|
|
1415
|
+
"react",
|
|
1416
|
+
"nextjs",
|
|
1417
|
+
"vue",
|
|
1418
|
+
"nuxt",
|
|
1419
|
+
"solid",
|
|
1420
|
+
"svelte",
|
|
1421
|
+
"astro",
|
|
1422
|
+
"remix"
|
|
1423
|
+
],
|
|
1424
|
+
"dependencies": [
|
|
1425
|
+
"@base-ui/react",
|
|
1426
|
+
"lucide-react"
|
|
1427
|
+
],
|
|
1428
|
+
"registryDependencies": [
|
|
1429
|
+
"button",
|
|
1430
|
+
"input",
|
|
1431
|
+
"label",
|
|
1432
|
+
"card"
|
|
1433
|
+
],
|
|
1434
|
+
"files": [
|
|
1435
|
+
{
|
|
1436
|
+
"name": "blocks/login-01.tsx",
|
|
1437
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nexport function Login01() {\n return (\n <div className=\"flex min-h-screen items-center justify-center bg-muted/50 p-4\">\n <div className=\"w-full max-w-sm rounded-xl border border-border bg-card p-6 text-card-foreground shadow-xs\">\n <div className=\"text-center mb-6\">\n <h1 className=\"text-2xl font-bold text-foreground\">Welcome back</h1>\n <p className=\"text-sm text-muted-foreground\">Sign in to your account</p>\n </div>\n <form onSubmit={(e) => e.preventDefault()} className=\"space-y-4\">\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium text-foreground\">Email</label>\n <input type=\"email\" placeholder=\"m@example.com\" className=\"flex h-10 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground shadow-xs\" />\n </div>\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium text-foreground\">Password</label>\n <input type=\"password\" placeholder=\"Enter your password\" className=\"flex h-10 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground shadow-xs\" />\n </div>\n <button type=\"submit\" className=\"inline-flex h-10 w-full items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors\">Sign in</button>\n </form>\n </div>\n </div>\n )\n}\n"
|
|
1438
|
+
}
|
|
1439
|
+
]
|
|
1440
|
+
},
|
|
1441
|
+
{
|
|
1442
|
+
"name": "login-02",
|
|
1443
|
+
"type": "components:block",
|
|
1444
|
+
"frameworks": [
|
|
1445
|
+
"react",
|
|
1446
|
+
"nextjs",
|
|
1447
|
+
"vue",
|
|
1448
|
+
"nuxt",
|
|
1449
|
+
"solid",
|
|
1450
|
+
"svelte",
|
|
1451
|
+
"astro",
|
|
1452
|
+
"remix"
|
|
1453
|
+
],
|
|
1454
|
+
"dependencies": [
|
|
1455
|
+
"@base-ui/react",
|
|
1456
|
+
"lucide-react"
|
|
1457
|
+
],
|
|
1458
|
+
"registryDependencies": [
|
|
1459
|
+
"button",
|
|
1460
|
+
"input",
|
|
1461
|
+
"label",
|
|
1462
|
+
"card",
|
|
1463
|
+
"separator"
|
|
1464
|
+
],
|
|
1465
|
+
"files": [
|
|
1466
|
+
{
|
|
1467
|
+
"name": "blocks/login-02.tsx",
|
|
1468
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nexport function Login02() {\n return (\n <div className=\"flex min-h-screen items-center justify-center bg-muted/50 p-4\">\n <div className=\"w-full max-w-sm rounded-xl border border-border bg-card p-6 text-card-foreground shadow-xs\">\n <div className=\"text-center mb-6\">\n <h1 className=\"text-2xl font-bold text-foreground\">Create an account</h1>\n <p className=\"text-sm text-muted-foreground\">Choose your sign up method</p>\n </div>\n <div className=\"space-y-3\">\n <button className=\"inline-flex h-10 w-full items-center justify-center rounded-md border border-border bg-background px-4 py-2 text-sm font-medium text-foreground hover:bg-muted transition-colors\">\n <svg className=\"w-4 h-4 mr-2\" viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 0 1-2.2 3.32v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.1z\"/><path fill=\"currentColor\" d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"/><path fill=\"currentColor\" d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"/><path fill=\"currentColor\" d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"/></svg>\n Continue with Google\n </button>\n <button className=\"inline-flex h-10 w-full items-center justify-center rounded-md border border-border bg-background px-4 py-2 text-sm font-medium text-foreground hover:bg-muted transition-colors\">\n <svg className=\"w-4 h-4 mr-2\" viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M12 0C5.37 0 0 5.37 0 12c0 5.3 3.44 9.8 8.2 11.39.6.11.82-.26.82-.58v-2.05c-3.34.72-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.09-.74.08-.73.08-.73 1.2.09 1.84 1.24 1.84 1.24 1.07 1.84 2.81 1.31 3.5 1 .1-.77.42-1.31.76-1.61-2.66-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.14-.3-.54-1.52.1-3.18 0 0 1-.33 3.3 1.23.96-.27 2-.4 3.02-.4s2.06.13 3.02.4c2.3-1.56 3.3-1.23 3.3-1.23.64 1.66.24 2.88.12 3.18.77.84 1.24 1.91 1.24 3.22 0 4.61-2.8 5.63-5.48 5.92.42.36.81 1.09.81 2.2v3.27c0 .32.22.7.83.58C20.56 21.8 24 17.3 24 12 24 5.37 18.63 0 12 0z\"/></svg>\n Continue with GitHub\n </button>\n <div className=\"relative my-4\">\n <div className=\"absolute inset-0 flex items-center\"><span className=\"w-full border-t border-border\" /></div>\n <div className=\"relative flex justify-center text-xs\"><span className=\"bg-card px-2 text-muted-foreground\">or</span></div>\n </div>\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium text-foreground\">Email</label>\n <input type=\"email\" placeholder=\"m@example.com\" className=\"flex h-10 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground shadow-xs\" />\n </div>\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium text-foreground\">Password</label>\n <input type=\"password\" placeholder=\"Create a password\" className=\"flex h-10 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground shadow-xs\" />\n </div>\n <button type=\"submit\" className=\"inline-flex h-10 w-full items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors\">Create account</button>\n </div>\n </div>\n </div>\n )\n}\n"
|
|
1469
|
+
}
|
|
1470
|
+
]
|
|
1471
|
+
},
|
|
1472
|
+
{
|
|
1473
|
+
"name": "pricing-01",
|
|
1474
|
+
"type": "components:block",
|
|
1475
|
+
"frameworks": [
|
|
1476
|
+
"react",
|
|
1477
|
+
"nextjs",
|
|
1478
|
+
"vue",
|
|
1479
|
+
"nuxt",
|
|
1480
|
+
"solid",
|
|
1481
|
+
"svelte",
|
|
1482
|
+
"astro",
|
|
1483
|
+
"remix"
|
|
1484
|
+
],
|
|
1485
|
+
"dependencies": [
|
|
1486
|
+
"@base-ui/react",
|
|
1487
|
+
"lucide-react"
|
|
1488
|
+
],
|
|
1489
|
+
"registryDependencies": [
|
|
1490
|
+
"card",
|
|
1491
|
+
"button",
|
|
1492
|
+
"badge"
|
|
1493
|
+
],
|
|
1494
|
+
"files": [
|
|
1495
|
+
{
|
|
1496
|
+
"name": "blocks/pricing-01.tsx",
|
|
1497
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nexport function Pricing01() {\n const tiers = [\n { name: \"Starter\", price: \"$9\", description: \"Perfect for getting started\", popular: false },\n { name: \"Pro\", price: \"$29\", description: \"Best for growing teams\", popular: true },\n { name: \"Enterprise\", price: \"$99\", description: \"For large organizations\", popular: false },\n ]\n return (\n <section className=\"py-16 px-4\">\n <div className=\"text-center mb-10\">\n <h2 className=\"text-3xl font-bold text-foreground\">Simple pricing</h2>\n <p className=\"text-muted-foreground mt-2\">Choose the plan that fits your needs</p>\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-6 max-w-4xl mx-auto\">\n {tiers.map((tier) => (\n <div key={tier.name} className={`rounded-xl border ${tier.popular ? \"border-primary\" : \"border-border\"} bg-card p-6 text-card-foreground shadow-xs relative`}>\n {tier.popular && <span className=\"absolute -top-2.5 left-1/2 -translate-x-1/2 inline-flex items-center rounded-full border border-border bg-background px-2.5 py-0.5 text-xs font-semibold text-foreground\">Most Popular</span>}\n <h3 className=\"text-lg font-semibold text-foreground\">{tier.name}</h3>\n <p className=\"text-sm text-muted-foreground mt-1\">{tier.description}</p>\n <p className=\"mt-4\"><span className=\"text-4xl font-bold text-foreground\">{tier.price}</span><span className=\"text-sm text-muted-foreground\">/month</span></p>\n <button className=\"mt-6 inline-flex h-10 w-full items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors\">Get started</button>\n </div>\n ))}\n </div>\n </section>\n )\n}\n"
|
|
1498
|
+
}
|
|
1499
|
+
]
|
|
1500
|
+
},
|
|
1501
|
+
{
|
|
1502
|
+
"name": "pricing-02",
|
|
1503
|
+
"type": "components:block",
|
|
1504
|
+
"frameworks": [
|
|
1505
|
+
"react",
|
|
1506
|
+
"nextjs",
|
|
1507
|
+
"vue",
|
|
1508
|
+
"nuxt",
|
|
1509
|
+
"solid",
|
|
1510
|
+
"svelte",
|
|
1511
|
+
"astro",
|
|
1512
|
+
"remix"
|
|
1513
|
+
],
|
|
1514
|
+
"dependencies": [
|
|
1515
|
+
"@base-ui/react",
|
|
1516
|
+
"lucide-react"
|
|
1517
|
+
],
|
|
1518
|
+
"registryDependencies": [
|
|
1519
|
+
"card",
|
|
1520
|
+
"button",
|
|
1521
|
+
"badge",
|
|
1522
|
+
"table"
|
|
1523
|
+
],
|
|
1524
|
+
"files": [
|
|
1525
|
+
{
|
|
1526
|
+
"name": "blocks/pricing-02.tsx",
|
|
1527
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nexport function Pricing02() {\n const features = [\"Unlimited projects\", \"Team collaboration\", \"API access\", \"Priority support\", \"Custom domains\", \"Analytics dashboard\"]\n const plans = [\n { name: \"Free\", price: \"$0\", features: [true, true, false, false, false, false] },\n { name: \"Pro\", price: \"$29\", features: [true, true, true, true, false, false] },\n { name: \"Business\", price: \"$79\", features: [true, true, true, true, true, true] },\n ]\n return (\n <section className=\"py-16 px-4\">\n <div className=\"text-center mb-10\">\n <h2 className=\"text-3xl font-bold text-foreground\">Compare plans</h2>\n <p className=\"text-muted-foreground mt-2\">Find the right plan for your team</p>\n </div>\n <div className=\"overflow-x-auto max-w-4xl mx-auto\">\n <table className=\"w-full border-collapse\">\n <thead>\n <tr className=\"border-b border-border\">\n <th className=\"text-left py-3 px-4 text-sm font-medium text-muted-foreground\">Feature</th>\n {plans.map((p) => <th key={p.name} className=\"py-3 px-4 text-sm font-semibold text-foreground text-center\">{p.name}<div className=\"text-lg font-bold\">{p.price}<span className=\"text-xs font-normal text-muted-foreground\">/mo</span></div></th>)}\n </tr>\n </thead>\n <tbody>\n {features.map((feature, idx) => (\n <tr key={feature} className=\"border-b border-border\">\n <td className=\"py-3 px-4 text-sm text-foreground\">{feature}</td>\n {plans.map((p) => (\n <td key={p.name} className=\"py-3 px-4 text-center\">\n {p.features[idx] ? <svg className=\"w-4 h-4 mx-auto text-green-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth=\"3\"><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\" /></svg> : <svg className=\"w-4 h-4 mx-auto text-muted-foreground/40\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth=\"2\"><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" /></svg>}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </section>\n )\n}\n"
|
|
1528
|
+
}
|
|
1529
|
+
]
|
|
1530
|
+
},
|
|
1531
|
+
{
|
|
1532
|
+
"name": "auth",
|
|
1533
|
+
"type": "components:template",
|
|
1534
|
+
"frameworks": [
|
|
1535
|
+
"react",
|
|
1536
|
+
"nextjs",
|
|
1537
|
+
"vue",
|
|
1538
|
+
"nuxt",
|
|
1539
|
+
"solid",
|
|
1540
|
+
"svelte",
|
|
1541
|
+
"astro",
|
|
1542
|
+
"remix"
|
|
1543
|
+
],
|
|
1544
|
+
"dependencies": [
|
|
1545
|
+
"@base-ui/react",
|
|
1546
|
+
"lucide-react",
|
|
1547
|
+
"next"
|
|
1548
|
+
],
|
|
1549
|
+
"registryDependencies": [
|
|
1550
|
+
"login-01",
|
|
1551
|
+
"login-02"
|
|
1552
|
+
],
|
|
1553
|
+
"files": [
|
|
1554
|
+
{
|
|
1555
|
+
"name": "templates/auth.tsx",
|
|
1556
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nexport function AuthPage() {\n const [mode, setMode] = React.useState<\"login\" | \"register\">(\"login\")\n return (\n <div className=\"flex min-h-screen items-center justify-center bg-muted/50 p-4\">\n <div className=\"w-full max-w-sm rounded-xl border border-border bg-card p-6 text-card-foreground shadow-xs\">\n <div className=\"flex mb-6 rounded-md border border-border p-1 bg-muted/50\">\n <button onClick={() => setMode(\"login\")} className={`flex-1 rounded-md px-3 py-1.5 text-sm font-medium transition-colors ${mode === \"login\" ? \"bg-background text-foreground shadow-xs\" : \"text-muted-foreground hover:text-foreground\"}`}>Sign in</button>\n <button onClick={() => setMode(\"register\")} className={`flex-1 rounded-md px-3 py-1.5 text-sm font-medium transition-colors ${mode === \"register\" ? \"bg-background text-foreground shadow-xs\" : \"text-muted-foreground hover:text-foreground\"}`}>Register</button>\n </div>\n {mode === \"login\" ? (\n <form onSubmit={(e) => e.preventDefault()} className=\"space-y-4\">\n <div className=\"text-center mb-2\">\n <h1 className=\"text-xl font-bold text-foreground\">Welcome back</h1>\n <p className=\"text-sm text-muted-foreground\">Sign in to your account</p>\n </div>\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium text-foreground\">Email</label>\n <input type=\"email\" placeholder=\"m@example.com\" className=\"flex h-10 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground shadow-xs\" />\n </div>\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium text-foreground\">Password</label>\n <input type=\"password\" placeholder=\"Enter your password\" className=\"flex h-10 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground shadow-xs\" />\n </div>\n <button type=\"submit\" className=\"inline-flex h-10 w-full items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors\">Sign in</button>\n </form>\n ) : (\n <form onSubmit={(e) => e.preventDefault()} className=\"space-y-4\">\n <div className=\"text-center mb-2\">\n <h1 className=\"text-xl font-bold text-foreground\">Create account</h1>\n <p className=\"text-sm text-muted-foreground\">Enter your details to get started</p>\n </div>\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium text-foreground\">Name</label>\n <input type=\"text\" placeholder=\"John Doe\" className=\"flex h-10 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground shadow-xs\" />\n </div>\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium text-foreground\">Email</label>\n <input type=\"email\" placeholder=\"m@example.com\" className=\"flex h-10 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground shadow-xs\" />\n </div>\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium text-foreground\">Password</label>\n <input type=\"password\" placeholder=\"Create a password\" className=\"flex h-10 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground shadow-xs\" />\n </div>\n <button type=\"submit\" className=\"inline-flex h-10 w-full items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors\">Create account</button>\n </form>\n )}\n </div>\n </div>\n )\n}\n"
|
|
1557
|
+
}
|
|
1558
|
+
]
|
|
1559
|
+
},
|
|
1560
|
+
{
|
|
1561
|
+
"name": "dashboard",
|
|
1562
|
+
"type": "components:template",
|
|
1563
|
+
"frameworks": [
|
|
1564
|
+
"react",
|
|
1565
|
+
"nextjs",
|
|
1566
|
+
"vue",
|
|
1567
|
+
"nuxt",
|
|
1568
|
+
"solid",
|
|
1569
|
+
"svelte",
|
|
1570
|
+
"astro",
|
|
1571
|
+
"remix"
|
|
1572
|
+
],
|
|
1573
|
+
"dependencies": [
|
|
1574
|
+
"@base-ui/react",
|
|
1575
|
+
"lucide-react",
|
|
1576
|
+
"next"
|
|
1577
|
+
],
|
|
1578
|
+
"registryDependencies": [
|
|
1579
|
+
"dashboard-01",
|
|
1580
|
+
"sidebar",
|
|
1581
|
+
"button",
|
|
1582
|
+
"card"
|
|
1583
|
+
],
|
|
1584
|
+
"files": [
|
|
1585
|
+
{
|
|
1586
|
+
"name": "templates/dashboard.tsx",
|
|
1587
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nexport function DashboardPage() {\n return (\n <div className=\"flex min-h-screen bg-muted/50\">\n <aside className=\"w-64 border-r border-border bg-background p-4\">\n <div className=\"text-lg font-bold text-foreground mb-8\">Static UI</div>\n <nav className=\"space-y-1\">\n {[\"Overview\", \"Analytics\", \"Customers\", \"Settings\"].map((item) => (\n <a key={item} href=\"#\" className=\"block rounded-md px-3 py-2 text-sm font-medium text-muted-foreground hover:bg-accent hover:text-accent-foreground transition-colors\">{item}</a>\n ))}\n </nav>\n </aside>\n <main className=\"flex-1 p-6\">\n <header className=\"mb-6\">\n <h1 className=\"text-2xl font-bold text-foreground\">Dashboard</h1>\n <p className=\"text-sm text-muted-foreground\">Welcome back, here is your overview.</p>\n </header>\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4 mb-6\">\n {[\n { label: \"Total Revenue\", value: \"$45,231\", change: \"+20.1%\" },\n { label: \"Active Users\", value: \"2,350\", change: \"+180.1%\" },\n { label: \"Sales\", value: \"12,234\", change: \"+19%\" },\n ].map((stat) => (\n <div key={stat.label} className=\"rounded-xl border border-border bg-card p-4 text-card-foreground shadow-xs\">\n <p className=\"text-sm text-muted-foreground\">{stat.label}</p>\n <p className=\"text-2xl font-bold text-foreground\">{stat.value}</p>\n <p className=\"text-xs text-green-500\">{stat.change}</p>\n </div>\n ))}\n </div>\n <div className=\"rounded-xl border border-border bg-card p-4 text-card-foreground shadow-xs\">\n <p className=\"text-sm text-muted-foreground mb-2\">Recent Activity</p>\n <div className=\"text-sm text-foreground\">No recent activity to show.</div>\n </div>\n </main>\n </div>\n )\n}\n"
|
|
1588
|
+
}
|
|
1589
|
+
]
|
|
1590
|
+
},
|
|
1591
|
+
{
|
|
1592
|
+
"name": "marketing",
|
|
1593
|
+
"type": "components:template",
|
|
1594
|
+
"frameworks": [
|
|
1595
|
+
"react",
|
|
1596
|
+
"nextjs",
|
|
1597
|
+
"vue",
|
|
1598
|
+
"nuxt",
|
|
1599
|
+
"solid",
|
|
1600
|
+
"svelte",
|
|
1601
|
+
"astro",
|
|
1602
|
+
"remix"
|
|
1603
|
+
],
|
|
1604
|
+
"dependencies": [
|
|
1605
|
+
"@base-ui/react",
|
|
1606
|
+
"lucide-react",
|
|
1607
|
+
"next"
|
|
1608
|
+
],
|
|
1609
|
+
"registryDependencies": [
|
|
1610
|
+
"hero-01",
|
|
1611
|
+
"feature-01",
|
|
1612
|
+
"pricing-01",
|
|
1613
|
+
"button"
|
|
1614
|
+
],
|
|
1615
|
+
"files": [
|
|
1616
|
+
{
|
|
1617
|
+
"name": "templates/marketing.tsx",
|
|
1618
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nexport function MarketingPage() {\n return (\n <div className=\"flex min-h-screen flex-col bg-background text-foreground\">\n <header className=\"border-b border-border\">\n <div className=\"max-w-5xl mx-auto flex h-14 items-center justify-between px-4\">\n <span className=\"text-lg font-bold\">Static UI</span>\n <nav className=\"hidden md:flex items-center gap-6 text-sm font-medium text-muted-foreground\">\n <a href=\"#\" className=\"hover:text-foreground transition-colors\">Features</a>\n <a href=\"#\" className=\"hover:text-foreground transition-colors\">Pricing</a>\n <a href=\"#\" className=\"hover:text-foreground transition-colors\">Docs</a>\n </nav>\n <button className=\"inline-flex h-9 items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors\">Get started</button>\n </div>\n </header>\n <main className=\"flex-1\">\n <section className=\"py-24 px-4 text-center\">\n <div className=\"max-w-2xl mx-auto\">\n <span className=\"inline-flex items-center rounded-full border border-border bg-background px-2.5 py-0.5 text-xs font-semibold text-foreground mb-4\">New release v2.0</span>\n <h1 className=\"text-4xl font-bold tracking-tight sm:text-5xl\">Build beautiful interfaces with Static UI</h1>\n <p className=\"mt-4 text-lg text-muted-foreground\">A modern component library built on Base UI and Tailwind CSS v4.</p>\n <div className=\"mt-8 flex items-center justify-center gap-4\">\n <button className=\"inline-flex h-10 items-center justify-center rounded-md bg-primary px-6 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors\">Get started</button>\n <button className=\"inline-flex h-10 items-center justify-center rounded-md border border-border bg-background px-6 py-2 text-sm font-medium text-foreground hover:bg-muted transition-colors\">Learn more</button>\n </div>\n </div>\n </section>\n <section className=\"py-16 px-4 bg-muted/30\">\n <div className=\"max-w-4xl mx-auto\">\n <div className=\"text-center mb-10\">\n <h2 className=\"text-3xl font-bold\">Why Static UI?</h2>\n <p className=\"text-muted-foreground mt-2\">Everything you need to build modern interfaces</p>\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-6\">\n {[{ title: \"Accessible\", desc: \"Built on Base UI with full ARIA support.\" }, { title: \"Customizable\", desc: \"Style with Tailwind CSS v4. No themes to override.\" }, { title: \"Lightweight\", desc: \"Copy what you need. Zero unnecessary deps.\" }].map((f) => (\n <div key={f.title} className=\"rounded-xl border border-border bg-card p-6 text-card-foreground shadow-xs\">\n <h3 className=\"font-semibold\">{f.title}</h3>\n <p className=\"mt-2 text-sm text-muted-foreground\">{f.desc}</p>\n </div>\n ))}\n </div>\n </div>\n </section>\n <section className=\"py-16 px-4\">\n <div className=\"text-center mb-10\">\n <h2 className=\"text-3xl font-bold\">Simple pricing</h2>\n <p className=\"text-muted-foreground mt-2\">Choose the plan that fits your needs</p>\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-6 max-w-4xl mx-auto\">\n {[{ name: \"Starter\", price: \"$9\" }, { name: \"Pro\", price: \"$29\" }, { name: \"Enterprise\", price: \"$99\" }].map((tier) => (\n <div key={tier.name} className=\"rounded-xl border border-border bg-card p-6 text-card-foreground shadow-xs\">\n <h3 className=\"text-lg font-semibold\">{tier.name}</h3>\n <p className=\"mt-4\"><span className=\"text-4xl font-bold\">{tier.price}</span><span className=\"text-sm text-muted-foreground\">/month</span></p>\n <button className=\"mt-6 inline-flex h-10 w-full items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors\">Get started</button>\n </div>\n ))}\n </div>\n </section>\n </main>\n <footer className=\"border-t border-border py-6 text-center text-sm text-muted-foreground\">\n © 2026 Static UI. All rights reserved.\n </footer>\n </div>\n )\n}\n"
|
|
503
1619
|
}
|
|
504
1620
|
]
|
|
505
1621
|
}
|