drivn 1.12.0 → 1.13.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/README.md +45 -0
- package/dist/index.js +443 -30
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -92,6 +92,51 @@ export function ConfirmDialog() {
|
|
|
92
92
|
}
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
+
## MCP Server
|
|
96
|
+
|
|
97
|
+
Connect your AI assistant directly to the Drivn component registry via the [Model Context Protocol](https://modelcontextprotocol.io). Instead of copy-pasting component code into chat, your AI gets exact source code, design tokens, and coding conventions automatically.
|
|
98
|
+
|
|
99
|
+
### Claude Code
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
claude mcp add drivn -- npx drivn@latest mcp
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Cursor
|
|
106
|
+
|
|
107
|
+
```sh
|
|
108
|
+
npx @anthropic-ai/cursor-mcp-installer drivn -- npx drivn@latest mcp
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Manual configuration
|
|
112
|
+
|
|
113
|
+
For any MCP-compatible client, add the following to your config file:
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"mcpServers": {
|
|
118
|
+
"drivn": {
|
|
119
|
+
"command": "npx",
|
|
120
|
+
"args": ["drivn@latest", "mcp"]
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Available tools
|
|
127
|
+
|
|
128
|
+
| Tool | Description |
|
|
129
|
+
|---|---|
|
|
130
|
+
| `list_components` | List all available components with descriptions |
|
|
131
|
+
| `get_component` | Get full source code and metadata for a component |
|
|
132
|
+
| `get_component_metadata` | Get metadata only (no source) — useful for planning |
|
|
133
|
+
| `search_components` | Search components by name or description |
|
|
134
|
+
| `get_installation_instructions` | Get step-by-step install instructions with dependency resolution |
|
|
135
|
+
| `get_design_tokens` | Get CSS design tokens (globals and theme tokens) |
|
|
136
|
+
| `get_drivn_rules` | Get Drivn coding conventions and component patterns |
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
95
140
|
## License
|
|
96
141
|
|
|
97
142
|
Licensed under the [MIT License](./LICENSE.md).
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {Command}from'commander';import*as n from'@clack/prompts';import u from'picocolors';import {join,dirname}from'path';import {execSync}from'child_process';import {existsSync,readFileSync,writeFileSync,mkdirSync}from'fs';import {McpServer}from'@modelcontextprotocol/sdk/server/mcp.js';import {StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';import {z as z$1}from'zod';var
|
|
2
|
+
import {Command}from'commander';import*as n from'@clack/prompts';import u from'picocolors';import {join,dirname}from'path';import {execSync}from'child_process';import {existsSync,readFileSync,writeFileSync,mkdirSync}from'fs';import {McpServer}from'@modelcontextprotocol/sdk/server/mcp.js';import {StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';import {z as z$1}from'zod';var j={next:"Next.js",react:"React"};function V(e){let r=join(e,"package.json");if(!existsSync(r))throw new Error("package.json not found");let t=JSON.parse(readFileSync(r,"utf-8")),a={...t.dependencies,...t.devDependencies},l="react";a.next&&(l="next");let d=existsSync(join(e,"src")),p=existsSync(join(e,"tsconfig.json"));return {framework:l,srcDir:d,typescript:p}}var F="drivn.config.json";function U(e){let r=join(e,F);return existsSync(r)?JSON.parse(readFileSync(r,"utf-8")):null}function K(e,r){let t=join(e,F);writeFileSync(t,JSON.stringify(r,null,2));}function _e(e){existsSync(e)||mkdirSync(e,{recursive:true});}function b(e,r){_e(dirname(e)),writeFileSync(e,r);}function H(e){return readFileSync(e,"utf-8")}function x(e){return existsSync(e)}function E(e){return existsSync(join(e,"pnpm-lock.yaml"))?"pnpm":"npm"}function w(e,r){let t=r.join(" ");return e==="pnpm"?`pnpm add ${t}`:`npm install ${t}`}function Y(e){return e==="pnpm"?"pnpm dlx":"npx"}var C=`@import "tailwindcss";
|
|
3
3
|
|
|
4
4
|
:root {
|
|
5
5
|
/* Surfaces */
|
|
@@ -136,13 +136,13 @@ body {
|
|
|
136
136
|
/* Special Surfaces */
|
|
137
137
|
--overlay: hsl(0 0% 0% / 0.18);
|
|
138
138
|
}
|
|
139
|
-
`;var
|
|
139
|
+
`;var Ke=`import { type ClassValue, clsx } from 'clsx'
|
|
140
140
|
import { twMerge } from 'tailwind-merge'
|
|
141
141
|
|
|
142
142
|
export function cn(...inputs: ClassValue[]) {
|
|
143
143
|
return twMerge(clsx(inputs))
|
|
144
144
|
}
|
|
145
|
-
`,
|
|
145
|
+
`,Ye=["src/app/globals.css","src/styles/globals.css","src/styles/globals.scss","app/globals.css"];function We(e){for(let r of Ye)if(x(join(e,r)))return r;return null}async function W(){let e=process.cwd();console.log(""),console.log(u.bgCyan(u.bold(u.black(" Drivn "))));let r;try{r=V(e),n.log.success(`Detected ${u.cyan(j[r.framework])}`);}catch{n.log.error("No package.json found. Run this command in a project directory."),n.outro("Setup cancelled"),process.exit(1);}if(x(join(e,"drivn.config.json"))){let s=await n.confirm({message:"Config already exists. Overwrite?",initialValue:false});(n.isCancel(s)||!s)&&(n.cancel("Setup cancelled"),process.exit(0));}let t=r.srcDir?"src/components/ui":"components/ui",a=r.srcDir?"src/utils":"utils",l=await n.group({components:()=>n.text({message:"Where should components be installed?",placeholder:t,defaultValue:t}),utils:()=>n.text({message:"Where should utilities be placed?",placeholder:a,defaultValue:a})},{onCancel:()=>{n.cancel("Setup cancelled"),process.exit(0);}}),d={framework:r.framework,typescript:r.typescript,paths:{components:l.components,utils:l.utils},installed:[]},p=r.typescript?"ts":"js",f=join(e,l.utils,`cn.${p}`);x(f)||b(f,Ke);let g=We(e);if(g){let s=await n.confirm({message:`Found ${u.cyan(g)}. Add Drivn color tokens?`,initialValue:true});!n.isCancel(s)&&s&&(b(join(e,g),C),d.paths.globals=g,n.log.success(`Color tokens written to ${u.cyan(g)}`));}else {let s=r.srcDir?"src/styles/globals.css":"styles/globals.css",i=await n.text({message:"Where should the globals CSS file be created?",placeholder:s,defaultValue:s});n.isCancel(i)||(b(join(e,i),C),d.paths.globals=i,n.log.success(`Color tokens written to ${u.cyan(i)}`));}K(e,d);let N=E(e),m=Y(N),h=["clsx","tailwind-merge","lucide-react"],o=n.spinner();o.start("Installing dependencies");try{execSync(w(N,h),{cwd:e,stdio:"ignore"}),o.stop("Dependencies installed");}catch{o.stop("Failed to install dependencies"),n.log.warn(`Run manually: ${w(N,h)}`);}n.log.info(`Add components with: ${u.cyan(`${m} drivn add button`)}`),n.log.info(`Add dark/light theme: ${u.cyan(`${m} drivn add theme`)}`),n.outro("Drivn initialized");}var X=`'use client'
|
|
146
146
|
|
|
147
147
|
import { ThemeProvider as NextThemesProvider } from 'next-themes'
|
|
148
148
|
|
|
@@ -2155,6 +2155,283 @@ export const Collapsible = Object.assign(CollapsibleRoot, {
|
|
|
2155
2155
|
})
|
|
2156
2156
|
`;var pe=`'use client'
|
|
2157
2157
|
|
|
2158
|
+
import * as React from 'react'
|
|
2159
|
+
import { ChevronRight } from 'lucide-react'
|
|
2160
|
+
import { cn } from '@/utils/cn'
|
|
2161
|
+
|
|
2162
|
+
const styles = {
|
|
2163
|
+
trigger: 'contents',
|
|
2164
|
+
content: cn(
|
|
2165
|
+
'fixed min-w-[180px] z-50',
|
|
2166
|
+
'bg-card border border-border rounded-[10px] p-1',
|
|
2167
|
+
'shadow-lg',
|
|
2168
|
+
'transition-[opacity,visibility] duration-150 ease-in'
|
|
2169
|
+
),
|
|
2170
|
+
item: cn(
|
|
2171
|
+
'flex items-center gap-2 w-full px-3 py-2',
|
|
2172
|
+
'text-sm text-foreground rounded-lg',
|
|
2173
|
+
'hover:bg-accent transition-colors cursor-pointer'
|
|
2174
|
+
),
|
|
2175
|
+
destructive: 'text-destructive hover:bg-destructive/10',
|
|
2176
|
+
disabled: 'opacity-50 pointer-events-none',
|
|
2177
|
+
shortcut: 'ml-auto text-xs text-muted-foreground',
|
|
2178
|
+
group: 'py-1',
|
|
2179
|
+
label: cn(
|
|
2180
|
+
'px-3 py-1.5 text-xs font-medium',
|
|
2181
|
+
'text-muted-foreground'
|
|
2182
|
+
),
|
|
2183
|
+
separator: 'my-1 h-px bg-border',
|
|
2184
|
+
sub: 'relative group/sub',
|
|
2185
|
+
subContent: cn(
|
|
2186
|
+
'absolute left-full top-0 min-w-[180px] z-50',
|
|
2187
|
+
'bg-card border border-border rounded-[10px] p-1',
|
|
2188
|
+
'shadow-lg',
|
|
2189
|
+
'transition-[opacity,visibility] duration-150 ease-in',
|
|
2190
|
+
'opacity-0 invisible',
|
|
2191
|
+
'group-hover/sub:opacity-100',
|
|
2192
|
+
'group-hover/sub:visible',
|
|
2193
|
+
'group-hover/sub:ease-out'
|
|
2194
|
+
),
|
|
2195
|
+
}
|
|
2196
|
+
|
|
2197
|
+
interface ContextMenuCtx {
|
|
2198
|
+
open: boolean
|
|
2199
|
+
setOpen: (v: boolean) => void
|
|
2200
|
+
pos: { x: number; y: number }
|
|
2201
|
+
}
|
|
2202
|
+
|
|
2203
|
+
type IconProp = React.ComponentType<{ className?: string }> | React.ReactElement
|
|
2204
|
+
|
|
2205
|
+
function ContextMenuRoot({
|
|
2206
|
+
children,
|
|
2207
|
+
className,
|
|
2208
|
+
}: {
|
|
2209
|
+
children: React.ReactNode
|
|
2210
|
+
className?: string
|
|
2211
|
+
}) {
|
|
2212
|
+
const [open, setOpen] = React.useState(false)
|
|
2213
|
+
const [pos, setPos] = React.useState({ x: 0, y: 0 })
|
|
2214
|
+
|
|
2215
|
+
React.useEffect(() => {
|
|
2216
|
+
if (!open) return
|
|
2217
|
+
const close = () => setOpen(false)
|
|
2218
|
+
const onKeyDown = (e: KeyboardEvent) => {
|
|
2219
|
+
if (e.key === 'Escape') close()
|
|
2220
|
+
}
|
|
2221
|
+
document.addEventListener('mousedown', close)
|
|
2222
|
+
document.addEventListener('keydown', onKeyDown)
|
|
2223
|
+
return () => {
|
|
2224
|
+
document.removeEventListener('mousedown', close)
|
|
2225
|
+
document.removeEventListener('keydown', onKeyDown)
|
|
2226
|
+
}
|
|
2227
|
+
}, [open])
|
|
2228
|
+
|
|
2229
|
+
const onContextMenu = React.useCallback(
|
|
2230
|
+
(e: React.MouseEvent) => {
|
|
2231
|
+
e.preventDefault()
|
|
2232
|
+
setPos({ x: e.clientX, y: e.clientY })
|
|
2233
|
+
setOpen(true)
|
|
2234
|
+
}, [])
|
|
2235
|
+
|
|
2236
|
+
return (
|
|
2237
|
+
<Ctx.Provider value={{ open, setOpen, pos }}>
|
|
2238
|
+
<div className={className}>
|
|
2239
|
+
<div className={styles.trigger} onContextMenu={onContextMenu}>
|
|
2240
|
+
{children}
|
|
2241
|
+
</div>
|
|
2242
|
+
</div>
|
|
2243
|
+
</Ctx.Provider>
|
|
2244
|
+
)
|
|
2245
|
+
}
|
|
2246
|
+
|
|
2247
|
+
function Trigger({
|
|
2248
|
+
children,
|
|
2249
|
+
}: {
|
|
2250
|
+
children: React.ReactNode
|
|
2251
|
+
}) {
|
|
2252
|
+
return <>{children}</>
|
|
2253
|
+
}
|
|
2254
|
+
|
|
2255
|
+
function Content({
|
|
2256
|
+
children,
|
|
2257
|
+
className,
|
|
2258
|
+
}: {
|
|
2259
|
+
children: React.ReactNode
|
|
2260
|
+
className?: string
|
|
2261
|
+
}) {
|
|
2262
|
+
const { open, pos } = useContextMenu()
|
|
2263
|
+
return (
|
|
2264
|
+
<div
|
|
2265
|
+
style={{ left: pos.x, top: pos.y }}
|
|
2266
|
+
className={cn(
|
|
2267
|
+
styles.content,
|
|
2268
|
+
open ? 'opacity-100 visible ease-out' : 'opacity-0 invisible',
|
|
2269
|
+
className
|
|
2270
|
+
)}
|
|
2271
|
+
>
|
|
2272
|
+
{children}
|
|
2273
|
+
</div>
|
|
2274
|
+
)
|
|
2275
|
+
}
|
|
2276
|
+
|
|
2277
|
+
function Item({
|
|
2278
|
+
children,
|
|
2279
|
+
onClick,
|
|
2280
|
+
icon: Icon,
|
|
2281
|
+
shortcut,
|
|
2282
|
+
destructive,
|
|
2283
|
+
disabled,
|
|
2284
|
+
className,
|
|
2285
|
+
...props
|
|
2286
|
+
}: {
|
|
2287
|
+
children: React.ReactNode
|
|
2288
|
+
onClick?: () => void
|
|
2289
|
+
icon?: IconProp
|
|
2290
|
+
shortcut?: string
|
|
2291
|
+
destructive?: boolean
|
|
2292
|
+
disabled?: boolean
|
|
2293
|
+
className?: string
|
|
2294
|
+
} & Omit<
|
|
2295
|
+
React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
2296
|
+
'onClick' | 'disabled'
|
|
2297
|
+
>) {
|
|
2298
|
+
const { setOpen } = useContextMenu()
|
|
2299
|
+
return (
|
|
2300
|
+
<button
|
|
2301
|
+
disabled={disabled}
|
|
2302
|
+
className={cn(
|
|
2303
|
+
styles.item,
|
|
2304
|
+
destructive && styles.destructive,
|
|
2305
|
+
disabled && styles.disabled,
|
|
2306
|
+
className
|
|
2307
|
+
)}
|
|
2308
|
+
onClick={() => {
|
|
2309
|
+
onClick?.()
|
|
2310
|
+
setOpen(false)
|
|
2311
|
+
}}
|
|
2312
|
+
{...props}
|
|
2313
|
+
>
|
|
2314
|
+
{Icon && (React.isValidElement(Icon) ? Icon : <Icon className="w-4 h-4" />)}
|
|
2315
|
+
{children}
|
|
2316
|
+
{shortcut && (
|
|
2317
|
+
<span className={styles.shortcut}>{shortcut}</span>
|
|
2318
|
+
)}
|
|
2319
|
+
</button>
|
|
2320
|
+
)
|
|
2321
|
+
}
|
|
2322
|
+
|
|
2323
|
+
function Sub({
|
|
2324
|
+
children,
|
|
2325
|
+
className,
|
|
2326
|
+
}: {
|
|
2327
|
+
children: React.ReactNode
|
|
2328
|
+
className?: string
|
|
2329
|
+
}) {
|
|
2330
|
+
return (
|
|
2331
|
+
<div className={cn(styles.sub, className)}>
|
|
2332
|
+
{children}
|
|
2333
|
+
</div>
|
|
2334
|
+
)
|
|
2335
|
+
}
|
|
2336
|
+
|
|
2337
|
+
function SubTrigger({
|
|
2338
|
+
children,
|
|
2339
|
+
icon: Icon,
|
|
2340
|
+
className,
|
|
2341
|
+
...props
|
|
2342
|
+
}: {
|
|
2343
|
+
children: React.ReactNode
|
|
2344
|
+
icon?: IconProp
|
|
2345
|
+
className?: string
|
|
2346
|
+
} & Omit<
|
|
2347
|
+
React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
2348
|
+
'children'
|
|
2349
|
+
>) {
|
|
2350
|
+
return (
|
|
2351
|
+
<button
|
|
2352
|
+
className={cn(styles.item, className)}
|
|
2353
|
+
{...props}
|
|
2354
|
+
>
|
|
2355
|
+
{Icon && (React.isValidElement(Icon) ? Icon : <Icon className="w-4 h-4" />)}
|
|
2356
|
+
{children}
|
|
2357
|
+
<ChevronRight className="ml-auto w-4 h-4" />
|
|
2358
|
+
</button>
|
|
2359
|
+
)
|
|
2360
|
+
}
|
|
2361
|
+
|
|
2362
|
+
function SubContent({
|
|
2363
|
+
children,
|
|
2364
|
+
className,
|
|
2365
|
+
}: {
|
|
2366
|
+
children: React.ReactNode
|
|
2367
|
+
className?: string
|
|
2368
|
+
}) {
|
|
2369
|
+
return (
|
|
2370
|
+
<div className={cn(styles.subContent, className)}>
|
|
2371
|
+
{children}
|
|
2372
|
+
</div>
|
|
2373
|
+
)
|
|
2374
|
+
}
|
|
2375
|
+
|
|
2376
|
+
function Group({
|
|
2377
|
+
children,
|
|
2378
|
+
className,
|
|
2379
|
+
}: {
|
|
2380
|
+
children: React.ReactNode
|
|
2381
|
+
className?: string
|
|
2382
|
+
}) {
|
|
2383
|
+
return (
|
|
2384
|
+
<div className={cn(styles.group, className)}>
|
|
2385
|
+
{children}
|
|
2386
|
+
</div>
|
|
2387
|
+
)
|
|
2388
|
+
}
|
|
2389
|
+
|
|
2390
|
+
function ContextMenuLabel({
|
|
2391
|
+
children,
|
|
2392
|
+
className,
|
|
2393
|
+
}: {
|
|
2394
|
+
children: React.ReactNode
|
|
2395
|
+
className?: string
|
|
2396
|
+
}) {
|
|
2397
|
+
return (
|
|
2398
|
+
<div className={cn(styles.label, className)}>
|
|
2399
|
+
{children}
|
|
2400
|
+
</div>
|
|
2401
|
+
)
|
|
2402
|
+
}
|
|
2403
|
+
|
|
2404
|
+
function ContextMenuSeparator({
|
|
2405
|
+
className,
|
|
2406
|
+
}: {
|
|
2407
|
+
className?: string
|
|
2408
|
+
}) {
|
|
2409
|
+
return (
|
|
2410
|
+
<div className={cn(styles.separator, className)} />
|
|
2411
|
+
)
|
|
2412
|
+
}
|
|
2413
|
+
|
|
2414
|
+
const Ctx = React.createContext<ContextMenuCtx | null>(null)
|
|
2415
|
+
|
|
2416
|
+
function useContextMenu() {
|
|
2417
|
+
const ctx = React.useContext(Ctx)
|
|
2418
|
+
if (!ctx) throw new Error('ContextMenu compound used outside <ContextMenu>')
|
|
2419
|
+
return ctx
|
|
2420
|
+
}
|
|
2421
|
+
|
|
2422
|
+
export const ContextMenu = Object.assign(ContextMenuRoot, {
|
|
2423
|
+
Trigger,
|
|
2424
|
+
Content,
|
|
2425
|
+
Item,
|
|
2426
|
+
Sub,
|
|
2427
|
+
SubTrigger,
|
|
2428
|
+
SubContent,
|
|
2429
|
+
Group,
|
|
2430
|
+
Label: ContextMenuLabel,
|
|
2431
|
+
Separator: ContextMenuSeparator,
|
|
2432
|
+
})
|
|
2433
|
+
`;var ue=`'use client'
|
|
2434
|
+
|
|
2158
2435
|
import * as React from 'react'
|
|
2159
2436
|
import { X } from 'lucide-react'
|
|
2160
2437
|
import { cn } from '@/utils/cn'
|
|
@@ -2309,7 +2586,7 @@ export const Dialog = Object.assign(DialogRoot, {
|
|
|
2309
2586
|
Trigger,
|
|
2310
2587
|
Content,
|
|
2311
2588
|
})
|
|
2312
|
-
`;var
|
|
2589
|
+
`;var me=`'use client'
|
|
2313
2590
|
|
|
2314
2591
|
import * as React from 'react'
|
|
2315
2592
|
import { X } from 'lucide-react'
|
|
@@ -2528,7 +2805,7 @@ export const Drawer = Object.assign(DrawerRoot, {
|
|
|
2528
2805
|
Header,
|
|
2529
2806
|
Footer,
|
|
2530
2807
|
})
|
|
2531
|
-
`;var
|
|
2808
|
+
`;var fe=`'use client'
|
|
2532
2809
|
|
|
2533
2810
|
import * as React from 'react'
|
|
2534
2811
|
import { cn } from '@/utils/cn'
|
|
@@ -2726,7 +3003,7 @@ export const Dropdown = Object.assign(DropdownRoot, {
|
|
|
2726
3003
|
Label,
|
|
2727
3004
|
Separator: DropdownSeparator
|
|
2728
3005
|
})
|
|
2729
|
-
`;var
|
|
3006
|
+
`;var ge=`import * as React from 'react'
|
|
2730
3007
|
import { cn } from '@/utils/cn'
|
|
2731
3008
|
|
|
2732
3009
|
const styles = {
|
|
@@ -2749,7 +3026,7 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(({
|
|
|
2749
3026
|
)
|
|
2750
3027
|
|
|
2751
3028
|
Input.displayName = 'Input'
|
|
2752
|
-
`;var
|
|
3029
|
+
`;var he=`import * as React from 'react'
|
|
2753
3030
|
import { cn } from '@/utils/cn'
|
|
2754
3031
|
|
|
2755
3032
|
const styles = {
|
|
@@ -2806,7 +3083,7 @@ function Group({
|
|
|
2806
3083
|
}
|
|
2807
3084
|
|
|
2808
3085
|
export const Kbd = Object.assign(KbdRoot, { Group })
|
|
2809
|
-
`;var
|
|
3086
|
+
`;var be=`import * as React from 'react'
|
|
2810
3087
|
import { cn } from '@/utils/cn'
|
|
2811
3088
|
|
|
2812
3089
|
export function Label({
|
|
@@ -2823,7 +3100,143 @@ export function Label({
|
|
|
2823
3100
|
/>
|
|
2824
3101
|
)
|
|
2825
3102
|
}
|
|
2826
|
-
`;var
|
|
3103
|
+
`;var ve=`'use client'
|
|
3104
|
+
|
|
3105
|
+
import * as React from 'react'
|
|
3106
|
+
import { ChevronDown } from 'lucide-react'
|
|
3107
|
+
import { cn } from '@/utils/cn'
|
|
3108
|
+
|
|
3109
|
+
const styles = {
|
|
3110
|
+
root: 'relative',
|
|
3111
|
+
list: 'flex items-center gap-1',
|
|
3112
|
+
item: 'relative',
|
|
3113
|
+
trigger: cn(
|
|
3114
|
+
'inline-flex items-center gap-1 px-3 py-2',
|
|
3115
|
+
'text-sm font-medium text-foreground rounded-lg',
|
|
3116
|
+
'hover:bg-accent transition-colors cursor-pointer',
|
|
3117
|
+
'outline-none'
|
|
3118
|
+
),
|
|
3119
|
+
triggerIcon: 'w-3.5 h-3.5 transition-transform duration-200',
|
|
3120
|
+
content: cn(
|
|
3121
|
+
'absolute left-0 top-full min-w-[220px] z-50',
|
|
3122
|
+
'bg-card border border-border rounded-xl p-2',
|
|
3123
|
+
'shadow-lg shadow-black/8',
|
|
3124
|
+
'origin-[var(--origin)]',
|
|
3125
|
+
'transition-[opacity,visibility]',
|
|
3126
|
+
'duration-150 ease-in'
|
|
3127
|
+
),
|
|
3128
|
+
link: cn(
|
|
3129
|
+
'flex w-full gap-3 px-3 py-2.5',
|
|
3130
|
+
'text-sm font-medium text-foreground rounded-lg',
|
|
3131
|
+
'hover:bg-accent transition-colors cursor-pointer',
|
|
3132
|
+
'no-underline outline-none'
|
|
3133
|
+
),
|
|
3134
|
+
}
|
|
3135
|
+
|
|
3136
|
+
function NavigationMenuRoot({
|
|
3137
|
+
children,
|
|
3138
|
+
className,
|
|
3139
|
+
}: {
|
|
3140
|
+
children: React.ReactNode
|
|
3141
|
+
className?: string
|
|
3142
|
+
}) {
|
|
3143
|
+
return (
|
|
3144
|
+
<nav className={cn(styles.root, className)}>
|
|
3145
|
+
{children}
|
|
3146
|
+
</nav>
|
|
3147
|
+
)
|
|
3148
|
+
}
|
|
3149
|
+
|
|
3150
|
+
function List({
|
|
3151
|
+
children,
|
|
3152
|
+
className,
|
|
3153
|
+
}: {
|
|
3154
|
+
children: React.ReactNode
|
|
3155
|
+
className?: string
|
|
3156
|
+
}) {
|
|
3157
|
+
return (
|
|
3158
|
+
<ul className={cn(styles.list, className)}>
|
|
3159
|
+
{children}
|
|
3160
|
+
</ul>
|
|
3161
|
+
)
|
|
3162
|
+
}
|
|
3163
|
+
|
|
3164
|
+
function Item({
|
|
3165
|
+
children,
|
|
3166
|
+
className,
|
|
3167
|
+
}: {
|
|
3168
|
+
children: React.ReactNode
|
|
3169
|
+
className?: string
|
|
3170
|
+
}) {
|
|
3171
|
+
return (
|
|
3172
|
+
<li className={cn('group/item', styles.item, className)}>
|
|
3173
|
+
{children}
|
|
3174
|
+
</li>
|
|
3175
|
+
)
|
|
3176
|
+
}
|
|
3177
|
+
|
|
3178
|
+
function Trigger({
|
|
3179
|
+
children,
|
|
3180
|
+
className,
|
|
3181
|
+
...props
|
|
3182
|
+
}: React.ButtonHTMLAttributes<HTMLButtonElement>) {
|
|
3183
|
+
return (
|
|
3184
|
+
<button className={cn(styles.trigger, className)} {...props}>
|
|
3185
|
+
{children}
|
|
3186
|
+
<ChevronDown className={cn(styles.triggerIcon, 'group-hover/item:rotate-180')} />
|
|
3187
|
+
</button>
|
|
3188
|
+
)
|
|
3189
|
+
}
|
|
3190
|
+
|
|
3191
|
+
function Content({
|
|
3192
|
+
children,
|
|
3193
|
+
className,
|
|
3194
|
+
}: {
|
|
3195
|
+
children: React.ReactNode
|
|
3196
|
+
className?: string
|
|
3197
|
+
}) {
|
|
3198
|
+
return (
|
|
3199
|
+
<div
|
|
3200
|
+
style={{ '--origin': '0 0' } as React.CSSProperties}
|
|
3201
|
+
className={cn(
|
|
3202
|
+
styles.content,
|
|
3203
|
+
'opacity-0 invisible',
|
|
3204
|
+
'group-hover/item:opacity-100',
|
|
3205
|
+
'group-hover/item:visible',
|
|
3206
|
+
'group-hover/item:ease-out',
|
|
3207
|
+
className
|
|
3208
|
+
)}
|
|
3209
|
+
>
|
|
3210
|
+
{children}
|
|
3211
|
+
</div>
|
|
3212
|
+
)
|
|
3213
|
+
}
|
|
3214
|
+
|
|
3215
|
+
function Link({
|
|
3216
|
+
children,
|
|
3217
|
+
href,
|
|
3218
|
+
className,
|
|
3219
|
+
...props
|
|
3220
|
+
}: React.AnchorHTMLAttributes<HTMLAnchorElement>) {
|
|
3221
|
+
return (
|
|
3222
|
+
<a
|
|
3223
|
+
href={href}
|
|
3224
|
+
className={cn(styles.link, className)}
|
|
3225
|
+
{...props}
|
|
3226
|
+
>
|
|
3227
|
+
{children}
|
|
3228
|
+
</a>
|
|
3229
|
+
)
|
|
3230
|
+
}
|
|
3231
|
+
|
|
3232
|
+
export const NavigationMenu = Object.assign(NavigationMenuRoot, {
|
|
3233
|
+
List,
|
|
3234
|
+
Item,
|
|
3235
|
+
Trigger,
|
|
3236
|
+
Content,
|
|
3237
|
+
Link
|
|
3238
|
+
})
|
|
3239
|
+
`;var xe=`import * as React from 'react'
|
|
2827
3240
|
import { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react'
|
|
2828
3241
|
import { cn } from '@/utils/cn'
|
|
2829
3242
|
|
|
@@ -2956,7 +3369,7 @@ export const Pagination = Object.assign(PaginationRoot, {
|
|
|
2956
3369
|
Next,
|
|
2957
3370
|
Ellipsis: PaginationEllipsis,
|
|
2958
3371
|
})
|
|
2959
|
-
`;var
|
|
3372
|
+
`;var ye=`'use client'
|
|
2960
3373
|
|
|
2961
3374
|
import * as React from 'react'
|
|
2962
3375
|
import { cn } from '@/utils/cn'
|
|
@@ -3061,7 +3474,7 @@ export const Popover = Object.assign(PopoverRoot, {
|
|
|
3061
3474
|
Trigger,
|
|
3062
3475
|
Content
|
|
3063
3476
|
})
|
|
3064
|
-
`;var
|
|
3477
|
+
`;var Ne=`import * as React from 'react'
|
|
3065
3478
|
import { cn } from '@/utils/cn'
|
|
3066
3479
|
|
|
3067
3480
|
const styles = {
|
|
@@ -3099,7 +3512,7 @@ export function Progress({
|
|
|
3099
3512
|
</div>
|
|
3100
3513
|
)
|
|
3101
3514
|
}
|
|
3102
|
-
`;var
|
|
3515
|
+
`;var Ce=`'use client'
|
|
3103
3516
|
|
|
3104
3517
|
import * as React from 'react'
|
|
3105
3518
|
import { cn } from '@/utils/cn'
|
|
@@ -3248,7 +3661,7 @@ function useRadioGroup() {
|
|
|
3248
3661
|
}
|
|
3249
3662
|
|
|
3250
3663
|
export const RadioGroup = Object.assign(RadioGroupRoot, { Item })
|
|
3251
|
-
`;var
|
|
3664
|
+
`;var Re=`'use client'
|
|
3252
3665
|
|
|
3253
3666
|
import * as React from 'react'
|
|
3254
3667
|
import { ChevronDown } from 'lucide-react'
|
|
@@ -3404,7 +3817,7 @@ export const Select = Object.assign(SelectRoot, {
|
|
|
3404
3817
|
Menu,
|
|
3405
3818
|
Option
|
|
3406
3819
|
})
|
|
3407
|
-
`;var
|
|
3820
|
+
`;var we=`import * as React from 'react'
|
|
3408
3821
|
import { cn } from '@/utils/cn'
|
|
3409
3822
|
|
|
3410
3823
|
const styles = {
|
|
@@ -3450,7 +3863,7 @@ export function ScrollArea({
|
|
|
3450
3863
|
</div>
|
|
3451
3864
|
)
|
|
3452
3865
|
}
|
|
3453
|
-
`;var
|
|
3866
|
+
`;var ke=`import * as React from 'react'
|
|
3454
3867
|
import { cn } from '@/utils/cn'
|
|
3455
3868
|
|
|
3456
3869
|
const styles = {
|
|
@@ -3474,7 +3887,7 @@ export function Separator({
|
|
|
3474
3887
|
/>
|
|
3475
3888
|
)
|
|
3476
3889
|
}
|
|
3477
|
-
`;var
|
|
3890
|
+
`;var Pe=`import * as React from 'react'
|
|
3478
3891
|
import { cn } from '@/utils/cn'
|
|
3479
3892
|
|
|
3480
3893
|
export function Skeleton({
|
|
@@ -3491,7 +3904,7 @@ export function Skeleton({
|
|
|
3491
3904
|
/>
|
|
3492
3905
|
)
|
|
3493
3906
|
}
|
|
3494
|
-
`;var
|
|
3907
|
+
`;var Se=`'use client'
|
|
3495
3908
|
|
|
3496
3909
|
import * as React from 'react'
|
|
3497
3910
|
import { ChevronDown, PanelLeft } from 'lucide-react'
|
|
@@ -3777,7 +4190,7 @@ export const Sidebar = Object.assign(SidebarRoot, {
|
|
|
3777
4190
|
Separator: SidebarSeparator,
|
|
3778
4191
|
CollapseButton,
|
|
3779
4192
|
})
|
|
3780
|
-
`;var
|
|
4193
|
+
`;var De=`'use client'
|
|
3781
4194
|
|
|
3782
4195
|
import * as React from 'react'
|
|
3783
4196
|
import { cn } from '@/utils/cn'
|
|
@@ -3922,7 +4335,7 @@ export const Slider = React.forwardRef<HTMLInputElement, SliderProps>(({
|
|
|
3922
4335
|
)
|
|
3923
4336
|
|
|
3924
4337
|
Slider.displayName = 'Slider'
|
|
3925
|
-
`;var
|
|
4338
|
+
`;var Te=`'use client'
|
|
3926
4339
|
|
|
3927
4340
|
import * as React from 'react'
|
|
3928
4341
|
import { cn } from '@/utils/cn'
|
|
@@ -3964,7 +4377,7 @@ export function Switch({
|
|
|
3964
4377
|
</button>
|
|
3965
4378
|
)
|
|
3966
4379
|
}
|
|
3967
|
-
`;var
|
|
4380
|
+
`;var Ie=`'use client'
|
|
3968
4381
|
|
|
3969
4382
|
import * as React from 'react'
|
|
3970
4383
|
import { cn } from '@/utils/cn'
|
|
@@ -4078,7 +4491,7 @@ export const Tabs = Object.assign(TabsRoot, {
|
|
|
4078
4491
|
Tab,
|
|
4079
4492
|
Panel
|
|
4080
4493
|
})
|
|
4081
|
-
`;var
|
|
4494
|
+
`;var Ee=`import * as React from 'react'
|
|
4082
4495
|
import { cn } from '@/utils/cn'
|
|
4083
4496
|
|
|
4084
4497
|
const styles = {
|
|
@@ -4105,7 +4518,7 @@ export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(({
|
|
|
4105
4518
|
))
|
|
4106
4519
|
|
|
4107
4520
|
Textarea.displayName = 'Textarea'
|
|
4108
|
-
`;var
|
|
4521
|
+
`;var Le=`'use client'
|
|
4109
4522
|
|
|
4110
4523
|
import * as React from 'react'
|
|
4111
4524
|
import { Toaster as Sonner, toast } from 'sonner'
|
|
@@ -4148,7 +4561,7 @@ function Toaster() {
|
|
|
4148
4561
|
}
|
|
4149
4562
|
|
|
4150
4563
|
export { Toaster, toast }
|
|
4151
|
-
`;var
|
|
4564
|
+
`;var Me=`'use client'
|
|
4152
4565
|
|
|
4153
4566
|
import * as React from 'react'
|
|
4154
4567
|
import { cn } from '@/utils/cn'
|
|
@@ -4310,7 +4723,7 @@ const Ctx = React.createContext<ToggleGroupCtx | null>(null)
|
|
|
4310
4723
|
export const Toggle = Object.assign(ToggleButton, {
|
|
4311
4724
|
Group: ToggleGroupRoot,
|
|
4312
4725
|
})
|
|
4313
|
-
`;var
|
|
4726
|
+
`;var Oe=`import * as React from 'react'
|
|
4314
4727
|
import { cn } from '@/utils/cn'
|
|
4315
4728
|
|
|
4316
4729
|
const styles = {
|
|
@@ -4484,7 +4897,7 @@ export const Table = Object.assign(TableRoot, {
|
|
|
4484
4897
|
Head,
|
|
4485
4898
|
Cell,
|
|
4486
4899
|
})
|
|
4487
|
-
`;var
|
|
4900
|
+
`;var Ae=`import * as React from 'react'
|
|
4488
4901
|
import { cn } from '@/utils/cn'
|
|
4489
4902
|
|
|
4490
4903
|
const styles = {
|
|
@@ -4529,7 +4942,7 @@ export function Tooltip({
|
|
|
4529
4942
|
</span>
|
|
4530
4943
|
)
|
|
4531
4944
|
}
|
|
4532
|
-
`;var
|
|
4945
|
+
`;var Be=`
|
|
4533
4946
|
/* react-day-picker theme integration */
|
|
4534
4947
|
.rdp-root {
|
|
4535
4948
|
--rdp-accent-color: var(--primary);
|
|
@@ -4540,7 +4953,7 @@ export function Tooltip({
|
|
|
4540
4953
|
--rdp-selected-border: none;
|
|
4541
4954
|
--rdp-day_button-border: none;
|
|
4542
4955
|
}
|
|
4543
|
-
`,v=[{name:"accordion",description:"Collapsible content sections with dot notation and smooth animation",dependencies:[],npmDependencies:[]},{name:"alert",description:"Contextual feedback messages with variants and icons",dependencies:[],npmDependencies:[]},{name:"aspect-ratio",description:"Maintain consistent width-to-height ratios for images, videos, and embedded content",dependencies:[],npmDependencies:[]},{name:"avatar",description:"User avatar with image support and fallback initials",dependencies:[],npmDependencies:[]},{name:"badge",description:"Small status indicator with color variants",dependencies:[],npmDependencies:[]},{name:"breadcrumb",description:"Breadcrumb navigation with auto-separators, ellipsis, and dot notation",dependencies:[],npmDependencies:[]},{name:"button",description:"Button with variants, sizes, loading state, and icon slots",dependencies:[],npmDependencies:[]},{name:"calendar",description:"Date picker powered by react-day-picker with single, range, and dropdown modes",dependencies:[],npmDependencies:["react-day-picker"]},{name:"date-picker",description:"Date picker input with Calendar dropdown for single date and range selection",dependencies:["calendar"],npmDependencies:[]},{name:"command",description:"Searchable command menu with filtering, keyboard navigation, and dialog mode",dependencies:["dialog"],npmDependencies:["cmdk"]},{name:"carousel",description:"Carousel with touch/swipe, navigation arrows, dot indicators, and loop mode",dependencies:["button"],npmDependencies:["embla-carousel-react"]},{name:"card",description:"Container with dot notation preview and info sub-components",dependencies:[],npmDependencies:[]},{name:"checkbox",description:"Checkbox input with label and CSS-only checkmark",dependencies:[],npmDependencies:[]},{name:"combobox",description:"Searchable select with filtering, single/multi selection, and keyboard navigation",dependencies:[],npmDependencies:["cmdk"]},{name:"collapsible",description:"Toggle content visibility with smooth animation and accessible controls",dependencies:[],npmDependencies:[]},{name:"dialog",description:"Modal dialog with dot notation, overlay, and escape key",dependencies:["button"],npmDependencies:[]},{name:"drawer",description:"Slide-in panel with side positioning, header/footer, and overlay",dependencies:["button"],npmDependencies:[]},{name:"dropdown",description:"Dropdown menu with dot notation, groups, separators, and click-outside",dependencies:["button"],npmDependencies:[]},{name:"input",description:"Text input with focus ring and disabled state",dependencies:[],npmDependencies:[]},{name:"kbd",description:"Keyboard key display for shortcuts and hotkeys",dependencies:[],npmDependencies:[]},{name:"label",description:"Accessible form label for inputs, checkboxes, and selects",dependencies:[],npmDependencies:[]},{name:"pagination",description:"Page navigation with dot notation, Previous/Next, ellipsis, and active state",dependencies:[],npmDependencies:[]},{name:"popover",description:"Floating content panel with dot notation and click-outside",dependencies:["button"],npmDependencies:[]},{name:"progress",description:"Progress bar with animated fill and ARIA attributes",dependencies:[],npmDependencies:[]},{name:"radio-group",description:"Radio group with dot notation, orientation support, and controlled/uncontrolled selection",dependencies:[],npmDependencies:[]},{name:"select",description:"Custom select with dot notation and composable options",dependencies:[],npmDependencies:[]},{name:"scroll-area",description:"Themed scrollable container with custom scrollbar styling and orientation control",dependencies:[],npmDependencies:[]},{name:"separator",description:"Visual divider with horizontal and vertical orientation",dependencies:[],npmDependencies:[]},{name:"skeleton",description:"Loading placeholder with pulse animation, sized and shaped via className",dependencies:[],npmDependencies:[]},{name:"sidebar",description:"Collapsible sidebar with dot notation, icon items, groups, and layout variants",dependencies:[],npmDependencies:[]},{name:"slider",description:"Range slider with pointer drag, step snapping, and size variants",dependencies:[],npmDependencies:[]},{name:"switch",description:"Toggle switch with smooth transition",dependencies:[],npmDependencies:[]},{name:"tabs",description:"Tab navigation with dot notation and panel content",dependencies:[],npmDependencies:[]},{name:"table",description:"Data table with dot notation, striped/bordered variants, and responsive overflow",dependencies:[],npmDependencies:[]},{name:"textarea",description:"Multi-line text input with consistent styling",dependencies:[],npmDependencies:[]},{name:"theme",description:"Dark/light theme support with next-themes and ThemeProvider",dependencies:[],npmDependencies:["next-themes"]},{name:"toast",description:"Toast notifications powered by Sonner",dependencies:[],npmDependencies:["sonner"]},{name:"toggle",description:"Toggle button with pressed state, single and multiple selection groups",dependencies:[],npmDependencies:[]},{name:"tooltip",description:"Pure CSS tooltip with 4 position options",dependencies:[],npmDependencies:[]}],R={accordion:q,alert:J,"aspect-ratio":Z,avatar:Q,badge:ee,breadcrumb:te,button:ne,calendar:oe,"date-picker":re,command:se,carousel:ae,card:ie,checkbox:ce,combobox:le,collapsible:de,
|
|
4956
|
+
`,v=[{name:"accordion",description:"Collapsible content sections with dot notation and smooth animation",dependencies:[],npmDependencies:[]},{name:"alert",description:"Contextual feedback messages with variants and icons",dependencies:[],npmDependencies:[]},{name:"aspect-ratio",description:"Maintain consistent width-to-height ratios for images, videos, and embedded content",dependencies:[],npmDependencies:[]},{name:"avatar",description:"User avatar with image support and fallback initials",dependencies:[],npmDependencies:[]},{name:"badge",description:"Small status indicator with color variants",dependencies:[],npmDependencies:[]},{name:"breadcrumb",description:"Breadcrumb navigation with auto-separators, ellipsis, and dot notation",dependencies:[],npmDependencies:[]},{name:"button",description:"Button with variants, sizes, loading state, and icon slots",dependencies:[],npmDependencies:[]},{name:"calendar",description:"Date picker powered by react-day-picker with single, range, and dropdown modes",dependencies:[],npmDependencies:["react-day-picker"]},{name:"date-picker",description:"Date picker input with Calendar dropdown for single date and range selection",dependencies:["calendar"],npmDependencies:[]},{name:"command",description:"Searchable command menu with filtering, keyboard navigation, and dialog mode",dependencies:["dialog"],npmDependencies:["cmdk"]},{name:"carousel",description:"Carousel with touch/swipe, navigation arrows, dot indicators, and loop mode",dependencies:["button"],npmDependencies:["embla-carousel-react"]},{name:"card",description:"Container with dot notation preview and info sub-components",dependencies:[],npmDependencies:[]},{name:"checkbox",description:"Checkbox input with label and CSS-only checkmark",dependencies:[],npmDependencies:[]},{name:"combobox",description:"Searchable select with filtering, single/multi selection, and keyboard navigation",dependencies:[],npmDependencies:["cmdk"]},{name:"collapsible",description:"Toggle content visibility with smooth animation and accessible controls",dependencies:[],npmDependencies:[]},{name:"context-menu",description:"Right-click context menu with submenus, keyboard shortcuts, icons, and dot notation",dependencies:[],npmDependencies:[]},{name:"dialog",description:"Modal dialog with dot notation, overlay, and escape key",dependencies:["button"],npmDependencies:[]},{name:"drawer",description:"Slide-in panel with side positioning, header/footer, and overlay",dependencies:["button"],npmDependencies:[]},{name:"dropdown",description:"Dropdown menu with dot notation, groups, separators, and click-outside",dependencies:["button"],npmDependencies:[]},{name:"input",description:"Text input with focus ring and disabled state",dependencies:[],npmDependencies:[]},{name:"kbd",description:"Keyboard key display for shortcuts and hotkeys",dependencies:[],npmDependencies:[]},{name:"label",description:"Accessible form label for inputs, checkboxes, and selects",dependencies:[],npmDependencies:[]},{name:"navigation-menu",description:"Horizontal navigation menu with dropdown content panels and dot notation",dependencies:[],npmDependencies:[]},{name:"pagination",description:"Page navigation with dot notation, Previous/Next, ellipsis, and active state",dependencies:[],npmDependencies:[]},{name:"popover",description:"Floating content panel with dot notation and click-outside",dependencies:["button"],npmDependencies:[]},{name:"progress",description:"Progress bar with animated fill and ARIA attributes",dependencies:[],npmDependencies:[]},{name:"radio-group",description:"Radio group with dot notation, orientation support, and controlled/uncontrolled selection",dependencies:[],npmDependencies:[]},{name:"select",description:"Custom select with dot notation and composable options",dependencies:[],npmDependencies:[]},{name:"scroll-area",description:"Themed scrollable container with custom scrollbar styling and orientation control",dependencies:[],npmDependencies:[]},{name:"separator",description:"Visual divider with horizontal and vertical orientation",dependencies:[],npmDependencies:[]},{name:"skeleton",description:"Loading placeholder with pulse animation, sized and shaped via className",dependencies:[],npmDependencies:[]},{name:"sidebar",description:"Collapsible sidebar with dot notation, icon items, groups, and layout variants",dependencies:[],npmDependencies:[]},{name:"slider",description:"Range slider with pointer drag, step snapping, and size variants",dependencies:[],npmDependencies:[]},{name:"switch",description:"Toggle switch with smooth transition",dependencies:[],npmDependencies:[]},{name:"tabs",description:"Tab navigation with dot notation and panel content",dependencies:[],npmDependencies:[]},{name:"table",description:"Data table with dot notation, striped/bordered variants, and responsive overflow",dependencies:[],npmDependencies:[]},{name:"textarea",description:"Multi-line text input with consistent styling",dependencies:[],npmDependencies:[]},{name:"theme",description:"Dark/light theme support with next-themes and ThemeProvider",dependencies:[],npmDependencies:["next-themes"]},{name:"toast",description:"Toast notifications powered by Sonner",dependencies:[],npmDependencies:["sonner"]},{name:"toggle",description:"Toggle button with pressed state, single and multiple selection groups",dependencies:[],npmDependencies:[]},{name:"tooltip",description:"Pure CSS tooltip with 4 position options",dependencies:[],npmDependencies:[]}],R={accordion:q,alert:J,"aspect-ratio":Z,avatar:Q,badge:ee,breadcrumb:te,button:ne,calendar:oe,"date-picker":re,command:se,carousel:ae,card:ie,checkbox:ce,combobox:le,collapsible:de,"context-menu":pe,dialog:ue,drawer:me,dropdown:fe,input:ge,kbd:he,label:be,"navigation-menu":ve,pagination:xe,popover:ye,progress:Ne,"radio-group":Ce,select:Re,"scroll-area":we,separator:ke,skeleton:Pe,sidebar:Se,slider:De,switch:Te,table:Oe,tabs:Ie,textarea:Ee,theme:X,toast:Le,toggle:Me,tooltip:Ae};async function He(e){let r=process.cwd();n.intro("drivn add");let t=U(r);if(t||(n.log.error("Drivn is not initialized. Run npx drivn@latest create"),n.outro("Cancelled"),process.exit(1)),!e||!e.length){let o=await n.multiselect({message:"Select components to add",options:v.map(s=>({label:s.name,hint:s.description,value:s.name})),required:true});n.isCancel(o)&&(n.cancel("Cancelled"),process.exit(0)),e=o;}let a=e.filter(o=>!v.find(s=>s.name===o));a.length&&(n.log.error(`Unknown components: ${a.join(", ")}`),n.log.info("Available: "+v.map(o=>o.name).join(", ")),n.outro("Cancelled"),process.exit(1));let l=e.includes("theme"),d=e.filter(o=>o!=="theme"),p=new Set,f=new Set,g=o=>{if(p.has(o))return;let s=v.find(i=>i.name===o);s&&(s.dependencies.forEach(i=>g(i)),s.npmDependencies?.forEach(i=>f.add(i)),p.add(o));};d.forEach(g),l&&f.add("next-themes");let N=[...p].filter(o=>!d.includes(o));N.length&&n.log.info(`Required dependency: ${N.join(", ")}`);let m=t.typescript?"tsx":"jsx",h=join(r,t.paths.components);for(let o of p){let s=join(h,`${o}.${m}`);if(x(s)){let S=await n.confirm({message:`${o}.${m} exists. Overwrite?`,initialValue:false});if(n.isCancel(S)||!S){n.log.warn(`Skipped ${o}`);continue}}let i=R[o];i=i.replace(/@\/utils/g,`@/${t.paths.utils.replace(/^src\//,"")}`),b(s,i),n.log.success(`${o} \u2192 ${t.paths.components}/${o}.${m}`);}if(l){let o=join(h,`theme-provider.${m}`);if(x(o)){let i=await n.confirm({message:`theme-provider.${m} exists. Overwrite?`,initialValue:false});!n.isCancel(i)&&i?(b(o,R.theme),n.log.success(`theme-provider \u2192 ${t.paths.components}/theme-provider.${m}`)):n.log.warn("Skipped theme-provider");}else b(o,R.theme),n.log.success(`theme-provider \u2192 ${t.paths.components}/theme-provider.${m}`);if(t.paths.globals){let i=join(r,t.paths.globals);if(x(i)){let S=H(i);S.includes('[data-theme="dark"]')?n.log.warn("Theme tokens already exist in globals \u2014 skipped"):(b(i,S+k),n.log.success(`Theme tokens appended to ${u.cyan(t.paths.globals)}`));}else n.log.warn(`Globals file not found at ${t.paths.globals}`);}else n.log.warn('No globals path in drivn.config.json. Add "globals" to paths');let s=t.paths.components.replace(/^src\//,"@/");n.log.message(""),n.log.info(u.bold("Complete the setup:")),n.log.message(""),n.log.message(u.bold(`${u.cyan("1.")} Import ThemeProvider in your root layout:`)),n.log.message(u.cyan(` import { ThemeProvider } from "${s}/theme-provider"`)),n.log.message(""),n.log.message(u.bold(`${u.cyan("2.")} Add suppressHydrationWarning to <html>:`)),n.log.message(u.cyan(" <html suppressHydrationWarning>")),n.log.message(""),n.log.message(u.bold(`${u.cyan("3.")} Wrap your app with ThemeProvider:`)),n.log.message(u.cyan(" <ThemeProvider>")),n.log.message(u.cyan(" {children}")),n.log.message(u.cyan(" </ThemeProvider>")),n.log.message("");}if(p.has("calendar")&&t.paths.globals){let o=join(r,t.paths.globals);if(x(o)){let s=H(o);s.includes(".rdp-root")?n.log.warn("Calendar tokens already exist in globals \u2014 skipped"):(b(o,s+Be),n.log.success(`Calendar tokens appended to ${u.cyan(t.paths.globals)}`));}}if(f.size){let o=E(r),s=[...f],i=n.spinner();i.start("Installing packages");try{execSync(w(o,s),{cwd:r,stdio:"ignore"}),i.stop("Packages installed");}catch{i.stop("Failed to install packages"),n.log.warn(`Run manually: ${w(o,s)}`);}}n.outro("Done.");}var z=`# Drivn Component Conventions
|
|
4544
4957
|
|
|
4545
4958
|
## Core Philosophy
|
|
4546
4959
|
- **Zero runtime UI deps** \u2014 No Radix, no cva, no external UI primitives. Pure React + Tailwind.
|
|
@@ -4653,13 +5066,13 @@ import { cn } from '@/utils/cn'
|
|
|
4653
5066
|
- Components declare internal deps (other Drivn components)
|
|
4654
5067
|
- Some components need npm packages (react-day-picker, cmdk, embla-carousel-react, sonner)
|
|
4655
5068
|
- The CLI resolves and installs all dependencies automatically
|
|
4656
|
-
`;var L={version:"1.
|
|
5069
|
+
`;var L={version:"1.13.0"};function M(e){return v.find(r=>r.name===e)}function Qe(e){let r=new Set,t=a=>{if(r.has(a))return;let l=M(a);l&&(l.dependencies.forEach(d=>t(d)),r.add(a));};return t(e),r.delete(e),[...r]}async function ze(){let e=new McpServer({name:"drivn",version:L.version});e.tool("list_components","List all available Drivn UI components with descriptions",{},async()=>({content:[{type:"text",text:JSON.stringify(v.map(t=>({name:t.name,description:t.description})),null,2)}]})),e.tool("get_component","Get the full source code and metadata for a Drivn component",{name:z$1.string().describe('Component name (e.g. "button", "dialog")')},async({name:t})=>{let a=M(t);if(!a)return {content:[{type:"text",text:`Component "${t}" not found. Use list_components to see available components.`}],isError:true};let l=R[t];return {content:[{type:"text",text:JSON.stringify({name:a.name,description:a.description,dependencies:a.dependencies,npmDependencies:a.npmDependencies,source:l},null,2)}]}}),e.tool("get_component_metadata","Get metadata only (no source code) for a Drivn component \u2014 useful for planning",{name:z$1.string().describe("Component name")},async({name:t})=>{let a=M(t);if(!a)return {content:[{type:"text",text:`Component "${t}" not found. Use list_components to see available components.`}],isError:true};let l=Qe(t);return {content:[{type:"text",text:JSON.stringify({name:a.name,description:a.description,dependencies:a.dependencies,npmDependencies:a.npmDependencies,allResolvedDependencies:l},null,2)}]}}),e.tool("search_components","Search Drivn components by name or description",{query:z$1.string().describe("Search query")},async({query:t})=>{let a=t.toLowerCase(),l=v.filter(d=>d.name.includes(a)||d.description.toLowerCase().includes(a));return {content:[{type:"text",text:l.length?JSON.stringify(l.map(d=>({name:d.name,description:d.description})),null,2):`No components matching "${t}".`}]}}),e.tool("get_installation_instructions","Get step-by-step installation instructions for one or more components",{components:z$1.array(z$1.string()).describe("Component names to install"),packageManager:z$1.enum(["npm","pnpm"]).optional().describe("Package manager (default: npm)")},async({components:t,packageManager:a})=>{let l=a??"npm",d=new Set,p=new Set,f=[],g=o=>{if(d.has(o))return;let s=M(o);if(!s){f.push(o);return}s.dependencies.forEach(i=>g(i)),s.npmDependencies.forEach(i=>p.add(i)),d.add(o);};if(t.forEach(g),f.length)return {content:[{type:"text",text:`Unknown components: ${f.join(", ")}. Use list_components to see available components.`}],isError:true};let N=l==="pnpm"?"pnpm dlx":"npx",m=l==="pnpm"?"pnpm add":"npm install",h=[];return h.push(`# Install components via CLI
|
|
4657
5070
|
${N} drivn@latest add ${[...d].join(" ")}`),p.size&&h.push(`# Install required npm dependencies
|
|
4658
5071
|
${m} ${[...p].join(" ")}`),h.push(`# Components will be installed to your configured components directory
|
|
4659
5072
|
# (default: src/components/ui/)`),{content:[{type:"text",text:JSON.stringify({componentsToInstall:[...d],npmDependencies:[...p],steps:h},null,2)}]}}),e.tool("get_design_tokens","Get the Drivn CSS design tokens (base globals and theme tokens)",{},async()=>({content:[{type:"text",text:`/* === Base Globals === */
|
|
4660
5073
|
${C}
|
|
4661
5074
|
|
|
4662
5075
|
/* === Theme Tokens === */
|
|
4663
|
-
${k}`}]})),e.tool("get_drivn_rules","Get Drivn coding conventions and component patterns",{},async()=>({content:[{type:"text",text:
|
|
5076
|
+
${k}`}]})),e.tool("get_drivn_rules","Get Drivn coding conventions and component patterns",{},async()=>({content:[{type:"text",text:z}]})),e.resource("drivn-rules","drivn://rules",{description:"Drivn coding conventions and component patterns"},async()=>({contents:[{uri:"drivn://rules",mimeType:"text/markdown",text:z}]})),e.resource("drivn-design-tokens","drivn://design-tokens",{description:"Drivn CSS globals and theme tokens"},async()=>({contents:[{uri:"drivn://design-tokens",mimeType:"text/css",text:`${C}
|
|
4664
5077
|
|
|
4665
|
-
${k}`}]}));for(let t of v){let a=`drivn://components/${t.name}`;e.resource(`drivn-component-${t.name}`,a,{description:t.description},async()=>({contents:[{uri:a,mimeType:"text/plain",text:R[t.name]}]}));}let r=new StdioServerTransport;await e.connect(r);}var I=new Command;I.name("drivn").description("Drivn \u2014 Modern UI components").version(L.version);I.command("create").description("Initialize Drivn in your project").action(
|
|
5078
|
+
${k}`}]}));for(let t of v){let a=`drivn://components/${t.name}`;e.resource(`drivn-component-${t.name}`,a,{description:t.description},async()=>({contents:[{uri:a,mimeType:"text/plain",text:R[t.name]}]}));}let r=new StdioServerTransport;await e.connect(r);}var I=new Command;I.name("drivn").description("Drivn \u2014 Modern UI components").version(L.version);I.command("create").description("Initialize Drivn in your project").action(W);I.command("add [components...]").description("Add components to your project").action(He);I.command("mcp").description("Start the Drivn MCP server").action(ze);I.parse();
|