drivn 1.13.2 → 1.14.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 +170 -19
- 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 j={next:"Next.js",react:"React"};function V(e){let r=join(e,"package.json");if(!existsSync(r))throw new Error("package.json not found");let t=JSON.parse(readFileSync(r,"utf-8")),a={...t.dependencies,...t.devDependencies},l="react";a.next&&(l="next");let d=existsSync(join(e,"src")),p=existsSync(join(e,"tsconfig.json"));return {framework:l,srcDir:d,typescript:p}}var F="drivn.config.json";function U(e){let r=join(e,F);return existsSync(r)?JSON.parse(readFileSync(r,"utf-8")):null}function K(e,r){let t=join(e,F);writeFileSync(t,JSON.stringify(r,null,2));}function
|
|
2
|
+
import {Command}from'commander';import*as n from'@clack/prompts';import u from'picocolors';import {join,dirname}from'path';import {execSync}from'child_process';import {existsSync,readFileSync,writeFileSync,mkdirSync}from'fs';import {McpServer}from'@modelcontextprotocol/sdk/server/mcp.js';import {StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';import {z as z$1}from'zod';var j={next:"Next.js",react:"React"};function V(e){let r=join(e,"package.json");if(!existsSync(r))throw new Error("package.json not found");let t=JSON.parse(readFileSync(r,"utf-8")),a={...t.dependencies,...t.devDependencies},l="react";a.next&&(l="next");let d=existsSync(join(e,"src")),p=existsSync(join(e,"tsconfig.json"));return {framework:l,srcDir:d,typescript:p}}var F="drivn.config.json";function U(e){let r=join(e,F);return existsSync(r)?JSON.parse(readFileSync(r,"utf-8")):null}function K(e,r){let t=join(e,F);writeFileSync(t,JSON.stringify(r,null,2));}function Ge(e){existsSync(e)||mkdirSync(e,{recursive:true});}function h(e,r){Ge(dirname(e)),writeFileSync(e,r);}function H(e){return readFileSync(e,"utf-8")}function x(e){return existsSync(e)}function E(e){return existsSync(join(e,"pnpm-lock.yaml"))?"pnpm":"npm"}function w(e,r){let t=r.join(" ");return e==="pnpm"?`pnpm add ${t}`:`npm install ${t}`}function Y(e){return e==="pnpm"?"pnpm dlx":"npx"}var C=`@import "tailwindcss";
|
|
3
3
|
|
|
4
4
|
:root {
|
|
5
5
|
/* Surfaces */
|
|
@@ -136,13 +136,13 @@ body {
|
|
|
136
136
|
/* Special Surfaces */
|
|
137
137
|
--overlay: hsl(0 0% 0% / 0.18);
|
|
138
138
|
}
|
|
139
|
-
`;var
|
|
139
|
+
`;var Ye=`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
|
+
`,We=["src/app/globals.css","src/styles/globals.css","src/styles/globals.scss","app/globals.css"];function Xe(e){for(let r of We)if(x(join(e,r)))return r;return null}async function W(){let e=process.cwd();console.log(""),console.log(u.bgCyan(u.bold(u.black(" Drivn "))));let r;try{r=V(e),n.log.success(`Detected ${u.cyan(j[r.framework])}`);}catch{n.log.error("No package.json found. Run this command in a project directory."),n.outro("Setup cancelled"),process.exit(1);}if(x(join(e,"drivn.config.json"))){let s=await n.confirm({message:"Config already exists. Overwrite?",initialValue:false});(n.isCancel(s)||!s)&&(n.cancel("Setup cancelled"),process.exit(0));}let t=r.srcDir?"src/components/ui":"components/ui",a=r.srcDir?"src/utils":"utils",l=await n.group({components:()=>n.text({message:"Where should components be installed?",placeholder:t,defaultValue:t}),utils:()=>n.text({message:"Where should utilities be placed?",placeholder:a,defaultValue:a})},{onCancel:()=>{n.cancel("Setup cancelled"),process.exit(0);}}),d={framework:r.framework,typescript:r.typescript,paths:{components:l.components,utils:l.utils},installed:[]},p=r.typescript?"ts":"js",f=join(e,l.utils,`cn.${p}`);x(f)||h(f,Ye);let g=Xe(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(w(N,b),{cwd:e,stdio:"ignore"}),o.stop("Dependencies installed");}catch{o.stop("Failed to install dependencies"),n.log.warn(`Run manually: ${w(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
|
|
|
@@ -3026,7 +3026,7 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(({
|
|
|
3026
3026
|
)
|
|
3027
3027
|
|
|
3028
3028
|
Input.displayName = 'Input'
|
|
3029
|
-
`;var
|
|
3029
|
+
`;var be=`import * as React from 'react'
|
|
3030
3030
|
import { cn } from '@/utils/cn'
|
|
3031
3031
|
|
|
3032
3032
|
const styles = {
|
|
@@ -3083,7 +3083,7 @@ function Group({
|
|
|
3083
3083
|
}
|
|
3084
3084
|
|
|
3085
3085
|
export const Kbd = Object.assign(KbdRoot, { Group })
|
|
3086
|
-
`;var
|
|
3086
|
+
`;var he=`import * as React from 'react'
|
|
3087
3087
|
import { cn } from '@/utils/cn'
|
|
3088
3088
|
|
|
3089
3089
|
export function Label({
|
|
@@ -3194,10 +3194,12 @@ function Trigger({
|
|
|
3194
3194
|
return (
|
|
3195
3195
|
<button
|
|
3196
3196
|
className={cn(styles.trigger, className)}
|
|
3197
|
-
|
|
3197
|
+
onPointerDown={(e) => {
|
|
3198
3198
|
if (document.activeElement === e.currentTarget) {
|
|
3199
3199
|
e.preventDefault()
|
|
3200
3200
|
e.currentTarget.blur()
|
|
3201
|
+
} else {
|
|
3202
|
+
e.currentTarget.focus()
|
|
3201
3203
|
}
|
|
3202
3204
|
}}
|
|
3203
3205
|
{...props}
|
|
@@ -4350,6 +4352,155 @@ export const Slider = React.forwardRef<HTMLInputElement, SliderProps>(({
|
|
|
4350
4352
|
Slider.displayName = 'Slider'
|
|
4351
4353
|
`;var Te=`'use client'
|
|
4352
4354
|
|
|
4355
|
+
import * as React from 'react'
|
|
4356
|
+
import { Check } from 'lucide-react'
|
|
4357
|
+
import { cn } from '@/utils/cn'
|
|
4358
|
+
|
|
4359
|
+
const styles = {
|
|
4360
|
+
root: {
|
|
4361
|
+
horizontal: 'flex items-center w-full',
|
|
4362
|
+
vertical: 'flex flex-col items-center',
|
|
4363
|
+
noLine: 'justify-between',
|
|
4364
|
+
},
|
|
4365
|
+
indicator: {
|
|
4366
|
+
base: cn(
|
|
4367
|
+
'flex items-center justify-center shrink-0',
|
|
4368
|
+
'h-8 min-w-8 rounded-full text-xs font-semibold',
|
|
4369
|
+
'transition-colors duration-200 select-none',
|
|
4370
|
+
'[&>svg]:size-4'
|
|
4371
|
+
),
|
|
4372
|
+
text: 'px-3 shrink',
|
|
4373
|
+
active: cn(
|
|
4374
|
+
'bg-accent text-muted-foreground',
|
|
4375
|
+
'border-2 border-primary'
|
|
4376
|
+
),
|
|
4377
|
+
completed: 'bg-primary text-muted-foreground',
|
|
4378
|
+
upcoming: cn(
|
|
4379
|
+
'bg-accent text-muted-foreground',
|
|
4380
|
+
'border-2 border-border'
|
|
4381
|
+
),
|
|
4382
|
+
clickable: 'cursor-pointer',
|
|
4383
|
+
disabled: 'opacity-50 cursor-not-allowed',
|
|
4384
|
+
},
|
|
4385
|
+
line: {
|
|
4386
|
+
horizontal: 'h-0.5 flex-1',
|
|
4387
|
+
vertical: 'w-0.5 min-h-6 self-center',
|
|
4388
|
+
active: 'bg-primary',
|
|
4389
|
+
upcoming: 'bg-border',
|
|
4390
|
+
},
|
|
4391
|
+
}
|
|
4392
|
+
|
|
4393
|
+
type IconProp = React.ComponentType<{ className?: string }>
|
|
4394
|
+
|
|
4395
|
+
interface StepperCtx {
|
|
4396
|
+
step: number
|
|
4397
|
+
orientation: 'horizontal' | 'vertical'
|
|
4398
|
+
onStepChange?: (step: number) => void
|
|
4399
|
+
}
|
|
4400
|
+
|
|
4401
|
+
function StepperRoot({
|
|
4402
|
+
step = 0,
|
|
4403
|
+
onStepChange,
|
|
4404
|
+
orientation = 'horizontal',
|
|
4405
|
+
line = true,
|
|
4406
|
+
className,
|
|
4407
|
+
children,
|
|
4408
|
+
}: {
|
|
4409
|
+
step?: number
|
|
4410
|
+
onStepChange?: (step: number) => void
|
|
4411
|
+
orientation?: 'horizontal' | 'vertical'
|
|
4412
|
+
line?: boolean
|
|
4413
|
+
className?: string
|
|
4414
|
+
children: React.ReactNode
|
|
4415
|
+
}) {
|
|
4416
|
+
const items = React.Children.toArray(children)
|
|
4417
|
+
return (
|
|
4418
|
+
<Ctx.Provider value={{ step, orientation, onStepChange }}>
|
|
4419
|
+
<div
|
|
4420
|
+
role="group"
|
|
4421
|
+
aria-label="Progress"
|
|
4422
|
+
className={cn(
|
|
4423
|
+
styles.root[orientation],
|
|
4424
|
+
!line && styles.root.noLine,
|
|
4425
|
+
className
|
|
4426
|
+
)}
|
|
4427
|
+
>
|
|
4428
|
+
{items.map((child, i) => (
|
|
4429
|
+
<React.Fragment key={i}>
|
|
4430
|
+
{React.isValidElement(child) &&
|
|
4431
|
+
React.cloneElement(
|
|
4432
|
+
child as React.ReactElement<{ _index?: number }>,
|
|
4433
|
+
{ _index: i }
|
|
4434
|
+
)}
|
|
4435
|
+
{line && i < items.length - 1 && (
|
|
4436
|
+
<div
|
|
4437
|
+
className={cn(
|
|
4438
|
+
styles.line[orientation],
|
|
4439
|
+
i < step ? styles.line.active : styles.line.upcoming
|
|
4440
|
+
)}
|
|
4441
|
+
/>
|
|
4442
|
+
)}
|
|
4443
|
+
</React.Fragment>
|
|
4444
|
+
))}
|
|
4445
|
+
</div>
|
|
4446
|
+
</Ctx.Provider>
|
|
4447
|
+
)
|
|
4448
|
+
}
|
|
4449
|
+
|
|
4450
|
+
function Item({
|
|
4451
|
+
_index = 0,
|
|
4452
|
+
label,
|
|
4453
|
+
icon: Icon,
|
|
4454
|
+
disabled,
|
|
4455
|
+
className,
|
|
4456
|
+
...props
|
|
4457
|
+
}: {
|
|
4458
|
+
_index?: number
|
|
4459
|
+
label?: string
|
|
4460
|
+
icon?: IconProp
|
|
4461
|
+
disabled?: boolean
|
|
4462
|
+
className?: string
|
|
4463
|
+
} & Omit<
|
|
4464
|
+
React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
4465
|
+
'disabled'
|
|
4466
|
+
>) {
|
|
4467
|
+
const { step, onStepChange } = useStepper()
|
|
4468
|
+
const state = _index < step ? 'completed' : _index === step ? 'active' : 'upcoming'
|
|
4469
|
+
return (
|
|
4470
|
+
<button
|
|
4471
|
+
type="button"
|
|
4472
|
+
disabled={disabled}
|
|
4473
|
+
aria-current={state === 'active' ? 'step' : undefined}
|
|
4474
|
+
className={cn(
|
|
4475
|
+
styles.indicator.base,
|
|
4476
|
+
label && styles.indicator.text,
|
|
4477
|
+
styles.indicator[state],
|
|
4478
|
+
disabled
|
|
4479
|
+
? styles.indicator.disabled
|
|
4480
|
+
: styles.indicator.clickable,
|
|
4481
|
+
className
|
|
4482
|
+
)}
|
|
4483
|
+
onClick={() => !disabled && onStepChange?.(_index)}
|
|
4484
|
+
{...props}
|
|
4485
|
+
>
|
|
4486
|
+
{label ?? (state === 'completed' ? <Check /> : Icon ? <Icon /> : _index + 1)}
|
|
4487
|
+
</button>
|
|
4488
|
+
)
|
|
4489
|
+
}
|
|
4490
|
+
|
|
4491
|
+
const Ctx = React.createContext<StepperCtx | null>(null)
|
|
4492
|
+
|
|
4493
|
+
function useStepper() {
|
|
4494
|
+
const ctx = React.useContext(Ctx)
|
|
4495
|
+
if (!ctx) throw new Error('Stepper.* used outside <Stepper>')
|
|
4496
|
+
return ctx
|
|
4497
|
+
}
|
|
4498
|
+
|
|
4499
|
+
export const Stepper = Object.assign(StepperRoot, {
|
|
4500
|
+
Item
|
|
4501
|
+
})
|
|
4502
|
+
`;var Ie=`'use client'
|
|
4503
|
+
|
|
4353
4504
|
import * as React from 'react'
|
|
4354
4505
|
import { cn } from '@/utils/cn'
|
|
4355
4506
|
|
|
@@ -4390,7 +4541,7 @@ export function Switch({
|
|
|
4390
4541
|
</button>
|
|
4391
4542
|
)
|
|
4392
4543
|
}
|
|
4393
|
-
`;var
|
|
4544
|
+
`;var Ee=`'use client'
|
|
4394
4545
|
|
|
4395
4546
|
import * as React from 'react'
|
|
4396
4547
|
import { cn } from '@/utils/cn'
|
|
@@ -4504,7 +4655,7 @@ export const Tabs = Object.assign(TabsRoot, {
|
|
|
4504
4655
|
Tab,
|
|
4505
4656
|
Panel
|
|
4506
4657
|
})
|
|
4507
|
-
`;var
|
|
4658
|
+
`;var Le=`import * as React from 'react'
|
|
4508
4659
|
import { cn } from '@/utils/cn'
|
|
4509
4660
|
|
|
4510
4661
|
const styles = {
|
|
@@ -4531,7 +4682,7 @@ export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(({
|
|
|
4531
4682
|
))
|
|
4532
4683
|
|
|
4533
4684
|
Textarea.displayName = 'Textarea'
|
|
4534
|
-
`;var
|
|
4685
|
+
`;var Me=`'use client'
|
|
4535
4686
|
|
|
4536
4687
|
import * as React from 'react'
|
|
4537
4688
|
import { Toaster as Sonner, toast } from 'sonner'
|
|
@@ -4574,7 +4725,7 @@ function Toaster() {
|
|
|
4574
4725
|
}
|
|
4575
4726
|
|
|
4576
4727
|
export { Toaster, toast }
|
|
4577
|
-
`;var
|
|
4728
|
+
`;var Oe=`'use client'
|
|
4578
4729
|
|
|
4579
4730
|
import * as React from 'react'
|
|
4580
4731
|
import { cn } from '@/utils/cn'
|
|
@@ -4736,7 +4887,7 @@ const Ctx = React.createContext<ToggleGroupCtx | null>(null)
|
|
|
4736
4887
|
export const Toggle = Object.assign(ToggleButton, {
|
|
4737
4888
|
Group: ToggleGroupRoot,
|
|
4738
4889
|
})
|
|
4739
|
-
`;var
|
|
4890
|
+
`;var Ae=`import * as React from 'react'
|
|
4740
4891
|
import { cn } from '@/utils/cn'
|
|
4741
4892
|
|
|
4742
4893
|
const styles = {
|
|
@@ -4910,7 +5061,7 @@ export const Table = Object.assign(TableRoot, {
|
|
|
4910
5061
|
Head,
|
|
4911
5062
|
Cell,
|
|
4912
5063
|
})
|
|
4913
|
-
`;var
|
|
5064
|
+
`;var Be=`import * as React from 'react'
|
|
4914
5065
|
import { cn } from '@/utils/cn'
|
|
4915
5066
|
|
|
4916
5067
|
const styles = {
|
|
@@ -4955,7 +5106,7 @@ export function Tooltip({
|
|
|
4955
5106
|
</span>
|
|
4956
5107
|
)
|
|
4957
5108
|
}
|
|
4958
|
-
`;var
|
|
5109
|
+
`;var He=`
|
|
4959
5110
|
/* react-day-picker theme integration */
|
|
4960
5111
|
.rdp-root {
|
|
4961
5112
|
--rdp-accent-color: var(--primary);
|
|
@@ -4966,7 +5117,7 @@ export function Tooltip({
|
|
|
4966
5117
|
--rdp-selected-border: none;
|
|
4967
5118
|
--rdp-day_button-border: none;
|
|
4968
5119
|
}
|
|
4969
|
-
`,v=[{name:"accordion",description:"Collapsible content sections with dot notation and smooth animation",dependencies:[],npmDependencies:[]},{name:"alert",description:"Contextual feedback messages with variants and icons",dependencies:[],npmDependencies:[]},{name:"aspect-ratio",description:"Maintain consistent width-to-height ratios for images, videos, and embedded content",dependencies:[],npmDependencies:[]},{name:"avatar",description:"User avatar with image support and fallback initials",dependencies:[],npmDependencies:[]},{name:"badge",description:"Small status indicator with color variants",dependencies:[],npmDependencies:[]},{name:"breadcrumb",description:"Breadcrumb navigation with auto-separators, ellipsis, and dot notation",dependencies:[],npmDependencies:[]},{name:"button",description:"Button with variants, sizes, loading state, and icon slots",dependencies:[],npmDependencies:[]},{name:"calendar",description:"Date picker powered by react-day-picker with single, range, and dropdown modes",dependencies:[],npmDependencies:["react-day-picker"]},{name:"date-picker",description:"Date picker input with Calendar dropdown for single date and range selection",dependencies:["calendar"],npmDependencies:[]},{name:"command",description:"Searchable command menu with filtering, keyboard navigation, and dialog mode",dependencies:["dialog"],npmDependencies:["cmdk"]},{name:"carousel",description:"Carousel with touch/swipe, navigation arrows, dot indicators, and loop mode",dependencies:["button"],npmDependencies:["embla-carousel-react"]},{name:"card",description:"Container with dot notation preview and info sub-components",dependencies:[],npmDependencies:[]},{name:"checkbox",description:"Checkbox input with label and CSS-only checkmark",dependencies:[],npmDependencies:[]},{name:"combobox",description:"Searchable select with filtering, single/multi selection, and keyboard navigation",dependencies:[],npmDependencies:["cmdk"]},{name:"collapsible",description:"Toggle content visibility with smooth animation and accessible controls",dependencies:[],npmDependencies:[]},{name:"context-menu",description:"Right-click context menu with submenus, keyboard shortcuts, icons, and dot notation",dependencies:[],npmDependencies:[]},{name:"dialog",description:"Modal dialog with dot notation, overlay, and escape key",dependencies:["button"],npmDependencies:[]},{name:"drawer",description:"Slide-in panel with side positioning, header/footer, and overlay",dependencies:["button"],npmDependencies:[]},{name:"dropdown",description:"Dropdown menu with dot notation, groups, separators, and click-outside",dependencies:["button"],npmDependencies:[]},{name:"input",description:"Text input with focus ring and disabled state",dependencies:[],npmDependencies:[]},{name:"kbd",description:"Keyboard key display for shortcuts and hotkeys",dependencies:[],npmDependencies:[]},{name:"label",description:"Accessible form label for inputs, checkboxes, and selects",dependencies:[],npmDependencies:[]},{name:"navigation-menu",description:"Horizontal navigation menu with dropdown content panels and dot notation",dependencies:[],npmDependencies:[]},{name:"pagination",description:"Page navigation with dot notation, Previous/Next, ellipsis, and active state",dependencies:[],npmDependencies:[]},{name:"popover",description:"Floating content panel with dot notation and click-outside",dependencies:["button"],npmDependencies:[]},{name:"progress",description:"Progress bar with animated fill and ARIA attributes",dependencies:[],npmDependencies:[]},{name:"radio-group",description:"Radio group with dot notation, orientation support, and controlled/uncontrolled selection",dependencies:[],npmDependencies:[]},{name:"select",description:"Custom select with dot notation and composable options",dependencies:[],npmDependencies:[]},{name:"scroll-area",description:"Themed scrollable container with custom scrollbar styling and orientation control",dependencies:[],npmDependencies:[]},{name:"separator",description:"Visual divider with horizontal and vertical orientation",dependencies:[],npmDependencies:[]},{name:"skeleton",description:"Loading placeholder with pulse animation, sized and shaped via className",dependencies:[],npmDependencies:[]},{name:"sidebar",description:"Collapsible sidebar with dot notation, icon items, groups, and layout variants",dependencies:[],npmDependencies:[]},{name:"slider",description:"Range slider with pointer drag, step snapping, and size variants",dependencies:[],npmDependencies:[]},{name:"switch",description:"Toggle switch with smooth transition",dependencies:[],npmDependencies:[]},{name:"tabs",description:"Tab navigation with dot notation and panel content",dependencies:[],npmDependencies:[]},{name:"table",description:"Data table with dot notation, striped/bordered variants, and responsive overflow",dependencies:[],npmDependencies:[]},{name:"textarea",description:"Multi-line text input with consistent styling",dependencies:[],npmDependencies:[]},{name:"theme",description:"Dark/light theme support with next-themes and ThemeProvider",dependencies:[],npmDependencies:["next-themes"]},{name:"toast",description:"Toast notifications powered by Sonner",dependencies:[],npmDependencies:["sonner"]},{name:"toggle",description:"Toggle button with pressed state, single and multiple selection groups",dependencies:[],npmDependencies:[]},{name:"tooltip",description:"Pure CSS tooltip with 4 position options",dependencies:[],npmDependencies:[]}],R={accordion:q,alert:J,"aspect-ratio":Z,avatar:Q,badge:ee,breadcrumb:te,button:ne,calendar:oe,"date-picker":re,command:se,carousel:ae,card:ie,checkbox:ce,combobox:le,collapsible:de,"context-menu":pe,dialog:ue,drawer:me,dropdown:fe,input:ge,kbd:
|
|
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:[]}],R={accordion:q,alert:J,"aspect-ratio":Z,avatar:Q,badge:ee,breadcrumb:te,button:ne,calendar:oe,"date-picker":re,command:se,carousel:ae,card:ie,checkbox:ce,combobox:le,collapsible:de,"context-menu":pe,dialog:ue,drawer:me,dropdown:fe,input:ge,kbd:be,label:he,"navigation-menu":ve,pagination:xe,popover:ye,progress:Ne,"radio-group":Ce,select:Re,"scroll-area":we,separator:ke,skeleton:Pe,sidebar:Se,slider:De,stepper:Te,switch:Ie,table:Ae,tabs:Ee,textarea:Le,theme:X,toast:Me,toggle:Oe,tooltip:Be};async function ze(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 S=await n.confirm({message:`${o}.${m} exists. Overwrite?`,initialValue:false});if(n.isCancel(S)||!S){n.log.warn(`Skipped ${o}`);continue}}let i=R[o];i=i.replace(/@\/utils/g,`@/${t.paths.utils.replace(/^src\//,"")}`),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,R.theme),n.log.success(`theme-provider \u2192 ${t.paths.components}/theme-provider.${m}`)):n.log.warn("Skipped theme-provider");}else h(o,R.theme),n.log.success(`theme-provider \u2192 ${t.paths.components}/theme-provider.${m}`);if(t.paths.globals){let i=join(r,t.paths.globals);if(x(i)){let S=H(i);S.includes('[data-theme="dark"]')?n.log.warn("Theme tokens already exist in globals \u2014 skipped"):(h(i,S+k),n.log.success(`Theme tokens appended to ${u.cyan(t.paths.globals)}`));}else n.log.warn(`Globals file not found at ${t.paths.globals}`);}else n.log.warn('No globals path in drivn.config.json. Add "globals" to paths');let s=t.paths.components.replace(/^src\//,"@/");n.log.message(""),n.log.info(u.bold("Complete the setup:")),n.log.message(""),n.log.message(u.bold(`${u.cyan("1.")} Import ThemeProvider in your root layout:`)),n.log.message(u.cyan(` import { ThemeProvider } from "${s}/theme-provider"`)),n.log.message(""),n.log.message(u.bold(`${u.cyan("2.")} Add suppressHydrationWarning to <html>:`)),n.log.message(u.cyan(" <html suppressHydrationWarning>")),n.log.message(""),n.log.message(u.bold(`${u.cyan("3.")} Wrap your app with ThemeProvider:`)),n.log.message(u.cyan(" <ThemeProvider>")),n.log.message(u.cyan(" {children}")),n.log.message(u.cyan(" </ThemeProvider>")),n.log.message("");}if(p.has("calendar")&&t.paths.globals){let o=join(r,t.paths.globals);if(x(o)){let s=H(o);s.includes(".rdp-root")?n.log.warn("Calendar tokens already exist in globals \u2014 skipped"):(h(o,s+He),n.log.success(`Calendar tokens appended to ${u.cyan(t.paths.globals)}`));}}if(f.size){let o=E(r),s=[...f],i=n.spinner();i.start("Installing packages");try{execSync(w(o,s),{cwd:r,stdio:"ignore"}),i.stop("Packages installed");}catch{i.stop("Failed to install packages"),n.log.warn(`Run manually: ${w(o,s)}`);}}n.outro("Done.");}var z=`# Drivn Component Conventions
|
|
4970
5121
|
|
|
4971
5122
|
## Core Philosophy
|
|
4972
5123
|
- **Zero runtime UI deps** \u2014 No Radix, no cva, no external UI primitives. Pure React + Tailwind.
|
|
@@ -5079,13 +5230,13 @@ import { cn } from '@/utils/cn'
|
|
|
5079
5230
|
- Components declare internal deps (other Drivn components)
|
|
5080
5231
|
- Some components need npm packages (react-day-picker, cmdk, embla-carousel-react, sonner)
|
|
5081
5232
|
- The CLI resolves and installs all dependencies automatically
|
|
5082
|
-
`;var L={version:"1.
|
|
5083
|
-
${N} drivn@latest add ${[...d].join(" ")}`),p.size&&
|
|
5084
|
-
${m} ${[...p].join(" ")}`),
|
|
5085
|
-
# (default: src/components/ui/)`),{content:[{type:"text",text:JSON.stringify({componentsToInstall:[...d],npmDependencies:[...p],steps:
|
|
5233
|
+
`;var L={version:"1.14.0"};function M(e){return v.find(r=>r.name===e)}function et(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 je(){let e=new McpServer({name:"drivn",version:L.version});e.tool("list_components","List all available Drivn UI components with descriptions",{},async()=>({content:[{type:"text",text:JSON.stringify(v.map(t=>({name:t.name,description:t.description})),null,2)}]})),e.tool("get_component","Get the full source code and metadata for a Drivn component",{name:z$1.string().describe('Component name (e.g. "button", "dialog")')},async({name:t})=>{let a=M(t);if(!a)return {content:[{type:"text",text:`Component "${t}" not found. Use list_components to see available components.`}],isError:true};let l=R[t];return {content:[{type:"text",text:JSON.stringify({name:a.name,description:a.description,dependencies:a.dependencies,npmDependencies:a.npmDependencies,source:l},null,2)}]}}),e.tool("get_component_metadata","Get metadata only (no source code) for a Drivn component \u2014 useful for planning",{name:z$1.string().describe("Component name")},async({name:t})=>{let a=M(t);if(!a)return {content:[{type:"text",text:`Component "${t}" not found. Use list_components to see available components.`}],isError:true};let l=et(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
|
+
${N} drivn@latest add ${[...d].join(" ")}`),p.size&&b.push(`# Install required npm dependencies
|
|
5235
|
+
${m} ${[...p].join(" ")}`),b.push(`# Components will be installed to your configured components directory
|
|
5236
|
+
# (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 === */
|
|
5086
5237
|
${C}
|
|
5087
5238
|
|
|
5088
5239
|
/* === Theme Tokens === */
|
|
5089
5240
|
${k}`}]})),e.tool("get_drivn_rules","Get Drivn coding conventions and component patterns",{},async()=>({content:[{type:"text",text:z}]})),e.resource("drivn-rules","drivn://rules",{description:"Drivn coding conventions and component patterns"},async()=>({contents:[{uri:"drivn://rules",mimeType:"text/markdown",text:z}]})),e.resource("drivn-design-tokens","drivn://design-tokens",{description:"Drivn CSS globals and theme tokens"},async()=>({contents:[{uri:"drivn://design-tokens",mimeType:"text/css",text:`${C}
|
|
5090
5241
|
|
|
5091
|
-
${k}`}]}));for(let t of v){let a=`drivn://components/${t.name}`;e.resource(`drivn-component-${t.name}`,a,{description:t.description},async()=>({contents:[{uri:a,mimeType:"text/plain",text:R[t.name]}]}));}let r=new StdioServerTransport;await e.connect(r);}var I=new Command;I.name("drivn").description("Drivn \u2014 Modern UI components").version(L.version);I.command("create").description("Initialize Drivn in your project").action(W);I.command("add [components...]").description("Add components to your project").action(
|
|
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:R[t.name]}]}));}let r=new StdioServerTransport;await e.connect(r);}var I=new Command;I.name("drivn").description("Drivn \u2014 Modern UI components").version(L.version);I.command("create").description("Initialize Drivn in your project").action(W);I.command("add [components...]").description("Add components to your project").action(ze);I.command("mcp").description("Start the Drivn MCP server").action(je);I.parse();
|