drivn 1.2.0 → 1.3.1
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 +619 -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 e from'@clack/prompts';import i from'picocolors';import {join,dirname}from'path';import {execSync}from'child_process';import {existsSync,readFileSync,writeFileSync,mkdirSync}from'fs';var A={next:"Next.js",react:"React"};function B(t){let n=join(t,"package.json");if(!existsSync(n))throw new Error("package.json not found");let a=JSON.parse(readFileSync(n,"utf-8")),
|
|
2
|
+
import {Command}from'commander';import*as e from'@clack/prompts';import i from'picocolors';import {join,dirname}from'path';import {execSync}from'child_process';import {existsSync,readFileSync,writeFileSync,mkdirSync}from'fs';var A={next:"Next.js",react:"React"};function B(t){let n=join(t,"package.json");if(!existsSync(n))throw new Error("package.json not found");let a=JSON.parse(readFileSync(n,"utf-8")),b={...a.dependencies,...a.devDependencies},p="react";b.next&&(p="next");let g=existsSync(join(t,"src")),u=existsSync(join(t,"tsconfig.json"));return {framework:p,srcDir:g,typescript:u}}var V="drivn.config.json";function _(t){let n=join(t,V);return existsSync(n)?JSON.parse(readFileSync(n,"utf-8")):null}function $(t,n){let a=join(t,V);writeFileSync(a,JSON.stringify(n,null,2));}function Pe(t){existsSync(t)||mkdirSync(t,{recursive:true});}function d(t,n){Pe(dirname(t)),writeFileSync(t,n);}function M(t){return readFileSync(t,"utf-8")}function m(t){return existsSync(t)}function P(t){return existsSync(join(t,"pnpm-lock.yaml"))?"pnpm":"npm"}function y(t,n){let a=n.join(" ");return t==="pnpm"?`pnpm add ${a}`:`npm install ${a}`}function F(t){return t==="pnpm"?"pnpm dlx":"npx"}var D=`@import "tailwindcss";
|
|
3
3
|
|
|
4
4
|
:root {
|
|
5
5
|
/* Surfaces */
|
|
@@ -70,7 +70,7 @@ body {
|
|
|
70
70
|
color: var(--color-foreground);
|
|
71
71
|
font-family: system-ui, -apple-system, sans-serif;
|
|
72
72
|
}
|
|
73
|
-
`,
|
|
73
|
+
`,O=`
|
|
74
74
|
/* Drivn Dark/Light Theme */
|
|
75
75
|
:root,
|
|
76
76
|
[data-theme="dark"] {
|
|
@@ -136,13 +136,13 @@ body {
|
|
|
136
136
|
/* Special Surfaces */
|
|
137
137
|
--overlay: hsl(0 0% 0% / 0.18);
|
|
138
138
|
}
|
|
139
|
-
`;var
|
|
139
|
+
`;var Ee=`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
|
+
`,Le=["src/app/globals.css","src/styles/globals.css","src/styles/globals.scss","app/globals.css"];function Ie(t){for(let n of Le)if(m(join(t,n)))return n;return null}async function G(){let t=process.cwd();console.log(""),console.log(i.bgCyan(i.bold(i.black(" Drivn "))));let n;try{n=B(t),e.log.success(`Detected ${i.cyan(A[n.framework])}`);}catch{e.log.error("No package.json found. Run this command in a project directory."),e.outro("Setup cancelled"),process.exit(1);}if(m(join(t,"drivn.config.json"))){let r=await e.confirm({message:"Config already exists. Overwrite?",initialValue:false});(e.isCancel(r)||!r)&&(e.cancel("Setup cancelled"),process.exit(0));}let a=n.srcDir?"src/components/ui":"components/ui",b=n.srcDir?"src/utils":"utils",p=await e.group({components:()=>e.text({message:"Where should components be installed?",placeholder:a,defaultValue:a}),utils:()=>e.text({message:"Where should utilities be placed?",placeholder:b,defaultValue:b})},{onCancel:()=>{e.cancel("Setup cancelled"),process.exit(0);}}),g={framework:n.framework,typescript:n.typescript,paths:{components:p.components,utils:p.utils},installed:[]},u=n.typescript?"ts":"js",v=join(t,p.utils,`cn.${u}`);m(v)||d(v,Ee);let h=Ie(t);if(h){let r=await e.confirm({message:`Found ${i.cyan(h)}. Add Drivn color tokens?`,initialValue:true});!e.isCancel(r)&&r&&(d(join(t,h),D),g.paths.globals=h,e.log.success(`Color tokens written to ${i.cyan(h)}`));}else {let r=n.srcDir?"src/styles/globals.css":"styles/globals.css",c=await e.text({message:"Where should the globals CSS file be created?",placeholder:r,defaultValue:r});e.isCancel(c)||(d(join(t,c),D),g.paths.globals=c,e.log.success(`Color tokens written to ${i.cyan(c)}`));}$(t,g);let x=P(t),l=F(x),N=["clsx","tailwind-merge","lucide-react"],o=e.spinner();o.start("Installing dependencies");try{execSync(y(x,N),{cwd:t,stdio:"ignore"}),o.stop("Dependencies installed");}catch{o.stop("Failed to install dependencies"),e.log.warn(`Run manually: ${y(x,N)}`);}e.log.info(`Add components with: ${i.cyan(`${l} drivn add button`)}`),e.log.info(`Add dark/light theme: ${i.cyan(`${l} drivn add theme`)}`),e.outro("Drivn initialized");}var K=`'use client'
|
|
146
146
|
|
|
147
147
|
import { ThemeProvider as NextThemesProvider } from 'next-themes'
|
|
148
148
|
|
|
@@ -161,7 +161,7 @@ export function ThemeProvider({
|
|
|
161
161
|
</NextThemesProvider>
|
|
162
162
|
)
|
|
163
163
|
}
|
|
164
|
-
`;var
|
|
164
|
+
`;var Y=`'use client'
|
|
165
165
|
|
|
166
166
|
import * as React from 'react'
|
|
167
167
|
import { ChevronDown } from 'lucide-react'
|
|
@@ -293,7 +293,7 @@ export const Accordion = Object.assign(AccordionRoot, {
|
|
|
293
293
|
Trigger,
|
|
294
294
|
Content
|
|
295
295
|
})
|
|
296
|
-
`;var
|
|
296
|
+
`;var W=`import * as React from 'react'
|
|
297
297
|
import { cn } from '@/utils/cn'
|
|
298
298
|
|
|
299
299
|
const styles = {
|
|
@@ -341,7 +341,7 @@ export function Alert({
|
|
|
341
341
|
</div>
|
|
342
342
|
)
|
|
343
343
|
}
|
|
344
|
-
`;var
|
|
344
|
+
`;var U=`import * as React from 'react'
|
|
345
345
|
import { cn } from '@/utils/cn'
|
|
346
346
|
|
|
347
347
|
const styles = {
|
|
@@ -385,7 +385,7 @@ export function Avatar({
|
|
|
385
385
|
</div>
|
|
386
386
|
)
|
|
387
387
|
}
|
|
388
|
-
`;var
|
|
388
|
+
`;var q=`import * as React from 'react'
|
|
389
389
|
import { cn } from '@/utils/cn'
|
|
390
390
|
|
|
391
391
|
const styles = {
|
|
@@ -415,7 +415,123 @@ export function Badge({ variant = 'default', className, children }: BadgeProps)
|
|
|
415
415
|
</span>
|
|
416
416
|
)
|
|
417
417
|
}
|
|
418
|
-
`;var
|
|
418
|
+
`;var X=`import * as React from 'react'
|
|
419
|
+
import { cn } from '@/utils/cn'
|
|
420
|
+
import { ChevronRight, MoreHorizontal } from 'lucide-react'
|
|
421
|
+
|
|
422
|
+
const styles = {
|
|
423
|
+
list: cn(
|
|
424
|
+
'flex items-center gap-1.5',
|
|
425
|
+
'flex-wrap text-sm text-muted-foreground'
|
|
426
|
+
),
|
|
427
|
+
link: cn(
|
|
428
|
+
'font-medium transition-colors hover:text-foreground',
|
|
429
|
+
'inline-flex items-center gap-1'
|
|
430
|
+
),
|
|
431
|
+
page: 'font-medium text-foreground',
|
|
432
|
+
separator: 'text-muted-foreground/60 [&>svg]:size-3.5',
|
|
433
|
+
ellipsis: cn(
|
|
434
|
+
'flex size-9 items-center justify-center',
|
|
435
|
+
'text-muted-foreground'
|
|
436
|
+
),
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
function BreadcrumbRoot({
|
|
440
|
+
separator,
|
|
441
|
+
className,
|
|
442
|
+
children,
|
|
443
|
+
}: {
|
|
444
|
+
separator?: React.ReactNode
|
|
445
|
+
className?: string
|
|
446
|
+
children: React.ReactNode
|
|
447
|
+
}) {
|
|
448
|
+
return (
|
|
449
|
+
<nav aria-label="Breadcrumb">
|
|
450
|
+
<ol className={cn(styles.list, className)}>
|
|
451
|
+
{React.Children.toArray(children).flatMap((child, i) => {
|
|
452
|
+
return !(React.isValidElement(child) &&
|
|
453
|
+
child.type === BreadcrumbSeparator) && i > 0 ? [
|
|
454
|
+
<BreadcrumbSeparator key={\`sep-\${i}\`}>
|
|
455
|
+
{separator}
|
|
456
|
+
</BreadcrumbSeparator>,
|
|
457
|
+
child,
|
|
458
|
+
] : [child]
|
|
459
|
+
})}
|
|
460
|
+
</ol>
|
|
461
|
+
</nav>
|
|
462
|
+
)
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
function Item({
|
|
466
|
+
href,
|
|
467
|
+
className,
|
|
468
|
+
children,
|
|
469
|
+
...props
|
|
470
|
+
}: React.AnchorHTMLAttributes<HTMLAnchorElement> & {
|
|
471
|
+
href: string
|
|
472
|
+
children: React.ReactNode
|
|
473
|
+
}) {
|
|
474
|
+
return (
|
|
475
|
+
<li>
|
|
476
|
+
<a
|
|
477
|
+
href={href}
|
|
478
|
+
className={cn(styles.link, className)}
|
|
479
|
+
{...props}
|
|
480
|
+
>
|
|
481
|
+
{children}
|
|
482
|
+
</a>
|
|
483
|
+
</li>
|
|
484
|
+
)
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
function Page({
|
|
488
|
+
className,
|
|
489
|
+
children,
|
|
490
|
+
}: {
|
|
491
|
+
className?: string
|
|
492
|
+
children: React.ReactNode
|
|
493
|
+
}) {
|
|
494
|
+
return (
|
|
495
|
+
<li aria-current="page">
|
|
496
|
+
<span className={cn(styles.page, className)}>
|
|
497
|
+
{children}
|
|
498
|
+
</span>
|
|
499
|
+
</li>
|
|
500
|
+
)
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
function BreadcrumbSeparator({
|
|
504
|
+
children,
|
|
505
|
+
}: {
|
|
506
|
+
children?: React.ReactNode
|
|
507
|
+
}) {
|
|
508
|
+
return (
|
|
509
|
+
<li role="presentation" aria-hidden="true">
|
|
510
|
+
<span className={styles.separator}>
|
|
511
|
+
{children ?? <ChevronRight />}
|
|
512
|
+
</span>
|
|
513
|
+
</li>
|
|
514
|
+
)
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
function Ellipsis() {
|
|
518
|
+
return (
|
|
519
|
+
<li>
|
|
520
|
+
<span className={styles.ellipsis}>
|
|
521
|
+
<MoreHorizontal className="size-4" />
|
|
522
|
+
<span className="sr-only">More pages</span>
|
|
523
|
+
</span>
|
|
524
|
+
</li>
|
|
525
|
+
)
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
export const Breadcrumb = Object.assign(BreadcrumbRoot, {
|
|
529
|
+
Item,
|
|
530
|
+
Page,
|
|
531
|
+
Separator: BreadcrumbSeparator,
|
|
532
|
+
Ellipsis,
|
|
533
|
+
})
|
|
534
|
+
`;var J=`import * as React from 'react'
|
|
419
535
|
import { Loader2 } from 'lucide-react'
|
|
420
536
|
import { cn } from '@/utils/cn'
|
|
421
537
|
|
|
@@ -495,7 +611,7 @@ export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(({
|
|
|
495
611
|
)
|
|
496
612
|
|
|
497
613
|
Button.displayName = 'Button'
|
|
498
|
-
`;var
|
|
614
|
+
`;var Q=`'use client'
|
|
499
615
|
|
|
500
616
|
import * as React from 'react'
|
|
501
617
|
import {
|
|
@@ -539,7 +655,7 @@ const styles = {
|
|
|
539
655
|
day: 'p-0 text-center',
|
|
540
656
|
day_button: cn(
|
|
541
657
|
'inline-flex items-center justify-center',
|
|
542
|
-
'w-8 h-8 rounded-md text-sm cursor-pointer',
|
|
658
|
+
'w-8 h-8 rounded-md text-sm font-medium cursor-pointer',
|
|
543
659
|
'hover:bg-accent hover:text-accent-foreground',
|
|
544
660
|
'focus-visible:outline-none'
|
|
545
661
|
),
|
|
@@ -671,7 +787,7 @@ export { type DateRange, type Locale }
|
|
|
671
787
|
export const Calendar = Object.assign(CalendarRoot, {
|
|
672
788
|
Range
|
|
673
789
|
})
|
|
674
|
-
`;var
|
|
790
|
+
`;var Z=`'use client'
|
|
675
791
|
|
|
676
792
|
import * as React from 'react'
|
|
677
793
|
import { CalendarDays } from 'lucide-react'
|
|
@@ -895,7 +1011,7 @@ export { type DateRange, type Locale }
|
|
|
895
1011
|
export const DatePicker = Object.assign(DatePickerRoot, {
|
|
896
1012
|
Range,
|
|
897
1013
|
})
|
|
898
|
-
`;var
|
|
1014
|
+
`;var ee=`'use client'
|
|
899
1015
|
|
|
900
1016
|
import * as React from 'react'
|
|
901
1017
|
import { Command as CommandPrimitive } from 'cmdk'
|
|
@@ -1126,7 +1242,7 @@ export const Command = Object.assign(CommandRoot, {
|
|
|
1126
1242
|
Shortcut,
|
|
1127
1243
|
Dialog: CommandDialog,
|
|
1128
1244
|
})
|
|
1129
|
-
`;var
|
|
1245
|
+
`;var te=`'use client'
|
|
1130
1246
|
|
|
1131
1247
|
import * as React from 'react'
|
|
1132
1248
|
import useEmblaCarousel, { type UseEmblaCarouselType } from 'embla-carousel-react'
|
|
@@ -1375,7 +1491,7 @@ export const Carousel = Object.assign(CarouselRoot, {
|
|
|
1375
1491
|
Next,
|
|
1376
1492
|
Dots
|
|
1377
1493
|
})
|
|
1378
|
-
`;var
|
|
1494
|
+
`;var oe=`import * as React from 'react'
|
|
1379
1495
|
import { cn } from '@/utils/cn'
|
|
1380
1496
|
|
|
1381
1497
|
const styles = {
|
|
@@ -1442,7 +1558,7 @@ export const Card = Object.assign(CardRoot, {
|
|
|
1442
1558
|
Preview,
|
|
1443
1559
|
Info
|
|
1444
1560
|
})
|
|
1445
|
-
`;var
|
|
1561
|
+
`;var ne=`'use client'
|
|
1446
1562
|
|
|
1447
1563
|
import * as React from 'react'
|
|
1448
1564
|
import { Check } from 'lucide-react'
|
|
@@ -1505,7 +1621,7 @@ export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(({
|
|
|
1505
1621
|
)
|
|
1506
1622
|
|
|
1507
1623
|
Checkbox.displayName = 'Checkbox'
|
|
1508
|
-
`;var
|
|
1624
|
+
`;var re=`'use client'
|
|
1509
1625
|
|
|
1510
1626
|
import * as React from 'react'
|
|
1511
1627
|
import { X } from 'lucide-react'
|
|
@@ -1664,7 +1780,7 @@ export const Dialog = Object.assign(DialogRoot, {
|
|
|
1664
1780
|
Content,
|
|
1665
1781
|
Close
|
|
1666
1782
|
})
|
|
1667
|
-
`;var
|
|
1783
|
+
`;var se=`'use client'
|
|
1668
1784
|
|
|
1669
1785
|
import * as React from 'react'
|
|
1670
1786
|
import { cn } from '@/utils/cn'
|
|
@@ -1862,7 +1978,7 @@ export const Dropdown = Object.assign(DropdownRoot, {
|
|
|
1862
1978
|
Label,
|
|
1863
1979
|
Separator: DropdownSeparator
|
|
1864
1980
|
})
|
|
1865
|
-
`;var
|
|
1981
|
+
`;var ae=`import * as React from 'react'
|
|
1866
1982
|
import { cn } from '@/utils/cn'
|
|
1867
1983
|
|
|
1868
1984
|
const styles = {
|
|
@@ -1885,7 +2001,157 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(({
|
|
|
1885
2001
|
)
|
|
1886
2002
|
|
|
1887
2003
|
Input.displayName = 'Input'
|
|
1888
|
-
`;var
|
|
2004
|
+
`;var ce=`import * as React from 'react'
|
|
2005
|
+
import { cn } from '@/utils/cn'
|
|
2006
|
+
|
|
2007
|
+
export function Label({
|
|
2008
|
+
className,
|
|
2009
|
+
...props
|
|
2010
|
+
}: React.LabelHTMLAttributes<HTMLLabelElement>) {
|
|
2011
|
+
return (
|
|
2012
|
+
<label
|
|
2013
|
+
className={cn(
|
|
2014
|
+
'text-sm font-medium text-foreground',
|
|
2015
|
+
className
|
|
2016
|
+
)}
|
|
2017
|
+
{...props}
|
|
2018
|
+
/>
|
|
2019
|
+
)
|
|
2020
|
+
}
|
|
2021
|
+
`;var ie=`import * as React from 'react'
|
|
2022
|
+
import { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react'
|
|
2023
|
+
import { cn } from '@/utils/cn'
|
|
2024
|
+
|
|
2025
|
+
const styles = {
|
|
2026
|
+
nav: 'mx-auto flex w-full justify-center',
|
|
2027
|
+
content: 'flex flex-row items-center gap-1',
|
|
2028
|
+
link: cn(
|
|
2029
|
+
'inline-flex items-center justify-center',
|
|
2030
|
+
'h-9 min-w-9 px-3 rounded-[10px] text-sm font-medium',
|
|
2031
|
+
'text-muted-foreground hover:text-foreground',
|
|
2032
|
+
'hover:bg-accent transition-colors cursor-pointer'
|
|
2033
|
+
),
|
|
2034
|
+
active: cn(
|
|
2035
|
+
'bg-foreground text-background',
|
|
2036
|
+
'hover:bg-foreground hover:text-background'
|
|
2037
|
+
),
|
|
2038
|
+
nav_link: cn(
|
|
2039
|
+
'inline-flex items-center justify-center',
|
|
2040
|
+
'h-9 px-3 gap-1 rounded-[10px] text-sm font-medium',
|
|
2041
|
+
'text-muted-foreground hover:text-foreground',
|
|
2042
|
+
'hover:bg-accent transition-colors cursor-pointer'
|
|
2043
|
+
),
|
|
2044
|
+
ellipsis: cn(
|
|
2045
|
+
'flex h-9 w-9 items-center justify-center',
|
|
2046
|
+
'text-muted-foreground'
|
|
2047
|
+
),
|
|
2048
|
+
}
|
|
2049
|
+
|
|
2050
|
+
function PaginationRoot({
|
|
2051
|
+
className,
|
|
2052
|
+
...props
|
|
2053
|
+
}: React.ComponentProps<'nav'>) {
|
|
2054
|
+
return (
|
|
2055
|
+
<nav
|
|
2056
|
+
role="navigation"
|
|
2057
|
+
aria-label="pagination"
|
|
2058
|
+
className={cn(styles.nav, className)}
|
|
2059
|
+
{...props}
|
|
2060
|
+
/>
|
|
2061
|
+
)
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
function Content({
|
|
2065
|
+
className,
|
|
2066
|
+
...props
|
|
2067
|
+
}: React.ComponentProps<'ul'>) {
|
|
2068
|
+
return (
|
|
2069
|
+
<ul
|
|
2070
|
+
className={cn(styles.content, className)}
|
|
2071
|
+
{...props}
|
|
2072
|
+
/>
|
|
2073
|
+
)
|
|
2074
|
+
}
|
|
2075
|
+
|
|
2076
|
+
function Item({
|
|
2077
|
+
className,
|
|
2078
|
+
...props
|
|
2079
|
+
}: React.ComponentProps<'li'>) {
|
|
2080
|
+
return <li className={className} {...props} />
|
|
2081
|
+
}
|
|
2082
|
+
|
|
2083
|
+
function Link({
|
|
2084
|
+
isActive,
|
|
2085
|
+
className,
|
|
2086
|
+
...props
|
|
2087
|
+
}: React.AnchorHTMLAttributes<HTMLAnchorElement> & {
|
|
2088
|
+
isActive?: boolean
|
|
2089
|
+
}) {
|
|
2090
|
+
return (
|
|
2091
|
+
<a
|
|
2092
|
+
aria-current={isActive ? 'page' : undefined}
|
|
2093
|
+
className={cn(styles.link, isActive && styles.active, className)}
|
|
2094
|
+
{...props}
|
|
2095
|
+
/>
|
|
2096
|
+
)
|
|
2097
|
+
}
|
|
2098
|
+
|
|
2099
|
+
function Previous({
|
|
2100
|
+
className,
|
|
2101
|
+
children,
|
|
2102
|
+
...props
|
|
2103
|
+
}: React.AnchorHTMLAttributes<HTMLAnchorElement>) {
|
|
2104
|
+
return (
|
|
2105
|
+
<a
|
|
2106
|
+
aria-label="Go to previous page"
|
|
2107
|
+
className={cn(styles.nav_link, className)}
|
|
2108
|
+
{...props}
|
|
2109
|
+
>
|
|
2110
|
+
<ChevronLeft className="h-4 w-4" />
|
|
2111
|
+
{children ?? <span>Previous</span>}
|
|
2112
|
+
</a>
|
|
2113
|
+
)
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
function Next({
|
|
2117
|
+
className,
|
|
2118
|
+
children,
|
|
2119
|
+
...props
|
|
2120
|
+
}: React.AnchorHTMLAttributes<HTMLAnchorElement>) {
|
|
2121
|
+
return (
|
|
2122
|
+
<a
|
|
2123
|
+
aria-label="Go to next page"
|
|
2124
|
+
className={cn(styles.nav_link, className)}
|
|
2125
|
+
{...props}
|
|
2126
|
+
>
|
|
2127
|
+
{children ?? <span>Next</span>}
|
|
2128
|
+
<ChevronRight className="h-4 w-4" />
|
|
2129
|
+
</a>
|
|
2130
|
+
)
|
|
2131
|
+
}
|
|
2132
|
+
|
|
2133
|
+
function PaginationEllipsis({
|
|
2134
|
+
className,
|
|
2135
|
+
}: {
|
|
2136
|
+
className?: string
|
|
2137
|
+
}) {
|
|
2138
|
+
return (
|
|
2139
|
+
<span className={cn(styles.ellipsis, className)}>
|
|
2140
|
+
<MoreHorizontal className="h-4 w-4" />
|
|
2141
|
+
<span className="sr-only">More pages</span>
|
|
2142
|
+
</span>
|
|
2143
|
+
)
|
|
2144
|
+
}
|
|
2145
|
+
|
|
2146
|
+
export const Pagination = Object.assign(PaginationRoot, {
|
|
2147
|
+
Content,
|
|
2148
|
+
Item,
|
|
2149
|
+
Link,
|
|
2150
|
+
Previous,
|
|
2151
|
+
Next,
|
|
2152
|
+
Ellipsis: PaginationEllipsis,
|
|
2153
|
+
})
|
|
2154
|
+
`;var le=`'use client'
|
|
1889
2155
|
|
|
1890
2156
|
import * as React from 'react'
|
|
1891
2157
|
import { cn } from '@/utils/cn'
|
|
@@ -1990,7 +2256,7 @@ export const Popover = Object.assign(PopoverRoot, {
|
|
|
1990
2256
|
Trigger,
|
|
1991
2257
|
Content
|
|
1992
2258
|
})
|
|
1993
|
-
`;var
|
|
2259
|
+
`;var de=`import * as React from 'react'
|
|
1994
2260
|
import { cn } from '@/utils/cn'
|
|
1995
2261
|
|
|
1996
2262
|
const styles = {
|
|
@@ -2028,7 +2294,156 @@ export function Progress({
|
|
|
2028
2294
|
</div>
|
|
2029
2295
|
)
|
|
2030
2296
|
}
|
|
2031
|
-
`;var
|
|
2297
|
+
`;var pe=`'use client'
|
|
2298
|
+
|
|
2299
|
+
import * as React from 'react'
|
|
2300
|
+
import { cn } from '@/utils/cn'
|
|
2301
|
+
|
|
2302
|
+
const styles = {
|
|
2303
|
+
group: 'flex flex-col gap-3',
|
|
2304
|
+
horizontal: 'flex-row gap-4',
|
|
2305
|
+
item: 'flex items-start gap-2 cursor-pointer',
|
|
2306
|
+
radio: cn(
|
|
2307
|
+
'aspect-square w-4 mt-[3px] border border-input shadow-xs',
|
|
2308
|
+
'transition-[color,box-shadow] flex-shrink-0',
|
|
2309
|
+
'flex items-center justify-center',
|
|
2310
|
+
'peer-focus-visible:ring-[3px]',
|
|
2311
|
+
'peer-focus-visible:ring-ring/50',
|
|
2312
|
+
'peer-focus-visible:border-ring'
|
|
2313
|
+
),
|
|
2314
|
+
checked: 'bg-foreground border-foreground',
|
|
2315
|
+
indicator: 'w-2 h-2 bg-background',
|
|
2316
|
+
label: 'text-sm font-medium text-foreground select-none',
|
|
2317
|
+
description: 'text-sm text-muted-foreground select-none',
|
|
2318
|
+
variants: {
|
|
2319
|
+
circle: 'rounded-full',
|
|
2320
|
+
square: 'rounded-[4px]',
|
|
2321
|
+
},
|
|
2322
|
+
indicators: {
|
|
2323
|
+
circle: 'rounded-full',
|
|
2324
|
+
square: 'rounded-[2px]',
|
|
2325
|
+
},
|
|
2326
|
+
}
|
|
2327
|
+
|
|
2328
|
+
interface RadioGroupCtx {
|
|
2329
|
+
value: string
|
|
2330
|
+
onSelect: (v: string) => void
|
|
2331
|
+
disabled?: boolean
|
|
2332
|
+
variant: 'circle' | 'square'
|
|
2333
|
+
}
|
|
2334
|
+
|
|
2335
|
+
function RadioGroupRoot({
|
|
2336
|
+
children,
|
|
2337
|
+
defaultValue,
|
|
2338
|
+
value: controlledValue,
|
|
2339
|
+
onValueChange,
|
|
2340
|
+
orientation = 'vertical',
|
|
2341
|
+
variant = 'circle',
|
|
2342
|
+
disabled,
|
|
2343
|
+
className,
|
|
2344
|
+
}: {
|
|
2345
|
+
children: React.ReactNode
|
|
2346
|
+
defaultValue?: string
|
|
2347
|
+
value?: string
|
|
2348
|
+
onValueChange?: (value: string) => void
|
|
2349
|
+
orientation?: 'vertical' | 'horizontal'
|
|
2350
|
+
variant?: 'circle' | 'square'
|
|
2351
|
+
disabled?: boolean
|
|
2352
|
+
className?: string
|
|
2353
|
+
}) {
|
|
2354
|
+
const [internal, setInternal] = React.useState(
|
|
2355
|
+
defaultValue ?? ''
|
|
2356
|
+
)
|
|
2357
|
+
const isControlled = controlledValue !== undefined
|
|
2358
|
+
const current = isControlled ? controlledValue : internal
|
|
2359
|
+
|
|
2360
|
+
const onSelect = (v: string) => {
|
|
2361
|
+
if (!isControlled) setInternal(v)
|
|
2362
|
+
onValueChange?.(v)
|
|
2363
|
+
}
|
|
2364
|
+
|
|
2365
|
+
return (
|
|
2366
|
+
<Ctx.Provider value={{ value: current, onSelect, disabled, variant }}>
|
|
2367
|
+
<div
|
|
2368
|
+
role="radiogroup"
|
|
2369
|
+
className={cn(
|
|
2370
|
+
styles.group,
|
|
2371
|
+
orientation === 'horizontal' && styles.horizontal,
|
|
2372
|
+
className
|
|
2373
|
+
)}
|
|
2374
|
+
>
|
|
2375
|
+
{children}
|
|
2376
|
+
</div>
|
|
2377
|
+
</Ctx.Provider>
|
|
2378
|
+
)
|
|
2379
|
+
}
|
|
2380
|
+
|
|
2381
|
+
const Item = React.forwardRef<
|
|
2382
|
+
HTMLInputElement,
|
|
2383
|
+
{
|
|
2384
|
+
value: string
|
|
2385
|
+
label?: string
|
|
2386
|
+
description?: string
|
|
2387
|
+
children?: React.ReactNode
|
|
2388
|
+
disabled?: boolean
|
|
2389
|
+
className?: string
|
|
2390
|
+
} & Omit<
|
|
2391
|
+
React.InputHTMLAttributes<HTMLInputElement>,
|
|
2392
|
+
'type' | 'value'
|
|
2393
|
+
>
|
|
2394
|
+
>(({ value, label, description, children, disabled, className, ...props }, ref) => {
|
|
2395
|
+
const ctx = useRadioGroup()
|
|
2396
|
+
const isDisabled = disabled ?? ctx.disabled
|
|
2397
|
+
const isChecked = ctx.value === value
|
|
2398
|
+
|
|
2399
|
+
return (
|
|
2400
|
+
<label
|
|
2401
|
+
className={cn(
|
|
2402
|
+
styles.item,
|
|
2403
|
+
isDisabled && 'opacity-50 cursor-not-allowed',
|
|
2404
|
+
className
|
|
2405
|
+
)}
|
|
2406
|
+
>
|
|
2407
|
+
<input
|
|
2408
|
+
ref={ref}
|
|
2409
|
+
type="radio"
|
|
2410
|
+
className="peer sr-only"
|
|
2411
|
+
checked={isChecked}
|
|
2412
|
+
disabled={isDisabled}
|
|
2413
|
+
onChange={() => {
|
|
2414
|
+
if (!isDisabled) ctx.onSelect(value)
|
|
2415
|
+
}}
|
|
2416
|
+
{...props}
|
|
2417
|
+
/>
|
|
2418
|
+
<span className={cn(styles.radio, styles.variants[ctx.variant], isChecked && styles.checked)}>
|
|
2419
|
+
{isChecked && <span className={cn(styles.indicator, styles.indicators[ctx.variant])} />}
|
|
2420
|
+
</span>
|
|
2421
|
+
{children ?? (label && (
|
|
2422
|
+
<div className="flex flex-col gap-0.5">
|
|
2423
|
+
<span className={styles.label}>{label}</span>
|
|
2424
|
+
{description && (
|
|
2425
|
+
<span className={styles.description}>
|
|
2426
|
+
{description}
|
|
2427
|
+
</span>
|
|
2428
|
+
)}
|
|
2429
|
+
</div>
|
|
2430
|
+
))}
|
|
2431
|
+
</label>
|
|
2432
|
+
)
|
|
2433
|
+
})
|
|
2434
|
+
|
|
2435
|
+
Item.displayName = 'RadioGroup.Item'
|
|
2436
|
+
|
|
2437
|
+
const Ctx = React.createContext<RadioGroupCtx | null>(null)
|
|
2438
|
+
|
|
2439
|
+
function useRadioGroup() {
|
|
2440
|
+
const ctx = React.useContext(Ctx)
|
|
2441
|
+
if (!ctx) throw new Error('RadioGroup compound used outside <RadioGroup>')
|
|
2442
|
+
return ctx
|
|
2443
|
+
}
|
|
2444
|
+
|
|
2445
|
+
export const RadioGroup = Object.assign(RadioGroupRoot, { Item })
|
|
2446
|
+
`;var ue=`'use client'
|
|
2032
2447
|
|
|
2033
2448
|
import * as React from 'react'
|
|
2034
2449
|
import { ChevronDown } from 'lucide-react'
|
|
@@ -2182,7 +2597,7 @@ export const Select = Object.assign(SelectRoot, {
|
|
|
2182
2597
|
Menu,
|
|
2183
2598
|
Option
|
|
2184
2599
|
})
|
|
2185
|
-
`;var
|
|
2600
|
+
`;var me=`import * as React from 'react'
|
|
2186
2601
|
import { cn } from '@/utils/cn'
|
|
2187
2602
|
|
|
2188
2603
|
const styles = {
|
|
@@ -2206,7 +2621,7 @@ export function Separator({
|
|
|
2206
2621
|
/>
|
|
2207
2622
|
)
|
|
2208
2623
|
}
|
|
2209
|
-
`;var
|
|
2624
|
+
`;var fe=`'use client'
|
|
2210
2625
|
|
|
2211
2626
|
import * as React from 'react'
|
|
2212
2627
|
import { cn } from '@/utils/cn'
|
|
@@ -2247,7 +2662,7 @@ export function Switch({
|
|
|
2247
2662
|
</button>
|
|
2248
2663
|
)
|
|
2249
2664
|
}
|
|
2250
|
-
`;var
|
|
2665
|
+
`;var ge=`'use client'
|
|
2251
2666
|
|
|
2252
2667
|
import * as React from 'react'
|
|
2253
2668
|
import { cn } from '@/utils/cn'
|
|
@@ -2361,7 +2776,7 @@ export const Tabs = Object.assign(TabsRoot, {
|
|
|
2361
2776
|
Tab,
|
|
2362
2777
|
Panel
|
|
2363
2778
|
})
|
|
2364
|
-
`;var
|
|
2779
|
+
`;var he=`import * as React from 'react'
|
|
2365
2780
|
import { cn } from '@/utils/cn'
|
|
2366
2781
|
|
|
2367
2782
|
const styles = {
|
|
@@ -2388,7 +2803,7 @@ export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(({
|
|
|
2388
2803
|
))
|
|
2389
2804
|
|
|
2390
2805
|
Textarea.displayName = 'Textarea'
|
|
2391
|
-
`;var
|
|
2806
|
+
`;var be=`'use client'
|
|
2392
2807
|
|
|
2393
2808
|
import * as React from 'react'
|
|
2394
2809
|
import { Toaster as Sonner, toast } from 'sonner'
|
|
@@ -2431,7 +2846,181 @@ function Toaster() {
|
|
|
2431
2846
|
}
|
|
2432
2847
|
|
|
2433
2848
|
export { Toaster, toast }
|
|
2434
|
-
`;var
|
|
2849
|
+
`;var ve=`import * as React from 'react'
|
|
2850
|
+
import { cn } from '@/utils/cn'
|
|
2851
|
+
|
|
2852
|
+
const styles = {
|
|
2853
|
+
wrapper: 'w-full overflow-x-auto',
|
|
2854
|
+
base: 'w-full caption-bottom text-sm border-collapse',
|
|
2855
|
+
variants: {
|
|
2856
|
+
default: '',
|
|
2857
|
+
striped: '[&_tbody_tr:nth-child(even)]:bg-muted/30',
|
|
2858
|
+
bordered: '[&_th]:border [&_td]:border',
|
|
2859
|
+
},
|
|
2860
|
+
caption: 'mt-3 text-sm text-muted-foreground',
|
|
2861
|
+
header: '[&_tr]:border-b [&_tr]:border-border',
|
|
2862
|
+
body: '[&_tr:last-child]:border-0',
|
|
2863
|
+
footer: 'border-t border-border bg-muted/30 font-medium',
|
|
2864
|
+
row: 'border-b border-border transition-colors hover:bg-muted/40',
|
|
2865
|
+
head: cn(
|
|
2866
|
+
'px-4 py-2.5 text-left font-semibold',
|
|
2867
|
+
'text-muted-foreground',
|
|
2868
|
+
'[&[align=center]]:text-center',
|
|
2869
|
+
'[&[align=right]]:text-right'
|
|
2870
|
+
),
|
|
2871
|
+
cell: cn(
|
|
2872
|
+
'px-4 py-2.5 text-foreground',
|
|
2873
|
+
'[&[align=center]]:text-center',
|
|
2874
|
+
'[&[align=right]]:text-right'
|
|
2875
|
+
),
|
|
2876
|
+
}
|
|
2877
|
+
|
|
2878
|
+
function TableRoot({
|
|
2879
|
+
variant = 'default',
|
|
2880
|
+
className,
|
|
2881
|
+
children,
|
|
2882
|
+
...props
|
|
2883
|
+
}: {
|
|
2884
|
+
variant?: keyof typeof styles.variants
|
|
2885
|
+
className?: string
|
|
2886
|
+
children: React.ReactNode
|
|
2887
|
+
} & Omit<
|
|
2888
|
+
React.ComponentPropsWithoutRef<'table'>,
|
|
2889
|
+
'className' | 'children'
|
|
2890
|
+
>) {
|
|
2891
|
+
return (
|
|
2892
|
+
<div className={styles.wrapper}>
|
|
2893
|
+
<table
|
|
2894
|
+
className={cn(
|
|
2895
|
+
styles.base,
|
|
2896
|
+
styles.variants[variant],
|
|
2897
|
+
className
|
|
2898
|
+
)}
|
|
2899
|
+
{...props}
|
|
2900
|
+
>
|
|
2901
|
+
{children}
|
|
2902
|
+
</table>
|
|
2903
|
+
</div>
|
|
2904
|
+
)
|
|
2905
|
+
}
|
|
2906
|
+
|
|
2907
|
+
function Caption({
|
|
2908
|
+
className,
|
|
2909
|
+
children,
|
|
2910
|
+
...props
|
|
2911
|
+
}: React.ComponentPropsWithoutRef<'caption'>) {
|
|
2912
|
+
return (
|
|
2913
|
+
<caption
|
|
2914
|
+
className={cn(styles.caption, className)}
|
|
2915
|
+
{...props}
|
|
2916
|
+
>
|
|
2917
|
+
{children}
|
|
2918
|
+
</caption>
|
|
2919
|
+
)
|
|
2920
|
+
}
|
|
2921
|
+
|
|
2922
|
+
function Header({
|
|
2923
|
+
className,
|
|
2924
|
+
children,
|
|
2925
|
+
...props
|
|
2926
|
+
}: React.ComponentPropsWithoutRef<'thead'>) {
|
|
2927
|
+
return (
|
|
2928
|
+
<thead
|
|
2929
|
+
className={cn(styles.header, className)}
|
|
2930
|
+
{...props}
|
|
2931
|
+
>
|
|
2932
|
+
{children}
|
|
2933
|
+
</thead>
|
|
2934
|
+
)
|
|
2935
|
+
}
|
|
2936
|
+
|
|
2937
|
+
function Body({
|
|
2938
|
+
className,
|
|
2939
|
+
children,
|
|
2940
|
+
...props
|
|
2941
|
+
}: React.ComponentPropsWithoutRef<'tbody'>) {
|
|
2942
|
+
return (
|
|
2943
|
+
<tbody
|
|
2944
|
+
className={cn(styles.body, className)}
|
|
2945
|
+
{...props}
|
|
2946
|
+
>
|
|
2947
|
+
{children}
|
|
2948
|
+
</tbody>
|
|
2949
|
+
)
|
|
2950
|
+
}
|
|
2951
|
+
|
|
2952
|
+
function Footer({
|
|
2953
|
+
className,
|
|
2954
|
+
children,
|
|
2955
|
+
...props
|
|
2956
|
+
}: React.ComponentPropsWithoutRef<'tfoot'>) {
|
|
2957
|
+
return (
|
|
2958
|
+
<tfoot
|
|
2959
|
+
className={cn(styles.footer, className)}
|
|
2960
|
+
{...props}
|
|
2961
|
+
>
|
|
2962
|
+
{children}
|
|
2963
|
+
</tfoot>
|
|
2964
|
+
)
|
|
2965
|
+
}
|
|
2966
|
+
|
|
2967
|
+
function Row({
|
|
2968
|
+
className,
|
|
2969
|
+
children,
|
|
2970
|
+
...props
|
|
2971
|
+
}: React.ComponentPropsWithoutRef<'tr'>) {
|
|
2972
|
+
return (
|
|
2973
|
+
<tr
|
|
2974
|
+
className={cn(styles.row, className)}
|
|
2975
|
+
{...props}
|
|
2976
|
+
>
|
|
2977
|
+
{children}
|
|
2978
|
+
</tr>
|
|
2979
|
+
)
|
|
2980
|
+
}
|
|
2981
|
+
|
|
2982
|
+
function Head({
|
|
2983
|
+
scope = 'col',
|
|
2984
|
+
className,
|
|
2985
|
+
children,
|
|
2986
|
+
...props
|
|
2987
|
+
}: React.ComponentPropsWithoutRef<'th'>) {
|
|
2988
|
+
return (
|
|
2989
|
+
<th
|
|
2990
|
+
scope={scope}
|
|
2991
|
+
className={cn(styles.head, className)}
|
|
2992
|
+
{...props}
|
|
2993
|
+
>
|
|
2994
|
+
{children}
|
|
2995
|
+
</th>
|
|
2996
|
+
)
|
|
2997
|
+
}
|
|
2998
|
+
|
|
2999
|
+
function Cell({
|
|
3000
|
+
className,
|
|
3001
|
+
children,
|
|
3002
|
+
...props
|
|
3003
|
+
}: React.ComponentPropsWithoutRef<'td'>) {
|
|
3004
|
+
return (
|
|
3005
|
+
<td
|
|
3006
|
+
className={cn(styles.cell, className)}
|
|
3007
|
+
{...props}
|
|
3008
|
+
>
|
|
3009
|
+
{children}
|
|
3010
|
+
</td>
|
|
3011
|
+
)
|
|
3012
|
+
}
|
|
3013
|
+
|
|
3014
|
+
export const Table = Object.assign(TableRoot, {
|
|
3015
|
+
Caption,
|
|
3016
|
+
Header,
|
|
3017
|
+
Body,
|
|
3018
|
+
Footer,
|
|
3019
|
+
Row,
|
|
3020
|
+
Head,
|
|
3021
|
+
Cell,
|
|
3022
|
+
})
|
|
3023
|
+
`;var xe=`import * as React from 'react'
|
|
2435
3024
|
import { cn } from '@/utils/cn'
|
|
2436
3025
|
|
|
2437
3026
|
const styles = {
|
|
@@ -2476,7 +3065,7 @@ export function Tooltip({
|
|
|
2476
3065
|
</span>
|
|
2477
3066
|
)
|
|
2478
3067
|
}
|
|
2479
|
-
`;var
|
|
3068
|
+
`;var ye=`
|
|
2480
3069
|
/* react-day-picker theme integration */
|
|
2481
3070
|
.rdp-root {
|
|
2482
3071
|
--rdp-accent-color: var(--primary);
|
|
@@ -2487,4 +3076,4 @@ export function Tooltip({
|
|
|
2487
3076
|
--rdp-selected-border: none;
|
|
2488
3077
|
--rdp-day_button-border: none;
|
|
2489
3078
|
}
|
|
2490
|
-
`,
|
|
3079
|
+
`,w=[{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:"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:"dialog",description:"Modal dialog with dot notation, overlay, and escape key",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:"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:"separator",description:"Visual divider with horizontal and vertical orientation",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:"tooltip",description:"Pure CSS tooltip with 4 position options",dependencies:[],npmDependencies:[]}],S={accordion:Y,alert:W,avatar:U,badge:q,breadcrumb:X,button:J,calendar:Q,"date-picker":Z,command:ee,carousel:te,card:oe,checkbox:ne,dialog:re,dropdown:se,input:ae,label:ce,pagination:ie,popover:le,progress:de,"radio-group":pe,select:ue,separator:me,switch:fe,table:ve,tabs:ge,textarea:he,theme:K,toast:be,tooltip:xe};async function Ne(t){let n=process.cwd();e.intro("drivn add");let a=_(n);if(a||(e.log.error("Drivn is not initialized. Run npx drivn@latest create"),e.outro("Cancelled"),process.exit(1)),!t||!t.length){let o=await e.multiselect({message:"Select components to add",options:w.map(r=>({label:r.name,hint:r.description,value:r.name})),required:true});e.isCancel(o)&&(e.cancel("Cancelled"),process.exit(0)),t=o;}let b=t.filter(o=>!w.find(r=>r.name===o));b.length&&(e.log.error(`Unknown components: ${b.join(", ")}`),e.log.info("Available: "+w.map(o=>o.name).join(", ")),e.outro("Cancelled"),process.exit(1));let p=t.includes("theme"),g=t.filter(o=>o!=="theme"),u=new Set,v=new Set,h=o=>{if(u.has(o))return;let r=w.find(c=>c.name===o);r&&(r.dependencies.forEach(c=>h(c)),r.npmDependencies?.forEach(c=>v.add(c)),u.add(o));};g.forEach(h),p&&v.add("next-themes");let x=[...u].filter(o=>!g.includes(o));x.length&&e.log.info(`Required dependency: ${x.join(", ")}`);let l=a.typescript?"tsx":"jsx",N=join(n,a.paths.components);for(let o of u){let r=join(N,`${o}.${l}`);if(m(r)){let C=await e.confirm({message:`${o}.${l} exists. Overwrite?`,initialValue:false});if(e.isCancel(C)||!C){e.log.warn(`Skipped ${o}`);continue}}let c=S[o];c=c.replace(/@\/utils/g,`@/${a.paths.utils.replace(/^src\//,"")}`),d(r,c),e.log.success(`${o} \u2192 ${a.paths.components}/${o}.${l}`);}if(p){let o=join(N,`theme-provider.${l}`);if(m(o)){let c=await e.confirm({message:`theme-provider.${l} exists. Overwrite?`,initialValue:false});!e.isCancel(c)&&c?(d(o,S.theme),e.log.success(`theme-provider \u2192 ${a.paths.components}/theme-provider.${l}`)):e.log.warn("Skipped theme-provider");}else d(o,S.theme),e.log.success(`theme-provider \u2192 ${a.paths.components}/theme-provider.${l}`);if(a.paths.globals){let c=join(n,a.paths.globals);if(m(c)){let C=M(c);C.includes('[data-theme="dark"]')?e.log.warn("Theme tokens already exist in globals \u2014 skipped"):(d(c,C+O),e.log.success(`Theme tokens appended to ${i.cyan(a.paths.globals)}`));}else e.log.warn(`Globals file not found at ${a.paths.globals}`);}else e.log.warn('No globals path in drivn.config.json. Add "globals" to paths');let r=a.paths.components.replace(/^src\//,"@/");e.log.message(""),e.log.info(i.bold("Complete the setup:")),e.log.message(""),e.log.message(i.bold(`${i.cyan("1.")} Import ThemeProvider in your root layout:`)),e.log.message(i.cyan(` import { ThemeProvider } from "${r}/theme-provider"`)),e.log.message(""),e.log.message(i.bold(`${i.cyan("2.")} Add suppressHydrationWarning to <html>:`)),e.log.message(i.cyan(" <html suppressHydrationWarning>")),e.log.message(""),e.log.message(i.bold(`${i.cyan("3.")} Wrap your app with ThemeProvider:`)),e.log.message(i.cyan(" <ThemeProvider>")),e.log.message(i.cyan(" {children}")),e.log.message(i.cyan(" </ThemeProvider>")),e.log.message("");}if(u.has("calendar")&&a.paths.globals){let o=join(n,a.paths.globals);if(m(o)){let r=M(o);r.includes(".rdp-root")?e.log.warn("Calendar tokens already exist in globals \u2014 skipped"):(d(o,r+ye),e.log.success(`Calendar tokens appended to ${i.cyan(a.paths.globals)}`));}}if(v.size){let o=P(n),r=[...v],c=e.spinner();c.start("Installing packages");try{execSync(y(o,r),{cwd:n,stdio:"ignore"}),c.stop("Packages installed");}catch{c.stop("Failed to install packages"),e.log.warn(`Run manually: ${y(o,r)}`);}}e.outro("Done.");}var Ce={version:"1.3.1"};var T=new Command;T.name("drivn").description("Drivn \u2014 Modern UI components").version(Ce.version);T.command("create").description("Initialize Drivn in your project").action(G);T.command("add [components...]").description("Add components to your project").action(Ne);T.parse();
|