drivn 1.3.0 → 1.4.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 +81 -24
- 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")),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
|
|
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 De(t){existsSync(t)||mkdirSync(t,{recursive:true});}function d(t,n){De(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 */
|
|
@@ -136,13 +136,13 @@ body {
|
|
|
136
136
|
/* Special Surfaces */
|
|
137
137
|
--overlay: hsl(0 0% 0% / 0.18);
|
|
138
138
|
}
|
|
139
|
-
`;var
|
|
139
|
+
`;var Le=`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
|
+
`,Ie=["src/app/globals.css","src/styles/globals.css","src/styles/globals.scss","app/globals.css"];function Me(t){for(let n of Ie)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,Le);let h=Me(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
|
|
|
@@ -425,7 +425,7 @@ const styles = {
|
|
|
425
425
|
'flex-wrap text-sm text-muted-foreground'
|
|
426
426
|
),
|
|
427
427
|
link: cn(
|
|
428
|
-
'transition-colors hover:text-foreground',
|
|
428
|
+
'font-medium transition-colors hover:text-foreground',
|
|
429
429
|
'inline-flex items-center gap-1'
|
|
430
430
|
),
|
|
431
431
|
page: 'font-medium text-foreground',
|
|
@@ -655,7 +655,7 @@ const styles = {
|
|
|
655
655
|
day: 'p-0 text-center',
|
|
656
656
|
day_button: cn(
|
|
657
657
|
'inline-flex items-center justify-center',
|
|
658
|
-
'w-8 h-8 rounded-md text-sm cursor-pointer',
|
|
658
|
+
'w-8 h-8 rounded-md text-sm font-medium cursor-pointer',
|
|
659
659
|
'hover:bg-accent hover:text-accent-foreground',
|
|
660
660
|
'focus-visible:outline-none'
|
|
661
661
|
),
|
|
@@ -1496,14 +1496,14 @@ import { cn } from '@/utils/cn'
|
|
|
1496
1496
|
|
|
1497
1497
|
const styles = {
|
|
1498
1498
|
base: cn(
|
|
1499
|
+
'w-48 aspect-square flex flex-col',
|
|
1499
1500
|
'bg-card border border-border rounded-[20px]',
|
|
1500
1501
|
'overflow-hidden transition-all duration-200'
|
|
1501
1502
|
),
|
|
1502
1503
|
hover: 'hover:bg-accent hover:border-border hover:-translate-y-1',
|
|
1503
1504
|
preview: cn(
|
|
1504
|
-
'
|
|
1505
|
-
'border-b border-border p-6'
|
|
1506
|
-
'bg-[radial-gradient(ellipse_at_50%_50%,hsl(239_84%_67%_/_0.08)_0%,transparent_70%)]'
|
|
1505
|
+
'flex-1 flex items-center justify-center',
|
|
1506
|
+
'border-b border-border p-6'
|
|
1507
1507
|
),
|
|
1508
1508
|
info: 'p-5 flex justify-between items-center',
|
|
1509
1509
|
}
|
|
@@ -2004,6 +2004,63 @@ Input.displayName = 'Input'
|
|
|
2004
2004
|
`;var ce=`import * as React from 'react'
|
|
2005
2005
|
import { cn } from '@/utils/cn'
|
|
2006
2006
|
|
|
2007
|
+
const styles = {
|
|
2008
|
+
base: cn(
|
|
2009
|
+
'pointer-events-none inline-flex items-center',
|
|
2010
|
+
'justify-center select-none',
|
|
2011
|
+
'h-5 w-fit min-w-5 gap-1 rounded-sm px-1',
|
|
2012
|
+
'font-mono text-xs font-medium',
|
|
2013
|
+
'[&_svg:not([class*=size-])]:size-3'
|
|
2014
|
+
),
|
|
2015
|
+
variants: {
|
|
2016
|
+
default: 'bg-muted text-muted-foreground',
|
|
2017
|
+
outline: 'border border-border text-muted-foreground',
|
|
2018
|
+
},
|
|
2019
|
+
group: 'inline-flex items-center gap-1',
|
|
2020
|
+
}
|
|
2021
|
+
|
|
2022
|
+
interface KbdProps {
|
|
2023
|
+
variant?: keyof typeof styles.variants
|
|
2024
|
+
className?: string
|
|
2025
|
+
children: React.ReactNode
|
|
2026
|
+
}
|
|
2027
|
+
|
|
2028
|
+
function KbdRoot({
|
|
2029
|
+
variant = 'default',
|
|
2030
|
+
className,
|
|
2031
|
+
children,
|
|
2032
|
+
}: KbdProps) {
|
|
2033
|
+
return (
|
|
2034
|
+
<kbd
|
|
2035
|
+
className={cn(
|
|
2036
|
+
styles.base,
|
|
2037
|
+
styles.variants[variant],
|
|
2038
|
+
className,
|
|
2039
|
+
)}
|
|
2040
|
+
>
|
|
2041
|
+
{children}
|
|
2042
|
+
</kbd>
|
|
2043
|
+
)
|
|
2044
|
+
}
|
|
2045
|
+
|
|
2046
|
+
function Group({
|
|
2047
|
+
className,
|
|
2048
|
+
children,
|
|
2049
|
+
}: {
|
|
2050
|
+
className?: string
|
|
2051
|
+
children: React.ReactNode
|
|
2052
|
+
}) {
|
|
2053
|
+
return (
|
|
2054
|
+
<kbd className={cn(styles.group, className)}>
|
|
2055
|
+
{children}
|
|
2056
|
+
</kbd>
|
|
2057
|
+
)
|
|
2058
|
+
}
|
|
2059
|
+
|
|
2060
|
+
export const Kbd = Object.assign(KbdRoot, { Group })
|
|
2061
|
+
`;var ie=`import * as React from 'react'
|
|
2062
|
+
import { cn } from '@/utils/cn'
|
|
2063
|
+
|
|
2007
2064
|
export function Label({
|
|
2008
2065
|
className,
|
|
2009
2066
|
...props
|
|
@@ -2018,7 +2075,7 @@ export function Label({
|
|
|
2018
2075
|
/>
|
|
2019
2076
|
)
|
|
2020
2077
|
}
|
|
2021
|
-
`;var
|
|
2078
|
+
`;var le=`import * as React from 'react'
|
|
2022
2079
|
import { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react'
|
|
2023
2080
|
import { cn } from '@/utils/cn'
|
|
2024
2081
|
|
|
@@ -2027,7 +2084,7 @@ const styles = {
|
|
|
2027
2084
|
content: 'flex flex-row items-center gap-1',
|
|
2028
2085
|
link: cn(
|
|
2029
2086
|
'inline-flex items-center justify-center',
|
|
2030
|
-
'h-9 min-w-9 px-3 rounded-[10px] text-sm',
|
|
2087
|
+
'h-9 min-w-9 px-3 rounded-[10px] text-sm font-medium',
|
|
2031
2088
|
'text-muted-foreground hover:text-foreground',
|
|
2032
2089
|
'hover:bg-accent transition-colors cursor-pointer'
|
|
2033
2090
|
),
|
|
@@ -2037,7 +2094,7 @@ const styles = {
|
|
|
2037
2094
|
),
|
|
2038
2095
|
nav_link: cn(
|
|
2039
2096
|
'inline-flex items-center justify-center',
|
|
2040
|
-
'h-9 px-3 gap-1 rounded-[10px] text-sm',
|
|
2097
|
+
'h-9 px-3 gap-1 rounded-[10px] text-sm font-medium',
|
|
2041
2098
|
'text-muted-foreground hover:text-foreground',
|
|
2042
2099
|
'hover:bg-accent transition-colors cursor-pointer'
|
|
2043
2100
|
),
|
|
@@ -2151,7 +2208,7 @@ export const Pagination = Object.assign(PaginationRoot, {
|
|
|
2151
2208
|
Next,
|
|
2152
2209
|
Ellipsis: PaginationEllipsis,
|
|
2153
2210
|
})
|
|
2154
|
-
`;var
|
|
2211
|
+
`;var de=`'use client'
|
|
2155
2212
|
|
|
2156
2213
|
import * as React from 'react'
|
|
2157
2214
|
import { cn } from '@/utils/cn'
|
|
@@ -2256,7 +2313,7 @@ export const Popover = Object.assign(PopoverRoot, {
|
|
|
2256
2313
|
Trigger,
|
|
2257
2314
|
Content
|
|
2258
2315
|
})
|
|
2259
|
-
`;var
|
|
2316
|
+
`;var pe=`import * as React from 'react'
|
|
2260
2317
|
import { cn } from '@/utils/cn'
|
|
2261
2318
|
|
|
2262
2319
|
const styles = {
|
|
@@ -2294,7 +2351,7 @@ export function Progress({
|
|
|
2294
2351
|
</div>
|
|
2295
2352
|
)
|
|
2296
2353
|
}
|
|
2297
|
-
`;var
|
|
2354
|
+
`;var ue=`'use client'
|
|
2298
2355
|
|
|
2299
2356
|
import * as React from 'react'
|
|
2300
2357
|
import { cn } from '@/utils/cn'
|
|
@@ -2443,7 +2500,7 @@ function useRadioGroup() {
|
|
|
2443
2500
|
}
|
|
2444
2501
|
|
|
2445
2502
|
export const RadioGroup = Object.assign(RadioGroupRoot, { Item })
|
|
2446
|
-
`;var
|
|
2503
|
+
`;var me=`'use client'
|
|
2447
2504
|
|
|
2448
2505
|
import * as React from 'react'
|
|
2449
2506
|
import { ChevronDown } from 'lucide-react'
|
|
@@ -2597,7 +2654,7 @@ export const Select = Object.assign(SelectRoot, {
|
|
|
2597
2654
|
Menu,
|
|
2598
2655
|
Option
|
|
2599
2656
|
})
|
|
2600
|
-
`;var
|
|
2657
|
+
`;var fe=`import * as React from 'react'
|
|
2601
2658
|
import { cn } from '@/utils/cn'
|
|
2602
2659
|
|
|
2603
2660
|
const styles = {
|
|
@@ -2621,7 +2678,7 @@ export function Separator({
|
|
|
2621
2678
|
/>
|
|
2622
2679
|
)
|
|
2623
2680
|
}
|
|
2624
|
-
`;var
|
|
2681
|
+
`;var ge=`'use client'
|
|
2625
2682
|
|
|
2626
2683
|
import * as React from 'react'
|
|
2627
2684
|
import { cn } from '@/utils/cn'
|
|
@@ -2662,7 +2719,7 @@ export function Switch({
|
|
|
2662
2719
|
</button>
|
|
2663
2720
|
)
|
|
2664
2721
|
}
|
|
2665
|
-
`;var
|
|
2722
|
+
`;var he=`'use client'
|
|
2666
2723
|
|
|
2667
2724
|
import * as React from 'react'
|
|
2668
2725
|
import { cn } from '@/utils/cn'
|
|
@@ -2776,7 +2833,7 @@ export const Tabs = Object.assign(TabsRoot, {
|
|
|
2776
2833
|
Tab,
|
|
2777
2834
|
Panel
|
|
2778
2835
|
})
|
|
2779
|
-
`;var
|
|
2836
|
+
`;var be=`import * as React from 'react'
|
|
2780
2837
|
import { cn } from '@/utils/cn'
|
|
2781
2838
|
|
|
2782
2839
|
const styles = {
|
|
@@ -2803,7 +2860,7 @@ export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(({
|
|
|
2803
2860
|
))
|
|
2804
2861
|
|
|
2805
2862
|
Textarea.displayName = 'Textarea'
|
|
2806
|
-
`;var
|
|
2863
|
+
`;var ve=`'use client'
|
|
2807
2864
|
|
|
2808
2865
|
import * as React from 'react'
|
|
2809
2866
|
import { Toaster as Sonner, toast } from 'sonner'
|
|
@@ -2846,7 +2903,7 @@ function Toaster() {
|
|
|
2846
2903
|
}
|
|
2847
2904
|
|
|
2848
2905
|
export { Toaster, toast }
|
|
2849
|
-
`;var
|
|
2906
|
+
`;var xe=`import * as React from 'react'
|
|
2850
2907
|
import { cn } from '@/utils/cn'
|
|
2851
2908
|
|
|
2852
2909
|
const styles = {
|
|
@@ -3020,7 +3077,7 @@ export const Table = Object.assign(TableRoot, {
|
|
|
3020
3077
|
Head,
|
|
3021
3078
|
Cell,
|
|
3022
3079
|
})
|
|
3023
|
-
`;var
|
|
3080
|
+
`;var ye=`import * as React from 'react'
|
|
3024
3081
|
import { cn } from '@/utils/cn'
|
|
3025
3082
|
|
|
3026
3083
|
const styles = {
|
|
@@ -3065,7 +3122,7 @@ export function Tooltip({
|
|
|
3065
3122
|
</span>
|
|
3066
3123
|
)
|
|
3067
3124
|
}
|
|
3068
|
-
`;var
|
|
3125
|
+
`;var Ne=`
|
|
3069
3126
|
/* react-day-picker theme integration */
|
|
3070
3127
|
.rdp-root {
|
|
3071
3128
|
--rdp-accent-color: var(--primary);
|
|
@@ -3076,4 +3133,4 @@ export function Tooltip({
|
|
|
3076
3133
|
--rdp-selected-border: none;
|
|
3077
3134
|
--rdp-day_button-border: none;
|
|
3078
3135
|
}
|
|
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,
|
|
3136
|
+
`,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:"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:"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,kbd:ce,label:ie,pagination:le,popover:de,progress:pe,"radio-group":ue,select:me,separator:fe,switch:ge,table:xe,tabs:he,textarea:be,theme:K,toast:ve,tooltip:ye};async function Ce(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+Ne),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 Re={version:"1.4.0"};var T=new Command;T.name("drivn").description("Drivn \u2014 Modern UI components").version(Re.version);T.command("create").description("Initialize Drivn in your project").action(G);T.command("add [components...]").description("Add components to your project").action(Ce);T.parse();
|