drivn 1.14.1 → 1.16.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.js +508 -30
- package/package.json +1 -1
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 z={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 Ue(e){existsSync(e)||mkdirSync(e,{recursive:true});}function h(e,r){Ue(dirname(e)),writeFileSync(e,r);}function B(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 R(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 Xe=`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
|
+
`,qe=["src/app/globals.css","src/styles/globals.css","src/styles/globals.scss","app/globals.css"];function Je(e){for(let r of qe)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(z[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}},p=r.typescript?"ts":"js",f=join(e,l.utils,`cn.${p}`);x(f)||h(f,Xe);let g=Je(e);if(g){let s=await n.confirm({message:`Found ${u.cyan(g)}. Add Drivn color tokens?`,initialValue:true});!n.isCancel(s)&&s&&(h(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)||(h(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),b=["clsx","tailwind-merge","lucide-react"],o=n.spinner();o.start("Installing dependencies");try{execSync(R(N,b),{cwd:e,stdio:"ignore"}),o.stop("Dependencies installed");}catch{o.stop("Failed to install dependencies"),n.log.warn(`Run manually: ${R(N,b)}`);}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
|
|
|
@@ -2432,6 +2432,257 @@ export const ContextMenu = Object.assign(ContextMenuRoot, {
|
|
|
2432
2432
|
})
|
|
2433
2433
|
`;var ue=`'use client'
|
|
2434
2434
|
|
|
2435
|
+
import * as React from 'react'
|
|
2436
|
+
import { ArrowDown, ArrowUp, ArrowUpDown } from 'lucide-react'
|
|
2437
|
+
import { cn } from '@/utils/cn'
|
|
2438
|
+
import { Table } from '@/components/ui/table'
|
|
2439
|
+
import { Checkbox } from '@/components/ui/checkbox'
|
|
2440
|
+
import { Skeleton } from '@/components/ui/skeleton'
|
|
2441
|
+
import { Pagination } from '@/components/ui/pagination'
|
|
2442
|
+
|
|
2443
|
+
const styles = {
|
|
2444
|
+
root: 'space-y-4',
|
|
2445
|
+
sortButton: 'inline-flex items-center gap-1 cursor-pointer select-none',
|
|
2446
|
+
sortIcon: 'w-3.5 h-3.5 text-muted-foreground',
|
|
2447
|
+
sortIconActive: 'text-foreground',
|
|
2448
|
+
selectCell: 'w-10',
|
|
2449
|
+
rowSelected: 'bg-primary/5',
|
|
2450
|
+
empty: 'py-12 text-center text-sm text-muted-foreground',
|
|
2451
|
+
skeleton: 'h-4 rounded',
|
|
2452
|
+
pagination: 'flex items-center justify-between',
|
|
2453
|
+
}
|
|
2454
|
+
|
|
2455
|
+
type Row = Record<string, unknown>
|
|
2456
|
+
|
|
2457
|
+
interface Sort {
|
|
2458
|
+
id: string
|
|
2459
|
+
direction: 'asc' | 'desc'
|
|
2460
|
+
}
|
|
2461
|
+
|
|
2462
|
+
interface ColumnDef<T> {
|
|
2463
|
+
id: string
|
|
2464
|
+
header: string
|
|
2465
|
+
cell?: (value: unknown, row: T) => React.ReactNode
|
|
2466
|
+
align?: 'left' | 'center' | 'right'
|
|
2467
|
+
width?: string
|
|
2468
|
+
sortable?: boolean
|
|
2469
|
+
}
|
|
2470
|
+
|
|
2471
|
+
interface DataTableProps<T> {
|
|
2472
|
+
data: T[]
|
|
2473
|
+
columns: ColumnDef<T>[]
|
|
2474
|
+
rowKey: string
|
|
2475
|
+
variant?: 'default' | 'striped' | 'bordered'
|
|
2476
|
+
sortable?: boolean
|
|
2477
|
+
onSortChange?: (sort: Sort) => void
|
|
2478
|
+
selectable?: boolean
|
|
2479
|
+
onSelectionChange?: (keys: Set<string>) => void
|
|
2480
|
+
loading?: boolean
|
|
2481
|
+
toolbar?: React.ReactNode
|
|
2482
|
+
footer?: React.ReactNode
|
|
2483
|
+
className?: string
|
|
2484
|
+
}
|
|
2485
|
+
|
|
2486
|
+
interface DataTablePaginationProps {
|
|
2487
|
+
page: number
|
|
2488
|
+
pageCount: number
|
|
2489
|
+
onPageChange: (page: number) => void
|
|
2490
|
+
className?: string
|
|
2491
|
+
}
|
|
2492
|
+
|
|
2493
|
+
function DataTableRoot<T>({
|
|
2494
|
+
data,
|
|
2495
|
+
columns,
|
|
2496
|
+
rowKey,
|
|
2497
|
+
variant = 'default',
|
|
2498
|
+
sortable = false,
|
|
2499
|
+
onSortChange,
|
|
2500
|
+
selectable = false,
|
|
2501
|
+
onSelectionChange,
|
|
2502
|
+
loading = false,
|
|
2503
|
+
toolbar,
|
|
2504
|
+
footer,
|
|
2505
|
+
className,
|
|
2506
|
+
}: DataTableProps<T>) {
|
|
2507
|
+
const [sort, setSort] = React.useState<Sort | null>(null)
|
|
2508
|
+
const [selected, setSelected] = React.useState<Set<string>>(new Set())
|
|
2509
|
+
const ref = React.useRef<HTMLInputElement>(null)
|
|
2510
|
+
|
|
2511
|
+
const sorted = React.useMemo(() => {
|
|
2512
|
+
if (!sort) return data
|
|
2513
|
+
const col = columns.find(c => c.id === sort.id)
|
|
2514
|
+
if (!col) return data
|
|
2515
|
+
const m = sort.direction === 'asc' ? 1 : -1
|
|
2516
|
+
return [...data].sort((a, b) => {
|
|
2517
|
+
const x = (a as Row)[col.id], y = (b as Row)[col.id]
|
|
2518
|
+
if (x == null) return 1
|
|
2519
|
+
if (y == null) return -1
|
|
2520
|
+
return (typeof x === 'number' && typeof y === 'number'
|
|
2521
|
+
? x - y : String(x).localeCompare(String(y))) * m
|
|
2522
|
+
})
|
|
2523
|
+
}, [data, sort, columns])
|
|
2524
|
+
|
|
2525
|
+
const keys = React.useMemo(() => sorted.map(r => \`\${(r as Row)[rowKey]}\`), [sorted, rowKey])
|
|
2526
|
+
const allSelected = keys.length > 0 && keys.every(k => selected.has(k))
|
|
2527
|
+
|
|
2528
|
+
React.useEffect(() => {
|
|
2529
|
+
if (ref.current) {
|
|
2530
|
+
ref.current.indeterminate = keys.some(k => selected.has(k)) && !allSelected
|
|
2531
|
+
}
|
|
2532
|
+
}, [selected, keys, allSelected])
|
|
2533
|
+
|
|
2534
|
+
function onSort(id: string) {
|
|
2535
|
+
const next: Sort | null = sort?.id !== id
|
|
2536
|
+
? { id, direction: 'asc' }
|
|
2537
|
+
: sort.direction === 'asc'
|
|
2538
|
+
? { id, direction: 'desc' }
|
|
2539
|
+
: null
|
|
2540
|
+
setSort(next)
|
|
2541
|
+
if (next) onSortChange?.(next)
|
|
2542
|
+
}
|
|
2543
|
+
|
|
2544
|
+
function setSelection(next: Set<string>) {
|
|
2545
|
+
setSelected(next)
|
|
2546
|
+
onSelectionChange?.(next)
|
|
2547
|
+
}
|
|
2548
|
+
|
|
2549
|
+
function toggle(k: string) {
|
|
2550
|
+
const next = new Set(selected)
|
|
2551
|
+
if (next.has(k)) next.delete(k)
|
|
2552
|
+
else next.add(k)
|
|
2553
|
+
setSelection(next)
|
|
2554
|
+
}
|
|
2555
|
+
|
|
2556
|
+
return (
|
|
2557
|
+
<div className={cn(styles.root, className)}>
|
|
2558
|
+
{toolbar}
|
|
2559
|
+
<Table variant={variant}>
|
|
2560
|
+
<Table.Header>
|
|
2561
|
+
<Table.Row>
|
|
2562
|
+
{selectable && (
|
|
2563
|
+
<Table.Head className={styles.selectCell}>
|
|
2564
|
+
<Checkbox
|
|
2565
|
+
ref={ref}
|
|
2566
|
+
checked={allSelected}
|
|
2567
|
+
onChange={() => setSelection(allSelected ? new Set() : new Set(keys))}
|
|
2568
|
+
/>
|
|
2569
|
+
</Table.Head>
|
|
2570
|
+
)}
|
|
2571
|
+
{columns.map(col => {
|
|
2572
|
+
const active = sort?.id === col.id
|
|
2573
|
+
const Icon = active
|
|
2574
|
+
? sort.direction === 'asc' ? ArrowUp : ArrowDown
|
|
2575
|
+
: ArrowUpDown
|
|
2576
|
+
return (
|
|
2577
|
+
<Table.Head
|
|
2578
|
+
key={col.id}
|
|
2579
|
+
align={col.align}
|
|
2580
|
+
style={col.width ? { width: col.width } : undefined}
|
|
2581
|
+
>
|
|
2582
|
+
{(col.sortable ?? sortable) ? (
|
|
2583
|
+
<button className={styles.sortButton} onClick={() => onSort(col.id)}>
|
|
2584
|
+
{col.header}
|
|
2585
|
+
<Icon className={cn(styles.sortIcon, active && styles.sortIconActive)} />
|
|
2586
|
+
</button>
|
|
2587
|
+
) : (
|
|
2588
|
+
col.header
|
|
2589
|
+
)}
|
|
2590
|
+
</Table.Head>
|
|
2591
|
+
)
|
|
2592
|
+
})}
|
|
2593
|
+
</Table.Row>
|
|
2594
|
+
</Table.Header>
|
|
2595
|
+
<Table.Body>
|
|
2596
|
+
{loading ? (
|
|
2597
|
+
Array.from({ length: 5 }, (_, i) => (
|
|
2598
|
+
<Table.Row key={i}>
|
|
2599
|
+
{columns.map(col => (
|
|
2600
|
+
<Table.Cell key={col.id}>
|
|
2601
|
+
<Skeleton className={styles.skeleton} style={{ width: col.width ?? '60%' }} />
|
|
2602
|
+
</Table.Cell>
|
|
2603
|
+
))}
|
|
2604
|
+
</Table.Row>
|
|
2605
|
+
))
|
|
2606
|
+
) : sorted.length === 0 ? (
|
|
2607
|
+
<Table.Row>
|
|
2608
|
+
<Table.Cell colSpan={columns.length + (selectable ? 1 : 0)}>
|
|
2609
|
+
<div className={styles.empty}>No results.</div>
|
|
2610
|
+
</Table.Cell>
|
|
2611
|
+
</Table.Row>
|
|
2612
|
+
) : (
|
|
2613
|
+
sorted.map(r => {
|
|
2614
|
+
const k = \`\${(r as Row)[rowKey]}\`
|
|
2615
|
+
return (
|
|
2616
|
+
<Table.Row
|
|
2617
|
+
key={k}
|
|
2618
|
+
className={selected.has(k) ? styles.rowSelected : undefined}
|
|
2619
|
+
>
|
|
2620
|
+
{selectable && (
|
|
2621
|
+
<Table.Cell className={styles.selectCell}>
|
|
2622
|
+
<Checkbox checked={selected.has(k)} onChange={() => toggle(k)} />
|
|
2623
|
+
</Table.Cell>
|
|
2624
|
+
)}
|
|
2625
|
+
{columns.map(col => {
|
|
2626
|
+
const v = (r as Row)[col.id]
|
|
2627
|
+
return (
|
|
2628
|
+
<Table.Cell key={col.id} align={col.align}>
|
|
2629
|
+
{col.cell ? col.cell(v, r) : String(v ?? '')}
|
|
2630
|
+
</Table.Cell>
|
|
2631
|
+
)
|
|
2632
|
+
})}
|
|
2633
|
+
</Table.Row>
|
|
2634
|
+
)
|
|
2635
|
+
})
|
|
2636
|
+
)}
|
|
2637
|
+
</Table.Body>
|
|
2638
|
+
</Table>
|
|
2639
|
+
{footer}
|
|
2640
|
+
</div>
|
|
2641
|
+
)
|
|
2642
|
+
}
|
|
2643
|
+
|
|
2644
|
+
function DataTablePagination({
|
|
2645
|
+
page,
|
|
2646
|
+
pageCount,
|
|
2647
|
+
onPageChange,
|
|
2648
|
+
className,
|
|
2649
|
+
}: DataTablePaginationProps) {
|
|
2650
|
+
return (
|
|
2651
|
+
<div className={cn(styles.pagination, className)}>
|
|
2652
|
+
<span className="text-sm text-muted-foreground">
|
|
2653
|
+
Page {page} of {pageCount}
|
|
2654
|
+
</span>
|
|
2655
|
+
<Pagination className="mx-0 w-auto justify-end">
|
|
2656
|
+
<Pagination.Content>
|
|
2657
|
+
<Pagination.Item>
|
|
2658
|
+
<Pagination.Previous
|
|
2659
|
+
onClick={(e) => {
|
|
2660
|
+
e.preventDefault()
|
|
2661
|
+
if (page > 1) onPageChange(page - 1)
|
|
2662
|
+
}}
|
|
2663
|
+
aria-disabled={page <= 1}
|
|
2664
|
+
/>
|
|
2665
|
+
</Pagination.Item>
|
|
2666
|
+
<Pagination.Item>
|
|
2667
|
+
<Pagination.Next
|
|
2668
|
+
onClick={(e) => {
|
|
2669
|
+
e.preventDefault()
|
|
2670
|
+
if (page < pageCount) onPageChange(page + 1)
|
|
2671
|
+
}}
|
|
2672
|
+
aria-disabled={page >= pageCount}
|
|
2673
|
+
/>
|
|
2674
|
+
</Pagination.Item>
|
|
2675
|
+
</Pagination.Content>
|
|
2676
|
+
</Pagination>
|
|
2677
|
+
</div>
|
|
2678
|
+
)
|
|
2679
|
+
}
|
|
2680
|
+
|
|
2681
|
+
export const DataTable = Object.assign(DataTableRoot, {
|
|
2682
|
+
Pagination: DataTablePagination
|
|
2683
|
+
})
|
|
2684
|
+
`;var me=`'use client'
|
|
2685
|
+
|
|
2435
2686
|
import * as React from 'react'
|
|
2436
2687
|
import { X } from 'lucide-react'
|
|
2437
2688
|
import { cn } from '@/utils/cn'
|
|
@@ -2586,7 +2837,7 @@ export const Dialog = Object.assign(DialogRoot, {
|
|
|
2586
2837
|
Trigger,
|
|
2587
2838
|
Content,
|
|
2588
2839
|
})
|
|
2589
|
-
`;var
|
|
2840
|
+
`;var fe=`'use client'
|
|
2590
2841
|
|
|
2591
2842
|
import * as React from 'react'
|
|
2592
2843
|
import { X } from 'lucide-react'
|
|
@@ -2805,7 +3056,7 @@ export const Drawer = Object.assign(DrawerRoot, {
|
|
|
2805
3056
|
Header,
|
|
2806
3057
|
Footer,
|
|
2807
3058
|
})
|
|
2808
|
-
`;var
|
|
3059
|
+
`;var ge=`'use client'
|
|
2809
3060
|
|
|
2810
3061
|
import * as React from 'react'
|
|
2811
3062
|
import { cn } from '@/utils/cn'
|
|
@@ -3003,7 +3254,7 @@ export const Dropdown = Object.assign(DropdownRoot, {
|
|
|
3003
3254
|
Label,
|
|
3004
3255
|
Separator: DropdownSeparator
|
|
3005
3256
|
})
|
|
3006
|
-
`;var
|
|
3257
|
+
`;var be=`import * as React from 'react'
|
|
3007
3258
|
import { cn } from '@/utils/cn'
|
|
3008
3259
|
|
|
3009
3260
|
const styles = {
|
|
@@ -3026,7 +3277,7 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(({
|
|
|
3026
3277
|
)
|
|
3027
3278
|
|
|
3028
3279
|
Input.displayName = 'Input'
|
|
3029
|
-
`;var
|
|
3280
|
+
`;var he=`import * as React from 'react'
|
|
3030
3281
|
import { cn } from '@/utils/cn'
|
|
3031
3282
|
|
|
3032
3283
|
const styles = {
|
|
@@ -3083,7 +3334,7 @@ function Group({
|
|
|
3083
3334
|
}
|
|
3084
3335
|
|
|
3085
3336
|
export const Kbd = Object.assign(KbdRoot, { Group })
|
|
3086
|
-
`;var
|
|
3337
|
+
`;var ve=`import * as React from 'react'
|
|
3087
3338
|
import { cn } from '@/utils/cn'
|
|
3088
3339
|
|
|
3089
3340
|
export function Label({
|
|
@@ -3100,7 +3351,7 @@ export function Label({
|
|
|
3100
3351
|
/>
|
|
3101
3352
|
)
|
|
3102
3353
|
}
|
|
3103
|
-
`;var
|
|
3354
|
+
`;var xe=`'use client'
|
|
3104
3355
|
|
|
3105
3356
|
import * as React from 'react'
|
|
3106
3357
|
import { ChevronDown } from 'lucide-react'
|
|
@@ -3251,7 +3502,7 @@ export const NavigationMenu = Object.assign(NavigationMenuRoot, {
|
|
|
3251
3502
|
Content,
|
|
3252
3503
|
Link
|
|
3253
3504
|
})
|
|
3254
|
-
`;var
|
|
3505
|
+
`;var ye=`import * as React from 'react'
|
|
3255
3506
|
import { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react'
|
|
3256
3507
|
import { cn } from '@/utils/cn'
|
|
3257
3508
|
|
|
@@ -3384,7 +3635,7 @@ export const Pagination = Object.assign(PaginationRoot, {
|
|
|
3384
3635
|
Next,
|
|
3385
3636
|
Ellipsis: PaginationEllipsis,
|
|
3386
3637
|
})
|
|
3387
|
-
`;var
|
|
3638
|
+
`;var Ne=`'use client'
|
|
3388
3639
|
|
|
3389
3640
|
import * as React from 'react'
|
|
3390
3641
|
import { cn } from '@/utils/cn'
|
|
@@ -3451,6 +3702,7 @@ function Trigger({
|
|
|
3451
3702
|
const { open, setOpen } = usePopover()
|
|
3452
3703
|
return (
|
|
3453
3704
|
<Button
|
|
3705
|
+
type="button"
|
|
3454
3706
|
variant="outline"
|
|
3455
3707
|
rounded="md"
|
|
3456
3708
|
className={className}
|
|
@@ -3489,7 +3741,7 @@ export const Popover = Object.assign(PopoverRoot, {
|
|
|
3489
3741
|
Trigger,
|
|
3490
3742
|
Content
|
|
3491
3743
|
})
|
|
3492
|
-
`;var
|
|
3744
|
+
`;var Ce=`import * as React from 'react'
|
|
3493
3745
|
import { cn } from '@/utils/cn'
|
|
3494
3746
|
|
|
3495
3747
|
const styles = {
|
|
@@ -3527,7 +3779,7 @@ export function Progress({
|
|
|
3527
3779
|
</div>
|
|
3528
3780
|
)
|
|
3529
3781
|
}
|
|
3530
|
-
`;var
|
|
3782
|
+
`;var we=`'use client'
|
|
3531
3783
|
|
|
3532
3784
|
import * as React from 'react'
|
|
3533
3785
|
import { cn } from '@/utils/cn'
|
|
@@ -3832,7 +4084,7 @@ export const Select = Object.assign(SelectRoot, {
|
|
|
3832
4084
|
Menu,
|
|
3833
4085
|
Option
|
|
3834
4086
|
})
|
|
3835
|
-
`;var
|
|
4087
|
+
`;var ke=`import * as React from 'react'
|
|
3836
4088
|
import { cn } from '@/utils/cn'
|
|
3837
4089
|
|
|
3838
4090
|
const styles = {
|
|
@@ -3878,7 +4130,7 @@ export function ScrollArea({
|
|
|
3878
4130
|
</div>
|
|
3879
4131
|
)
|
|
3880
4132
|
}
|
|
3881
|
-
`;var
|
|
4133
|
+
`;var Se=`import * as React from 'react'
|
|
3882
4134
|
import { cn } from '@/utils/cn'
|
|
3883
4135
|
|
|
3884
4136
|
const styles = {
|
|
@@ -3919,7 +4171,7 @@ export function Skeleton({
|
|
|
3919
4171
|
/>
|
|
3920
4172
|
)
|
|
3921
4173
|
}
|
|
3922
|
-
`;var
|
|
4174
|
+
`;var Te=`'use client'
|
|
3923
4175
|
|
|
3924
4176
|
import * as React from 'react'
|
|
3925
4177
|
import { ChevronDown, PanelLeft } from 'lucide-react'
|
|
@@ -4350,7 +4602,7 @@ export const Slider = React.forwardRef<HTMLInputElement, SliderProps>(({
|
|
|
4350
4602
|
)
|
|
4351
4603
|
|
|
4352
4604
|
Slider.displayName = 'Slider'
|
|
4353
|
-
`;var
|
|
4605
|
+
`;var Ie=`'use client'
|
|
4354
4606
|
|
|
4355
4607
|
import * as React from 'react'
|
|
4356
4608
|
import { Check } from 'lucide-react'
|
|
@@ -4499,7 +4751,7 @@ function useStepper() {
|
|
|
4499
4751
|
export const Stepper = Object.assign(StepperRoot, {
|
|
4500
4752
|
Item
|
|
4501
4753
|
})
|
|
4502
|
-
`;var
|
|
4754
|
+
`;var Ee=`'use client'
|
|
4503
4755
|
|
|
4504
4756
|
import * as React from 'react'
|
|
4505
4757
|
import { cn } from '@/utils/cn'
|
|
@@ -4541,7 +4793,7 @@ export function Switch({
|
|
|
4541
4793
|
</button>
|
|
4542
4794
|
)
|
|
4543
4795
|
}
|
|
4544
|
-
`;var
|
|
4796
|
+
`;var Le=`'use client'
|
|
4545
4797
|
|
|
4546
4798
|
import * as React from 'react'
|
|
4547
4799
|
import { cn } from '@/utils/cn'
|
|
@@ -4655,7 +4907,7 @@ export const Tabs = Object.assign(TabsRoot, {
|
|
|
4655
4907
|
Tab,
|
|
4656
4908
|
Panel
|
|
4657
4909
|
})
|
|
4658
|
-
`;var
|
|
4910
|
+
`;var Me=`import * as React from 'react'
|
|
4659
4911
|
import { cn } from '@/utils/cn'
|
|
4660
4912
|
|
|
4661
4913
|
const styles = {
|
|
@@ -4682,7 +4934,229 @@ export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(({
|
|
|
4682
4934
|
))
|
|
4683
4935
|
|
|
4684
4936
|
Textarea.displayName = 'Textarea'
|
|
4685
|
-
`;var
|
|
4937
|
+
`;var Oe=`'use client'
|
|
4938
|
+
|
|
4939
|
+
import * as React from 'react'
|
|
4940
|
+
import { Clock } from 'lucide-react'
|
|
4941
|
+
import { cn } from '@/utils/cn'
|
|
4942
|
+
import { Popover } from '@/components/ui/popover'
|
|
4943
|
+
import { Input } from '@/components/ui/input'
|
|
4944
|
+
|
|
4945
|
+
const styles = {
|
|
4946
|
+
base: 'relative block max-w-xs',
|
|
4947
|
+
trigger: cn(
|
|
4948
|
+
'flex items-center gap-2 w-full h-10 px-3',
|
|
4949
|
+
'border border-input rounded-[10px] text-sm',
|
|
4950
|
+
'text-foreground transition-colors',
|
|
4951
|
+
'font-normal hover:scale-100',
|
|
4952
|
+
'focus:outline-none',
|
|
4953
|
+
'disabled:opacity-50 disabled:cursor-default'
|
|
4954
|
+
),
|
|
4955
|
+
placeholder: 'text-muted-foreground',
|
|
4956
|
+
icon: 'w-4 h-4 text-muted-foreground shrink-0',
|
|
4957
|
+
text: 'flex-1 truncate text-left',
|
|
4958
|
+
content: 'p-2',
|
|
4959
|
+
columns: 'flex gap-1',
|
|
4960
|
+
column: cn(
|
|
4961
|
+
'flex flex-col items-center',
|
|
4962
|
+
'h-[220px] overflow-y-auto px-1',
|
|
4963
|
+
'[&::-webkit-scrollbar]:w-1',
|
|
4964
|
+
'[&::-webkit-scrollbar-thumb]:rounded-full',
|
|
4965
|
+
'[&::-webkit-scrollbar-thumb]:bg-border',
|
|
4966
|
+
'[&::-webkit-scrollbar-track]:bg-transparent'
|
|
4967
|
+
),
|
|
4968
|
+
columnLabel: cn(
|
|
4969
|
+
'text-xs font-medium text-muted-foreground',
|
|
4970
|
+
'pb-1'
|
|
4971
|
+
),
|
|
4972
|
+
cell: cn(
|
|
4973
|
+
'flex items-center justify-center w-14 h-12',
|
|
4974
|
+
'text-base rounded-lg hover:bg-accent',
|
|
4975
|
+
'transition-colors cursor-pointer'
|
|
4976
|
+
),
|
|
4977
|
+
cellActive: cn(
|
|
4978
|
+
'bg-foreground text-background font-medium',
|
|
4979
|
+
'hover:bg-foreground hover:text-background'
|
|
4980
|
+
),
|
|
4981
|
+
period: 'flex flex-col gap-0.5 pt-5 pl-1',
|
|
4982
|
+
periodBtn: cn(
|
|
4983
|
+
'flex items-center justify-center w-14 h-12',
|
|
4984
|
+
'text-xs font-medium rounded-lg',
|
|
4985
|
+
'hover:bg-accent transition-colors cursor-pointer'
|
|
4986
|
+
),
|
|
4987
|
+
}
|
|
4988
|
+
|
|
4989
|
+
interface TimePickerProps {
|
|
4990
|
+
selected?: Date
|
|
4991
|
+
onSelect?: (date: Date | undefined) => void
|
|
4992
|
+
format?: '12h' | '24h'
|
|
4993
|
+
showSeconds?: boolean
|
|
4994
|
+
placeholder?: string
|
|
4995
|
+
formatTime?: (date: Date) => string
|
|
4996
|
+
disabled?: boolean
|
|
4997
|
+
className?: string
|
|
4998
|
+
}
|
|
4999
|
+
|
|
5000
|
+
function to24(v: number, period: 'AM' | 'PM' | undefined) {
|
|
5001
|
+
if (!period) return v
|
|
5002
|
+
if (period === 'AM') return v === 12 ? 0 : v
|
|
5003
|
+
return v === 12 ? 12 : v + 12
|
|
5004
|
+
}
|
|
5005
|
+
|
|
5006
|
+
function Column({
|
|
5007
|
+
items,
|
|
5008
|
+
selected,
|
|
5009
|
+
onSelect,
|
|
5010
|
+
label,
|
|
5011
|
+
}: {
|
|
5012
|
+
items: number[]
|
|
5013
|
+
selected: number | undefined
|
|
5014
|
+
onSelect: (v: number) => void
|
|
5015
|
+
label: string
|
|
5016
|
+
}) {
|
|
5017
|
+
const ref = React.useRef<HTMLDivElement>(null)
|
|
5018
|
+
React.useEffect(() => {
|
|
5019
|
+
const col = ref.current
|
|
5020
|
+
const el = col?.querySelector('[data-selected]') as HTMLElement | null
|
|
5021
|
+
if (!col || !el) return
|
|
5022
|
+
col.scrollTop = el.offsetTop - col.offsetTop - col.clientHeight / 2 + el.clientHeight / 2
|
|
5023
|
+
}, [selected])
|
|
5024
|
+
|
|
5025
|
+
return (
|
|
5026
|
+
<div className="flex flex-col items-center">
|
|
5027
|
+
<span className={styles.columnLabel}>{label}</span>
|
|
5028
|
+
<div ref={ref} className={styles.column}>
|
|
5029
|
+
{items.map((v) => (
|
|
5030
|
+
<button
|
|
5031
|
+
key={v}
|
|
5032
|
+
type="button"
|
|
5033
|
+
data-selected={v === selected || undefined}
|
|
5034
|
+
className={cn(
|
|
5035
|
+
styles.cell,
|
|
5036
|
+
v === selected && styles.cellActive
|
|
5037
|
+
)}
|
|
5038
|
+
onClick={() => onSelect(v)}
|
|
5039
|
+
>
|
|
5040
|
+
{String(v).padStart(2, '0')}
|
|
5041
|
+
</button>
|
|
5042
|
+
))}
|
|
5043
|
+
</div>
|
|
5044
|
+
</div>
|
|
5045
|
+
)
|
|
5046
|
+
}
|
|
5047
|
+
|
|
5048
|
+
function TimePickerRoot({
|
|
5049
|
+
selected,
|
|
5050
|
+
onSelect,
|
|
5051
|
+
format = '24h',
|
|
5052
|
+
showSeconds = false,
|
|
5053
|
+
placeholder = 'Pick a time',
|
|
5054
|
+
formatTime,
|
|
5055
|
+
disabled = false,
|
|
5056
|
+
className,
|
|
5057
|
+
}: TimePickerProps) {
|
|
5058
|
+
const is12 = format === '12h'
|
|
5059
|
+
const h = selected?.getHours()
|
|
5060
|
+
const m = selected?.getMinutes()
|
|
5061
|
+
const s = selected?.getSeconds()
|
|
5062
|
+
const period = h !== undefined ? (h >= 12 ? 'PM' : 'AM') : undefined
|
|
5063
|
+
const h12 = h !== undefined ? (h % 12 || 12) : undefined
|
|
5064
|
+
const hours = is12 ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 24 }, (_, i) => i)
|
|
5065
|
+
const values = Array.from({ length: 60 }, (_, i) => i)
|
|
5066
|
+
|
|
5067
|
+
return (
|
|
5068
|
+
<Popover className={cn(styles.base, className)}>
|
|
5069
|
+
<Popover.Trigger disabled={disabled} className={styles.trigger}>
|
|
5070
|
+
<Clock className={styles.icon} />
|
|
5071
|
+
<span className={cn(styles.text, !selected && styles.placeholder)}>
|
|
5072
|
+
{selected ? (formatTime?.(selected) ?? selected.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', ...(showSeconds && { second: '2-digit' }), hour12: is12 })) : placeholder}
|
|
5073
|
+
</span>
|
|
5074
|
+
</Popover.Trigger>
|
|
5075
|
+
<Popover.Content className={styles.content}>
|
|
5076
|
+
<div className={styles.columns}>
|
|
5077
|
+
<Column
|
|
5078
|
+
label="Hr"
|
|
5079
|
+
items={hours}
|
|
5080
|
+
selected={is12 ? h12 : h}
|
|
5081
|
+
onSelect={(v) =>
|
|
5082
|
+
onSelect?.(new Date(0, 0, 0, is12 ? to24(v, period) : v, m ?? 0, s ?? 0))
|
|
5083
|
+
}
|
|
5084
|
+
/>
|
|
5085
|
+
<Column
|
|
5086
|
+
label="Min"
|
|
5087
|
+
items={values}
|
|
5088
|
+
selected={m}
|
|
5089
|
+
onSelect={(v) =>
|
|
5090
|
+
onSelect?.(new Date(0, 0, 0, h ?? 0, v, s ?? 0))
|
|
5091
|
+
}
|
|
5092
|
+
/>
|
|
5093
|
+
{showSeconds && (
|
|
5094
|
+
<Column
|
|
5095
|
+
label="Sec"
|
|
5096
|
+
items={values}
|
|
5097
|
+
selected={s}
|
|
5098
|
+
onSelect={(v) =>
|
|
5099
|
+
onSelect?.(new Date(0, 0, 0, h ?? 0, m ?? 0, v))
|
|
5100
|
+
}
|
|
5101
|
+
/>
|
|
5102
|
+
)}
|
|
5103
|
+
{is12 && (
|
|
5104
|
+
<div className={styles.period}>
|
|
5105
|
+
{(['AM', 'PM'] as const).map((p) => (
|
|
5106
|
+
<button
|
|
5107
|
+
key={p}
|
|
5108
|
+
type="button"
|
|
5109
|
+
className={cn(
|
|
5110
|
+
styles.periodBtn,
|
|
5111
|
+
period === p && styles.cellActive
|
|
5112
|
+
)}
|
|
5113
|
+
onClick={() => onSelect?.(new Date(0, 0, 0, to24(h12 ?? 12, p), m ?? 0, s ?? 0))}
|
|
5114
|
+
>
|
|
5115
|
+
{p}
|
|
5116
|
+
</button>
|
|
5117
|
+
))}
|
|
5118
|
+
</div>
|
|
5119
|
+
)}
|
|
5120
|
+
</div>
|
|
5121
|
+
</Popover.Content>
|
|
5122
|
+
</Popover>
|
|
5123
|
+
)
|
|
5124
|
+
}
|
|
5125
|
+
|
|
5126
|
+
function TimePickerInput({
|
|
5127
|
+
selected,
|
|
5128
|
+
onSelect,
|
|
5129
|
+
className,
|
|
5130
|
+
...props
|
|
5131
|
+
}: Omit<
|
|
5132
|
+
React.InputHTMLAttributes<HTMLInputElement>,
|
|
5133
|
+
'type' | 'onChange' | 'value' | 'onSelect'
|
|
5134
|
+
> & {
|
|
5135
|
+
selected?: Date
|
|
5136
|
+
onSelect?: (date: Date | undefined) => void
|
|
5137
|
+
}) {
|
|
5138
|
+
const value = selected ? String(selected.getHours()).padStart(2, '0') + ':' + String(selected.getMinutes()).padStart(2, '0') : ''
|
|
5139
|
+
|
|
5140
|
+
return (
|
|
5141
|
+
<Input
|
|
5142
|
+
type="time"
|
|
5143
|
+
value={value}
|
|
5144
|
+
onChange={(e) => {
|
|
5145
|
+
const v = (e.target as HTMLInputElement).value
|
|
5146
|
+
if (!v) return onSelect?.(undefined)
|
|
5147
|
+
const [h, m] = v.split(':').map(Number)
|
|
5148
|
+
onSelect?.(new Date(0, 0, 0, h, m))
|
|
5149
|
+
}}
|
|
5150
|
+
className={className}
|
|
5151
|
+
{...props}
|
|
5152
|
+
/>
|
|
5153
|
+
)
|
|
5154
|
+
}
|
|
5155
|
+
|
|
5156
|
+
export const TimePicker = Object.assign(TimePickerRoot, {
|
|
5157
|
+
Input: TimePickerInput
|
|
5158
|
+
})
|
|
5159
|
+
`;var Ae=`'use client'
|
|
4686
5160
|
|
|
4687
5161
|
import * as React from 'react'
|
|
4688
5162
|
import { Toaster as Sonner, toast } from 'sonner'
|
|
@@ -4725,7 +5199,7 @@ function Toaster() {
|
|
|
4725
5199
|
}
|
|
4726
5200
|
|
|
4727
5201
|
export { Toaster, toast }
|
|
4728
|
-
`;var
|
|
5202
|
+
`;var He=`'use client'
|
|
4729
5203
|
|
|
4730
5204
|
import * as React from 'react'
|
|
4731
5205
|
import { cn } from '@/utils/cn'
|
|
@@ -4887,7 +5361,7 @@ const Ctx = React.createContext<ToggleGroupCtx | null>(null)
|
|
|
4887
5361
|
export const Toggle = Object.assign(ToggleButton, {
|
|
4888
5362
|
Group: ToggleGroupRoot,
|
|
4889
5363
|
})
|
|
4890
|
-
`;var
|
|
5364
|
+
`;var Be=`import * as React from 'react'
|
|
4891
5365
|
import { cn } from '@/utils/cn'
|
|
4892
5366
|
|
|
4893
5367
|
const styles = {
|
|
@@ -4896,7 +5370,11 @@ const styles = {
|
|
|
4896
5370
|
variants: {
|
|
4897
5371
|
default: '',
|
|
4898
5372
|
striped: '[&_tbody_tr:nth-child(even)]:bg-muted/30',
|
|
4899
|
-
bordered:
|
|
5373
|
+
bordered: cn(
|
|
5374
|
+
'[&_th]:border [&_td]:border',
|
|
5375
|
+
'[&_th]:border-border [&_td]:border-border',
|
|
5376
|
+
'[&_tbody_tr:nth-child(even)]:bg-muted/30'
|
|
5377
|
+
),
|
|
4900
5378
|
},
|
|
4901
5379
|
caption: 'mt-3 text-sm text-muted-foreground',
|
|
4902
5380
|
header: '[&_tr]:border-b [&_tr]:border-border',
|
|
@@ -5061,7 +5539,7 @@ export const Table = Object.assign(TableRoot, {
|
|
|
5061
5539
|
Head,
|
|
5062
5540
|
Cell,
|
|
5063
5541
|
})
|
|
5064
|
-
`;var
|
|
5542
|
+
`;var je=`import * as React from 'react'
|
|
5065
5543
|
import { cn } from '@/utils/cn'
|
|
5066
5544
|
|
|
5067
5545
|
const styles = {
|
|
@@ -5106,7 +5584,7 @@ export function Tooltip({
|
|
|
5106
5584
|
</span>
|
|
5107
5585
|
)
|
|
5108
5586
|
}
|
|
5109
|
-
`;var
|
|
5587
|
+
`;var ze=`
|
|
5110
5588
|
/* react-day-picker theme integration */
|
|
5111
5589
|
.rdp-root {
|
|
5112
5590
|
--rdp-accent-color: var(--primary);
|
|
@@ -5117,7 +5595,7 @@ export function Tooltip({
|
|
|
5117
5595
|
--rdp-selected-border: none;
|
|
5118
5596
|
--rdp-day_button-border: none;
|
|
5119
5597
|
}
|
|
5120
|
-
`,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:"stepper",description:"Multi-step progress indicator with horizontal/vertical orientation, connecting lines, and dot notation",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:[]}],
|
|
5598
|
+
`,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:"data-table",description:"Data-driven table with sorting, selection, loading, and empty states",dependencies:["table","checkbox","skeleton","pagination"],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:"stepper",description:"Multi-step progress indicator with horizontal/vertical orientation, connecting lines, and dot notation",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:"time-picker",description:"Time picker with scrollable dropdown columns and native input mode",dependencies:["popover","input"],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:[]}],w={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,"data-table":ue,dialog:me,drawer:fe,dropdown:ge,input:be,kbd:he,label:ve,"navigation-menu":xe,pagination:ye,popover:Ne,progress:Ce,"radio-group":we,select:Re,"scroll-area":ke,separator:Se,skeleton:Pe,sidebar:Te,slider:De,stepper:Ie,switch:Ee,table:Be,tabs:Le,textarea:Me,"time-picker":Oe,theme:X,toast:Ae,toggle:He,tooltip:je};async function Ve(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",b=join(r,t.paths.components);for(let o of p){let s=join(b,`${o}.${m}`);if(x(s)){let P=await n.confirm({message:`${o}.${m} exists. Overwrite?`,initialValue:false});if(n.isCancel(P)||!P){n.log.warn(`Skipped ${o}`);continue}}let i=w[o];i=i.replace(/@\/utils/g,`@/${t.paths.utils.replace(/^src\//,"")}`),h(s,i),n.log.success(`${o} \u2192 ${t.paths.components}/${o}.${m}`);}if(l){let o=join(b,`theme-provider.${m}`);if(x(o)){let i=await n.confirm({message:`theme-provider.${m} exists. Overwrite?`,initialValue:false});!n.isCancel(i)&&i?(h(o,w.theme),n.log.success(`theme-provider \u2192 ${t.paths.components}/theme-provider.${m}`)):n.log.warn("Skipped theme-provider");}else h(o,w.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 P=B(i);P.includes('[data-theme="dark"]')?n.log.warn("Theme tokens already exist in globals \u2014 skipped"):(h(i,P+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=B(o);s.includes(".rdp-root")?n.log.warn("Calendar tokens already exist in globals \u2014 skipped"):(h(o,s+ze),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(R(o,s),{cwd:r,stdio:"ignore"}),i.stop("Packages installed");}catch{i.stop("Failed to install packages"),n.log.warn(`Run manually: ${R(o,s)}`);}}n.outro("Done.");}var j=`# Drivn Component Conventions
|
|
5121
5599
|
|
|
5122
5600
|
## Core Philosophy
|
|
5123
5601
|
- **Zero runtime UI deps** \u2014 No Radix, no cva, no external UI primitives. Pure React + Tailwind.
|
|
@@ -5230,13 +5708,13 @@ import { cn } from '@/utils/cn'
|
|
|
5230
5708
|
- Components declare internal deps (other Drivn components)
|
|
5231
5709
|
- Some components need npm packages (react-day-picker, cmdk, embla-carousel-react, sonner)
|
|
5232
5710
|
- The CLI resolves and installs all dependencies automatically
|
|
5233
|
-
`;var L={version:"1.
|
|
5711
|
+
`;var L={version:"1.16.0"};function M(e){return v.find(r=>r.name===e)}function nt(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 _e(){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=w[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=nt(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",b=[];return b.push(`# Install components via CLI
|
|
5234
5712
|
${N} drivn@latest add ${[...d].join(" ")}`),p.size&&b.push(`# Install required npm dependencies
|
|
5235
5713
|
${m} ${[...p].join(" ")}`),b.push(`# Components will be installed to your configured components directory
|
|
5236
5714
|
# (default: src/components/ui/)`),{content:[{type:"text",text:JSON.stringify({componentsToInstall:[...d],npmDependencies:[...p],steps:b},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 === */
|
|
5237
5715
|
${C}
|
|
5238
5716
|
|
|
5239
5717
|
/* === Theme Tokens === */
|
|
5240
|
-
${k}`}]})),e.tool("get_drivn_rules","Get Drivn coding conventions and component patterns",{},async()=>({content:[{type:"text",text:
|
|
5718
|
+
${k}`}]})),e.tool("get_drivn_rules","Get Drivn coding conventions and component patterns",{},async()=>({content:[{type:"text",text:j}]})),e.resource("drivn-rules","drivn://rules",{description:"Drivn coding conventions and component patterns"},async()=>({contents:[{uri:"drivn://rules",mimeType:"text/markdown",text:j}]})),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}
|
|
5241
5719
|
|
|
5242
|
-
${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:
|
|
5720
|
+
${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:w[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(Ve);I.command("mcp").description("Start the Drivn MCP server").action(_e);I.parse();
|