drivn 1.0.1 → 1.1.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 +214 -284
- 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
|
|
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 M={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 c=JSON.parse(readFileSync(n,"utf-8")),v={...c.dependencies,...c.devDependencies},d="react";v.next&&(d="next");let m=existsSync(join(t,"src")),f=existsSync(join(t,"tsconfig.json"));return {framework:d,srcDir:m,typescript:f}}var H="drivn.config.json";function V(t){let n=join(t,H);return existsSync(n)?JSON.parse(readFileSync(n,"utf-8")):null}function z(t,n){let c=join(t,H);writeFileSync(c,JSON.stringify(n,null,2));}function he(t){existsSync(t)||mkdirSync(t,{recursive:true});}function p(t,n){he(dirname(t)),writeFileSync(t,n);}function F(t){return readFileSync(t,"utf-8")}function h(t){return existsSync(t)}function k(t){return existsSync(join(t,"pnpm-lock.yaml"))?"pnpm":"npm"}function y(t,n){let c=n.join(" ");return t==="pnpm"?`pnpm add ${c}`:`npm install ${c}`}function _(t){return t==="pnpm"?"pnpm dlx":"npx"}var T=`@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
|
+
`,L=`
|
|
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 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
|
+
`,Ne=["src/app/globals.css","src/styles/globals.css","src/styles/globals.scss","app/globals.css"];function we(t){for(let n of Ne)if(h(join(t,n)))return n;return null}async function U(){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(M[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(h(join(t,"drivn.config.json"))){let s=await e.confirm({message:"Config already exists. Overwrite?",initialValue:false});(e.isCancel(s)||!s)&&(e.cancel("Setup cancelled"),process.exit(0));}let c=n.srcDir?"src/components/ui":"components/ui",v=n.srcDir?"src/utils":"utils",d=await e.group({components:()=>e.text({message:"Where should components be installed?",placeholder:c,defaultValue:c}),utils:()=>e.text({message:"Where should utilities be placed?",placeholder:v,defaultValue:v})},{onCancel:()=>{e.cancel("Setup cancelled"),process.exit(0);}}),m={framework:n.framework,typescript:n.typescript,paths:{components:d.components,utils:d.utils},installed:[]},f=n.typescript?"ts":"js",b=join(t,d.utils,`cn.${f}`);h(b)||p(b,ye);let g=we(t);if(g){let s=await e.confirm({message:`Found ${i.cyan(g)}. Add Drivn color tokens?`,initialValue:true});!e.isCancel(s)&&s&&(p(join(t,g),T),m.paths.globals=g,e.log.success(`Color tokens written to ${i.cyan(g)}`));}else {let s=n.srcDir?"src/styles/globals.css":"styles/globals.css",a=await e.text({message:"Where should the globals CSS file be created?",placeholder:s,defaultValue:s});e.isCancel(a)||(p(join(t,a),T),m.paths.globals=a,e.log.success(`Color tokens written to ${i.cyan(a)}`));}z(t,m);let x=k(t),l=_(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 G=`'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 W=`'use client'
|
|
165
165
|
|
|
166
166
|
import * as React from 'react'
|
|
167
167
|
import { ChevronDown } from 'lucide-react'
|
|
@@ -183,47 +183,32 @@ const styles = {
|
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
interface AccordionCtx {
|
|
186
|
-
|
|
187
|
-
toggle: (
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
const Ctx = React.createContext<AccordionCtx | null>(null)
|
|
191
|
-
const ItemCtx = React.createContext<string | null>(null)
|
|
192
|
-
|
|
193
|
-
function useAccordion() {
|
|
194
|
-
const ctx = React.useContext(Ctx)
|
|
195
|
-
if (!ctx) throw new Error('Accordion compound used outside <Accordion>')
|
|
196
|
-
return ctx
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function useItemValue() {
|
|
200
|
-
const value = React.useContext(ItemCtx)
|
|
201
|
-
if (!value) throw new Error(
|
|
202
|
-
'Accordion sub-component used outside <Accordion.Item>'
|
|
203
|
-
)
|
|
204
|
-
return value
|
|
186
|
+
open: Set<string>
|
|
187
|
+
toggle: (v: string) => void
|
|
205
188
|
}
|
|
206
189
|
|
|
207
190
|
function AccordionRoot({
|
|
208
191
|
children,
|
|
209
192
|
defaultValue,
|
|
193
|
+
multiple,
|
|
210
194
|
className,
|
|
211
195
|
}: {
|
|
212
196
|
children: React.ReactNode
|
|
213
|
-
defaultValue?: string
|
|
197
|
+
defaultValue?: string | string[]
|
|
198
|
+
multiple?: boolean
|
|
214
199
|
className?: string
|
|
215
200
|
}) {
|
|
216
|
-
const [
|
|
217
|
-
|
|
218
|
-
)
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
201
|
+
const [open, setOpen] = React.useState(() => new Set([defaultValue ?? []].flat()))
|
|
202
|
+
|
|
203
|
+
const toggle = (v: string) =>
|
|
204
|
+
setOpen((prev) => {
|
|
205
|
+
const next = new Set(multiple ? prev : [])
|
|
206
|
+
prev.has(v) ? next.delete(v) : next.add(v)
|
|
207
|
+
return next
|
|
208
|
+
})
|
|
224
209
|
|
|
225
210
|
return (
|
|
226
|
-
<Ctx.Provider value={{
|
|
211
|
+
<Ctx.Provider value={{ open, toggle }}>
|
|
227
212
|
<div className={cn(styles.base, className)}>
|
|
228
213
|
{children}
|
|
229
214
|
</div>
|
|
@@ -250,17 +235,20 @@ function Item({
|
|
|
250
235
|
function Trigger({
|
|
251
236
|
children,
|
|
252
237
|
className,
|
|
238
|
+
...props
|
|
253
239
|
}: {
|
|
254
240
|
children: React.ReactNode
|
|
255
241
|
className?: string
|
|
256
|
-
}) {
|
|
257
|
-
const {
|
|
258
|
-
const value =
|
|
259
|
-
const isOpen =
|
|
242
|
+
} & React.ButtonHTMLAttributes<HTMLButtonElement>) {
|
|
243
|
+
const { open, toggle } = useCtx()
|
|
244
|
+
const value = React.useContext(ItemCtx)
|
|
245
|
+
const isOpen = open.has(value)
|
|
260
246
|
return (
|
|
261
247
|
<button
|
|
248
|
+
aria-expanded={isOpen}
|
|
262
249
|
className={cn(styles.trigger, className)}
|
|
263
250
|
onClick={() => toggle(value)}
|
|
251
|
+
{...props}
|
|
264
252
|
>
|
|
265
253
|
{children}
|
|
266
254
|
<ChevronDown className={cn(styles.icon, isOpen && 'rotate-180')} />
|
|
@@ -275,11 +263,12 @@ function Content({
|
|
|
275
263
|
children: React.ReactNode
|
|
276
264
|
className?: string
|
|
277
265
|
}) {
|
|
278
|
-
const {
|
|
279
|
-
const value =
|
|
280
|
-
const isOpen =
|
|
266
|
+
const { open } = useCtx()
|
|
267
|
+
const value = React.useContext(ItemCtx)
|
|
268
|
+
const isOpen = open.has(value)
|
|
281
269
|
return (
|
|
282
270
|
<div
|
|
271
|
+
role="region"
|
|
283
272
|
className={styles.panel}
|
|
284
273
|
style={{ gridTemplateRows: isOpen ? '1fr' : '0fr' }}
|
|
285
274
|
>
|
|
@@ -290,12 +279,19 @@ function Content({
|
|
|
290
279
|
)
|
|
291
280
|
}
|
|
292
281
|
|
|
282
|
+
const Ctx = React.createContext<AccordionCtx | null>(null)
|
|
283
|
+
const ItemCtx = React.createContext('')
|
|
284
|
+
|
|
285
|
+
function useCtx() {
|
|
286
|
+
const c = React.useContext(Ctx)
|
|
287
|
+
if (!c) throw new Error('Accordion compound used outside <Accordion>')
|
|
288
|
+
return c
|
|
289
|
+
}
|
|
290
|
+
|
|
293
291
|
export const Accordion = Object.assign(AccordionRoot, {
|
|
294
|
-
Item,
|
|
295
|
-
Trigger,
|
|
296
|
-
Content,
|
|
292
|
+
Item, Trigger, Content,
|
|
297
293
|
})
|
|
298
|
-
`;var
|
|
294
|
+
`;var X=`import * as React from 'react'
|
|
299
295
|
import { cn } from '@/utils/cn'
|
|
300
296
|
|
|
301
297
|
const styles = {
|
|
@@ -310,9 +306,7 @@ const styles = {
|
|
|
310
306
|
description: 'text-sm opacity-90',
|
|
311
307
|
}
|
|
312
308
|
|
|
313
|
-
type IconProp =
|
|
314
|
-
| React.ComponentType<{ className?: string }>
|
|
315
|
-
| React.ReactElement
|
|
309
|
+
type IconProp = React.ComponentType<{ className?: string }> | React.ReactElement
|
|
316
310
|
|
|
317
311
|
interface AlertProps {
|
|
318
312
|
variant?: keyof typeof styles.variants
|
|
@@ -345,7 +339,7 @@ export function Alert({
|
|
|
345
339
|
</div>
|
|
346
340
|
)
|
|
347
341
|
}
|
|
348
|
-
`;var
|
|
342
|
+
`;var q=`import * as React from 'react'
|
|
349
343
|
import { cn } from '@/utils/cn'
|
|
350
344
|
|
|
351
345
|
const styles = {
|
|
@@ -389,7 +383,7 @@ export function Avatar({
|
|
|
389
383
|
</div>
|
|
390
384
|
)
|
|
391
385
|
}
|
|
392
|
-
`;var
|
|
386
|
+
`;var J=`import * as React from 'react'
|
|
393
387
|
import { cn } from '@/utils/cn'
|
|
394
388
|
|
|
395
389
|
const styles = {
|
|
@@ -450,9 +444,7 @@ const styles = {
|
|
|
450
444
|
},
|
|
451
445
|
}
|
|
452
446
|
|
|
453
|
-
type IconProp =
|
|
454
|
-
| React.ComponentType<{ className?: string }>
|
|
455
|
-
| React.ReactElement
|
|
447
|
+
type IconProp = React.ComponentType<{ className?: string }> | React.ReactElement
|
|
456
448
|
|
|
457
449
|
interface ButtonProps
|
|
458
450
|
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
@@ -464,33 +456,22 @@ interface ButtonProps
|
|
|
464
456
|
rightIcon?: IconProp
|
|
465
457
|
}
|
|
466
458
|
|
|
467
|
-
export const Button = React.forwardRef<
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
children,
|
|
480
|
-
...props
|
|
481
|
-
},
|
|
482
|
-
ref
|
|
483
|
-
) => (
|
|
459
|
+
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(({
|
|
460
|
+
className,
|
|
461
|
+
variant = 'default',
|
|
462
|
+
size = 'md',
|
|
463
|
+
rounded = 'full',
|
|
464
|
+
loading,
|
|
465
|
+
disabled,
|
|
466
|
+
leftIcon: LeftIcon,
|
|
467
|
+
rightIcon: RightIcon,
|
|
468
|
+
children,
|
|
469
|
+
...props
|
|
470
|
+
}, ref) => (
|
|
484
471
|
<button
|
|
485
472
|
ref={ref}
|
|
486
473
|
disabled={loading || disabled}
|
|
487
|
-
className={cn(
|
|
488
|
-
styles.base,
|
|
489
|
-
styles.sizes[size],
|
|
490
|
-
styles.variants[variant],
|
|
491
|
-
styles.rounded[rounded],
|
|
492
|
-
className
|
|
493
|
-
)}
|
|
474
|
+
className={cn(styles.base, styles.sizes[size], styles.variants[variant], styles.rounded[rounded], className)}
|
|
494
475
|
{...props}
|
|
495
476
|
>
|
|
496
477
|
{loading && (
|
|
@@ -512,7 +493,7 @@ export const Button = React.forwardRef<
|
|
|
512
493
|
)
|
|
513
494
|
|
|
514
495
|
Button.displayName = 'Button'
|
|
515
|
-
`;var
|
|
496
|
+
`;var Q=`import * as React from 'react'
|
|
516
497
|
import { cn } from '@/utils/cn'
|
|
517
498
|
|
|
518
499
|
const styles = {
|
|
@@ -579,7 +560,7 @@ export const Card = Object.assign(CardRoot, {
|
|
|
579
560
|
Preview,
|
|
580
561
|
Info,
|
|
581
562
|
})
|
|
582
|
-
`;var
|
|
563
|
+
`;var Y=`'use client'
|
|
583
564
|
|
|
584
565
|
import * as React from 'react'
|
|
585
566
|
import { Check } from 'lucide-react'
|
|
@@ -596,42 +577,25 @@ const styles = {
|
|
|
596
577
|
label: 'text-sm text-foreground select-none',
|
|
597
578
|
}
|
|
598
579
|
|
|
599
|
-
interface CheckboxProps
|
|
600
|
-
extends Omit<
|
|
601
|
-
React.InputHTMLAttributes<HTMLInputElement>,
|
|
602
|
-
'type'
|
|
603
|
-
> {
|
|
580
|
+
interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {
|
|
604
581
|
label?: string
|
|
605
582
|
}
|
|
606
583
|
|
|
607
|
-
export const Checkbox = React.forwardRef<
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
...props
|
|
618
|
-
},
|
|
619
|
-
ref
|
|
620
|
-
) => {
|
|
621
|
-
const [internal, setInternal] = React.useState(
|
|
622
|
-
defaultChecked ?? false
|
|
623
|
-
)
|
|
584
|
+
export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(({
|
|
585
|
+
className,
|
|
586
|
+
label,
|
|
587
|
+
checked,
|
|
588
|
+
defaultChecked,
|
|
589
|
+
onChange,
|
|
590
|
+
disabled,
|
|
591
|
+
...props
|
|
592
|
+
}, ref) => {
|
|
593
|
+
const [internal, setInternal] = React.useState(defaultChecked ?? false)
|
|
624
594
|
const isControlled = checked !== undefined
|
|
625
595
|
const isChecked = isControlled ? checked : internal
|
|
626
596
|
|
|
627
597
|
return (
|
|
628
|
-
<label
|
|
629
|
-
className={cn(
|
|
630
|
-
styles.base,
|
|
631
|
-
disabled && 'opacity-50 cursor-default',
|
|
632
|
-
className
|
|
633
|
-
)}
|
|
634
|
-
>
|
|
598
|
+
<label className={cn(styles.base, disabled && 'opacity-50 cursor-default', className)}>
|
|
635
599
|
<input
|
|
636
600
|
ref={ref}
|
|
637
601
|
type="checkbox"
|
|
@@ -645,12 +609,7 @@ export const Checkbox = React.forwardRef<
|
|
|
645
609
|
}}
|
|
646
610
|
{...props}
|
|
647
611
|
/>
|
|
648
|
-
<span
|
|
649
|
-
className={cn(
|
|
650
|
-
styles.box,
|
|
651
|
-
isChecked && styles.checked
|
|
652
|
-
)}
|
|
653
|
-
>
|
|
612
|
+
<span className={cn(styles.box, isChecked && styles.checked)}>
|
|
654
613
|
{isChecked && (
|
|
655
614
|
<Check className="w-2.5 h-2.5 text-primary-foreground" />
|
|
656
615
|
)}
|
|
@@ -664,7 +623,7 @@ export const Checkbox = React.forwardRef<
|
|
|
664
623
|
)
|
|
665
624
|
|
|
666
625
|
Checkbox.displayName = 'Checkbox'
|
|
667
|
-
`;var
|
|
626
|
+
`;var Z=`'use client'
|
|
668
627
|
|
|
669
628
|
import * as React from 'react'
|
|
670
629
|
import { X } from 'lucide-react'
|
|
@@ -672,23 +631,24 @@ import { cn } from '@/utils/cn'
|
|
|
672
631
|
import { Button } from '@/components/ui/button'
|
|
673
632
|
|
|
674
633
|
const styles = {
|
|
675
|
-
|
|
676
|
-
'fixed inset-0
|
|
677
|
-
'
|
|
678
|
-
'
|
|
634
|
+
base: cn(
|
|
635
|
+
'fixed inset-0 m-0 p-0 border-none',
|
|
636
|
+
'max-w-none max-h-none w-screen h-dvh',
|
|
637
|
+
'flex items-center justify-center bg-overlay',
|
|
638
|
+
'backdrop-blur-sm transition-opacity duration-150',
|
|
639
|
+
'ease-out'
|
|
679
640
|
),
|
|
680
641
|
content: cn(
|
|
681
|
-
'relative w-full max-w-md mx-4 p-6',
|
|
642
|
+
'relative w-full max-w-md mx-4 p-6 shadow-xl',
|
|
682
643
|
'bg-card border border-border rounded-[20px]',
|
|
683
|
-
'shadow-xl',
|
|
684
644
|
'transition-[scale] duration-150 ease-out'
|
|
685
645
|
),
|
|
686
646
|
title: 'text-lg font-semibold text-foreground mb-4',
|
|
687
647
|
close: cn(
|
|
688
|
-
'absolute top-4 right-4 w-8 h-8',
|
|
648
|
+
'absolute top-4 right-4 w-8 h-8 cursor-pointer',
|
|
689
649
|
'flex items-center justify-center rounded-full',
|
|
690
650
|
'text-muted-foreground hover:text-foreground',
|
|
691
|
-
'hover:bg-accent transition-colors
|
|
651
|
+
'hover:bg-accent transition-colors'
|
|
692
652
|
),
|
|
693
653
|
}
|
|
694
654
|
|
|
@@ -697,14 +657,6 @@ interface DialogCtx {
|
|
|
697
657
|
setOpen: (v: boolean) => void
|
|
698
658
|
}
|
|
699
659
|
|
|
700
|
-
const Ctx = React.createContext<DialogCtx | null>(null)
|
|
701
|
-
|
|
702
|
-
function useDialog() {
|
|
703
|
-
const ctx = React.useContext(Ctx)
|
|
704
|
-
if (!ctx) throw new Error('Dialog compound used outside <Dialog>')
|
|
705
|
-
return ctx
|
|
706
|
-
}
|
|
707
|
-
|
|
708
660
|
function DialogRoot({
|
|
709
661
|
children,
|
|
710
662
|
open: controlled,
|
|
@@ -716,15 +668,16 @@ function DialogRoot({
|
|
|
716
668
|
}) {
|
|
717
669
|
const [uncontrolled, setUncontrolled] = React.useState(false)
|
|
718
670
|
const open = controlled ?? uncontrolled
|
|
719
|
-
const setOpen =
|
|
720
|
-
(v
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
},
|
|
724
|
-
[controlled, onOpenChange]
|
|
725
|
-
)
|
|
671
|
+
const setOpen = (v: boolean) => {
|
|
672
|
+
onOpenChange?.(v)
|
|
673
|
+
if (controlled === undefined) setUncontrolled(v)
|
|
674
|
+
}
|
|
726
675
|
|
|
727
|
-
return
|
|
676
|
+
return (
|
|
677
|
+
<Ctx.Provider value={{ open, setOpen }}>
|
|
678
|
+
{children}
|
|
679
|
+
</Ctx.Provider>
|
|
680
|
+
)
|
|
728
681
|
}
|
|
729
682
|
|
|
730
683
|
function Trigger({
|
|
@@ -756,43 +709,51 @@ function Content({
|
|
|
756
709
|
className?: string
|
|
757
710
|
}) {
|
|
758
711
|
const { open, setOpen } = useDialog()
|
|
712
|
+
const ref = React.useRef<HTMLDialogElement>(null)
|
|
713
|
+
const [visible, setVisible] = React.useState(false)
|
|
759
714
|
|
|
760
715
|
React.useEffect(() => {
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
716
|
+
const el = ref.current
|
|
717
|
+
if (!el) return
|
|
718
|
+
const onCancel = (e: Event) => {
|
|
719
|
+
e.preventDefault()
|
|
720
|
+
setOpen(false)
|
|
764
721
|
}
|
|
765
|
-
|
|
766
|
-
|
|
722
|
+
el.addEventListener('cancel', onCancel)
|
|
723
|
+
if (open) {
|
|
724
|
+
if (!el.open) el.showModal()
|
|
725
|
+
document.body.style.overflow = 'hidden'
|
|
726
|
+
requestAnimationFrame(() => setVisible(true))
|
|
727
|
+
return () => {
|
|
728
|
+
el.removeEventListener('cancel', onCancel)
|
|
729
|
+
document.body.style.overflow = ''
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
setVisible(false)
|
|
733
|
+
const id = setTimeout(() => {
|
|
734
|
+
if (el.open) el.close()
|
|
735
|
+
}, 150)
|
|
767
736
|
return () => {
|
|
768
|
-
|
|
769
|
-
|
|
737
|
+
el.removeEventListener('cancel', onCancel)
|
|
738
|
+
clearTimeout(id)
|
|
770
739
|
}
|
|
771
740
|
}, [open, setOpen])
|
|
772
741
|
|
|
773
742
|
return (
|
|
774
|
-
<
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
open
|
|
778
|
-
? 'opacity-100'
|
|
779
|
-
: 'opacity-0 pointer-events-none'
|
|
780
|
-
)}
|
|
743
|
+
<dialog
|
|
744
|
+
ref={ref}
|
|
745
|
+
className={cn(styles.base, visible ? 'opacity-100' : 'opacity-0 pointer-events-none')}
|
|
781
746
|
onClick={(e) => {
|
|
782
747
|
if (e.target === e.currentTarget) setOpen(false)
|
|
783
748
|
}}
|
|
784
749
|
>
|
|
785
|
-
<div
|
|
786
|
-
|
|
787
|
-
styles.
|
|
788
|
-
open ? 'scale-100' : 'scale-95',
|
|
789
|
-
className
|
|
750
|
+
<div className={cn(styles.content, visible ? 'scale-100' : 'scale-95', className)}>
|
|
751
|
+
{title && (
|
|
752
|
+
<h2 className={styles.title}>{title}</h2>
|
|
790
753
|
)}
|
|
791
|
-
>
|
|
792
|
-
{title && <h2 className={styles.title}>{title}</h2>}
|
|
793
754
|
{children}
|
|
794
755
|
</div>
|
|
795
|
-
</
|
|
756
|
+
</dialog>
|
|
796
757
|
)
|
|
797
758
|
}
|
|
798
759
|
|
|
@@ -808,12 +769,20 @@ function Close({ className }: { className?: string }) {
|
|
|
808
769
|
)
|
|
809
770
|
}
|
|
810
771
|
|
|
772
|
+
const Ctx = React.createContext<DialogCtx | null>(null)
|
|
773
|
+
|
|
774
|
+
function useDialog() {
|
|
775
|
+
const ctx = React.useContext(Ctx)
|
|
776
|
+
if (!ctx) throw new Error('Dialog compound used outside <Dialog>')
|
|
777
|
+
return ctx
|
|
778
|
+
}
|
|
779
|
+
|
|
811
780
|
export const Dialog = Object.assign(DialogRoot, {
|
|
812
781
|
Trigger,
|
|
813
782
|
Content,
|
|
814
783
|
Close,
|
|
815
784
|
})
|
|
816
|
-
`;var
|
|
785
|
+
`;var ee=`'use client'
|
|
817
786
|
|
|
818
787
|
import * as React from 'react'
|
|
819
788
|
import { cn } from '@/utils/cn'
|
|
@@ -851,15 +820,7 @@ interface DropdownCtx {
|
|
|
851
820
|
align: keyof typeof styles.align
|
|
852
821
|
}
|
|
853
822
|
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
function useDropdown() {
|
|
857
|
-
const ctx = React.useContext(Ctx)
|
|
858
|
-
if (!ctx) throw new Error(
|
|
859
|
-
'Dropdown compound used outside <Dropdown>'
|
|
860
|
-
)
|
|
861
|
-
return ctx
|
|
862
|
-
}
|
|
823
|
+
type IconProp = React.ComponentType<{ className?: string }> | React.ReactElement
|
|
863
824
|
|
|
864
825
|
function DropdownRoot({
|
|
865
826
|
children,
|
|
@@ -925,50 +886,35 @@ function Content({
|
|
|
925
886
|
}) {
|
|
926
887
|
const { open, align } = useDropdown()
|
|
927
888
|
return (
|
|
928
|
-
<div
|
|
929
|
-
className={cn(
|
|
930
|
-
styles.content,
|
|
931
|
-
styles.align[align],
|
|
932
|
-
open
|
|
933
|
-
? 'opacity-100 scale-100'
|
|
934
|
-
: 'opacity-0 scale-95 pointer-events-none',
|
|
935
|
-
className
|
|
936
|
-
)}
|
|
937
|
-
>
|
|
889
|
+
<div className={cn(styles.content, styles.align[align], open ? 'opacity-100 scale-100' : 'opacity-0 scale-95 pointer-events-none', className)}>
|
|
938
890
|
{children}
|
|
939
891
|
</div>
|
|
940
892
|
)
|
|
941
893
|
}
|
|
942
894
|
|
|
943
|
-
type IconProp =
|
|
944
|
-
| React.ComponentType<{ className?: string }>
|
|
945
|
-
| React.ReactElement
|
|
946
|
-
|
|
947
895
|
function Item({
|
|
948
896
|
children,
|
|
949
897
|
onClick,
|
|
950
898
|
icon: Icon,
|
|
951
899
|
destructive,
|
|
952
900
|
className,
|
|
901
|
+
...props
|
|
953
902
|
}: {
|
|
954
903
|
children: React.ReactNode
|
|
955
904
|
onClick?: () => void
|
|
956
905
|
icon?: IconProp
|
|
957
906
|
destructive?: boolean
|
|
958
907
|
className?: string
|
|
959
|
-
}) {
|
|
908
|
+
} & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onClick'>) {
|
|
960
909
|
const { setOpen } = useDropdown()
|
|
961
910
|
return (
|
|
962
911
|
<button
|
|
963
|
-
className={cn(
|
|
964
|
-
styles.item,
|
|
965
|
-
destructive && styles.destructive,
|
|
966
|
-
className
|
|
967
|
-
)}
|
|
912
|
+
className={cn(styles.item, destructive && styles.destructive, className)}
|
|
968
913
|
onClick={() => {
|
|
969
914
|
onClick?.()
|
|
970
915
|
setOpen(false)
|
|
971
916
|
}}
|
|
917
|
+
{...props}
|
|
972
918
|
>
|
|
973
919
|
{Icon && (
|
|
974
920
|
React.isValidElement(Icon)
|
|
@@ -1018,6 +964,14 @@ function DropdownSeparator({
|
|
|
1018
964
|
)
|
|
1019
965
|
}
|
|
1020
966
|
|
|
967
|
+
const Ctx = React.createContext<DropdownCtx | null>(null)
|
|
968
|
+
|
|
969
|
+
function useDropdown() {
|
|
970
|
+
const ctx = React.useContext(Ctx)
|
|
971
|
+
if (!ctx) throw new Error('Dropdown compound used outside <Dropdown>')
|
|
972
|
+
return ctx
|
|
973
|
+
}
|
|
974
|
+
|
|
1021
975
|
export const Dropdown = Object.assign(DropdownRoot, {
|
|
1022
976
|
Trigger,
|
|
1023
977
|
Content,
|
|
@@ -1026,7 +980,7 @@ export const Dropdown = Object.assign(DropdownRoot, {
|
|
|
1026
980
|
Label,
|
|
1027
981
|
Separator: DropdownSeparator,
|
|
1028
982
|
})
|
|
1029
|
-
`;var
|
|
983
|
+
`;var te=`import * as React from 'react'
|
|
1030
984
|
import { cn } from '@/utils/cn'
|
|
1031
985
|
|
|
1032
986
|
const styles = {
|
|
@@ -1040,14 +994,16 @@ const styles = {
|
|
|
1040
994
|
|
|
1041
995
|
type InputProps = React.InputHTMLAttributes<HTMLInputElement>
|
|
1042
996
|
|
|
1043
|
-
export const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|
1044
|
-
|
|
997
|
+
export const Input = React.forwardRef<HTMLInputElement, InputProps>(({
|
|
998
|
+
className,
|
|
999
|
+
...props
|
|
1000
|
+
}, ref) => (
|
|
1045
1001
|
<input ref={ref} className={cn(styles.base, className)} {...props} />
|
|
1046
1002
|
)
|
|
1047
1003
|
)
|
|
1048
1004
|
|
|
1049
1005
|
Input.displayName = 'Input'
|
|
1050
|
-
`;var
|
|
1006
|
+
`;var oe=`'use client'
|
|
1051
1007
|
|
|
1052
1008
|
import * as React from 'react'
|
|
1053
1009
|
import { cn } from '@/utils/cn'
|
|
@@ -1075,14 +1031,6 @@ interface PopoverCtx {
|
|
|
1075
1031
|
position: keyof typeof styles.positions
|
|
1076
1032
|
}
|
|
1077
1033
|
|
|
1078
|
-
const Ctx = React.createContext<PopoverCtx | null>(null)
|
|
1079
|
-
|
|
1080
|
-
function usePopover() {
|
|
1081
|
-
const ctx = React.useContext(Ctx)
|
|
1082
|
-
if (!ctx) throw new Error('Popover compound used outside <Popover>')
|
|
1083
|
-
return ctx
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
1034
|
function PopoverRoot({
|
|
1087
1035
|
children,
|
|
1088
1036
|
position = 'bottom',
|
|
@@ -1142,26 +1090,25 @@ function Content({
|
|
|
1142
1090
|
}) {
|
|
1143
1091
|
const { open, position } = usePopover()
|
|
1144
1092
|
return (
|
|
1145
|
-
<div
|
|
1146
|
-
className={cn(
|
|
1147
|
-
styles.content,
|
|
1148
|
-
styles.positions[position],
|
|
1149
|
-
open
|
|
1150
|
-
? 'opacity-100 scale-100'
|
|
1151
|
-
: 'opacity-0 scale-95 pointer-events-none',
|
|
1152
|
-
className
|
|
1153
|
-
)}
|
|
1154
|
-
>
|
|
1093
|
+
<div className={cn(styles.content, styles.positions[position], open ? 'opacity-100 scale-100' : 'opacity-0 scale-95 pointer-events-none', className)}>
|
|
1155
1094
|
{children}
|
|
1156
1095
|
</div>
|
|
1157
1096
|
)
|
|
1158
1097
|
}
|
|
1159
1098
|
|
|
1099
|
+
const Ctx = React.createContext<PopoverCtx | null>(null)
|
|
1100
|
+
|
|
1101
|
+
function usePopover() {
|
|
1102
|
+
const ctx = React.useContext(Ctx)
|
|
1103
|
+
if (!ctx) throw new Error('Popover compound used outside <Popover>')
|
|
1104
|
+
return ctx
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1160
1107
|
export const Popover = Object.assign(PopoverRoot, {
|
|
1161
1108
|
Trigger,
|
|
1162
1109
|
Content,
|
|
1163
1110
|
})
|
|
1164
|
-
`;var
|
|
1111
|
+
`;var ne=`import * as React from 'react'
|
|
1165
1112
|
import { cn } from '@/utils/cn'
|
|
1166
1113
|
|
|
1167
1114
|
const styles = {
|
|
@@ -1199,7 +1146,7 @@ export function Progress({
|
|
|
1199
1146
|
</div>
|
|
1200
1147
|
)
|
|
1201
1148
|
}
|
|
1202
|
-
`;var
|
|
1149
|
+
`;var re=`'use client'
|
|
1203
1150
|
|
|
1204
1151
|
import * as React from 'react'
|
|
1205
1152
|
import { ChevronDown } from 'lucide-react'
|
|
@@ -1238,14 +1185,6 @@ interface SelectCtx {
|
|
|
1238
1185
|
onSelect: (v: string) => void
|
|
1239
1186
|
}
|
|
1240
1187
|
|
|
1241
|
-
const Ctx = React.createContext<SelectCtx | null>(null)
|
|
1242
|
-
|
|
1243
|
-
function useSelect() {
|
|
1244
|
-
const ctx = React.useContext(Ctx)
|
|
1245
|
-
if (!ctx) throw new Error('Select compound used outside <Select>')
|
|
1246
|
-
return ctx
|
|
1247
|
-
}
|
|
1248
|
-
|
|
1249
1188
|
function SelectRoot({
|
|
1250
1189
|
children,
|
|
1251
1190
|
value,
|
|
@@ -1290,16 +1229,18 @@ function Trigger({
|
|
|
1290
1229
|
placeholder = 'Select...',
|
|
1291
1230
|
children,
|
|
1292
1231
|
className,
|
|
1232
|
+
...props
|
|
1293
1233
|
}: {
|
|
1294
1234
|
placeholder?: string
|
|
1295
1235
|
children?: React.ReactNode
|
|
1296
1236
|
className?: string
|
|
1297
|
-
}) {
|
|
1237
|
+
} & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onClick'>) {
|
|
1298
1238
|
const { open, setOpen } = useSelect()
|
|
1299
1239
|
return (
|
|
1300
1240
|
<button
|
|
1301
1241
|
className={cn(styles.trigger, className)}
|
|
1302
1242
|
onClick={() => setOpen(!open)}
|
|
1243
|
+
{...props}
|
|
1303
1244
|
>
|
|
1304
1245
|
<span className={!children ? styles.placeholder : undefined}>
|
|
1305
1246
|
{children ?? placeholder}
|
|
@@ -1318,15 +1259,7 @@ function Menu({
|
|
|
1318
1259
|
}) {
|
|
1319
1260
|
const { open } = useSelect()
|
|
1320
1261
|
return (
|
|
1321
|
-
<div
|
|
1322
|
-
className={cn(
|
|
1323
|
-
styles.menu,
|
|
1324
|
-
open
|
|
1325
|
-
? 'opacity-100 scale-100'
|
|
1326
|
-
: 'opacity-0 scale-95 pointer-events-none',
|
|
1327
|
-
className
|
|
1328
|
-
)}
|
|
1329
|
-
>
|
|
1262
|
+
<div className={cn(styles.menu, open ? 'opacity-100 scale-100' : 'opacity-0 scale-95 pointer-events-none', className)}>
|
|
1330
1263
|
{children}
|
|
1331
1264
|
</div>
|
|
1332
1265
|
)
|
|
@@ -1336,32 +1269,38 @@ function Option({
|
|
|
1336
1269
|
value: optValue,
|
|
1337
1270
|
children,
|
|
1338
1271
|
className,
|
|
1272
|
+
...props
|
|
1339
1273
|
}: {
|
|
1340
1274
|
value: string
|
|
1341
1275
|
children: React.ReactNode
|
|
1342
1276
|
className?: string
|
|
1343
|
-
}) {
|
|
1277
|
+
} & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onClick'>) {
|
|
1344
1278
|
const { value, onSelect } = useSelect()
|
|
1345
1279
|
return (
|
|
1346
1280
|
<button
|
|
1347
|
-
className={cn(
|
|
1348
|
-
styles.option,
|
|
1349
|
-
optValue === value && styles.selected,
|
|
1350
|
-
className
|
|
1351
|
-
)}
|
|
1281
|
+
className={cn(styles.option, optValue === value && styles.selected, className)}
|
|
1352
1282
|
onClick={() => onSelect(optValue)}
|
|
1283
|
+
{...props}
|
|
1353
1284
|
>
|
|
1354
1285
|
{children}
|
|
1355
1286
|
</button>
|
|
1356
1287
|
)
|
|
1357
1288
|
}
|
|
1358
1289
|
|
|
1290
|
+
const Ctx = React.createContext<SelectCtx | null>(null)
|
|
1291
|
+
|
|
1292
|
+
function useSelect() {
|
|
1293
|
+
const ctx = React.useContext(Ctx)
|
|
1294
|
+
if (!ctx) throw new Error('Select compound used outside <Select>')
|
|
1295
|
+
return ctx
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1359
1298
|
export const Select = Object.assign(SelectRoot, {
|
|
1360
1299
|
Trigger,
|
|
1361
1300
|
Menu,
|
|
1362
1301
|
Option,
|
|
1363
1302
|
})
|
|
1364
|
-
`;var
|
|
1303
|
+
`;var se=`import * as React from 'react'
|
|
1365
1304
|
import { cn } from '@/utils/cn'
|
|
1366
1305
|
|
|
1367
1306
|
const styles = {
|
|
@@ -1385,7 +1324,7 @@ export function Separator({
|
|
|
1385
1324
|
/>
|
|
1386
1325
|
)
|
|
1387
1326
|
}
|
|
1388
|
-
`;var
|
|
1327
|
+
`;var ae=`'use client'
|
|
1389
1328
|
|
|
1390
1329
|
import * as React from 'react'
|
|
1391
1330
|
import { cn } from '@/utils/cn'
|
|
@@ -1402,40 +1341,31 @@ const styles = {
|
|
|
1402
1341
|
),
|
|
1403
1342
|
}
|
|
1404
1343
|
|
|
1405
|
-
interface SwitchProps
|
|
1344
|
+
interface SwitchProps
|
|
1345
|
+
extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onChange'> {
|
|
1406
1346
|
checked?: boolean
|
|
1407
1347
|
onChange?: (checked: boolean) => void
|
|
1408
|
-
className?: string
|
|
1409
1348
|
}
|
|
1410
1349
|
|
|
1411
1350
|
export function Switch({
|
|
1412
1351
|
checked = false,
|
|
1413
1352
|
onChange,
|
|
1414
1353
|
className,
|
|
1354
|
+
...props
|
|
1415
1355
|
}: SwitchProps) {
|
|
1416
1356
|
return (
|
|
1417
1357
|
<button
|
|
1418
1358
|
role="switch"
|
|
1419
1359
|
aria-checked={checked}
|
|
1420
1360
|
onClick={() => onChange?.(!checked)}
|
|
1421
|
-
className={cn(
|
|
1422
|
-
|
|
1423
|
-
checked ? 'bg-primary' : 'bg-border',
|
|
1424
|
-
className
|
|
1425
|
-
)}
|
|
1361
|
+
className={cn(styles.base, checked ? 'bg-primary' : 'bg-border', className)}
|
|
1362
|
+
{...props}
|
|
1426
1363
|
>
|
|
1427
|
-
<span
|
|
1428
|
-
className={cn(
|
|
1429
|
-
styles.thumb,
|
|
1430
|
-
checked
|
|
1431
|
-
? 'translate-x-[25px]'
|
|
1432
|
-
: 'translate-x-[3px]'
|
|
1433
|
-
)}
|
|
1434
|
-
/>
|
|
1364
|
+
<span className={cn(styles.thumb, checked ? 'translate-x-[25px]' : 'translate-x-[3px]')} />
|
|
1435
1365
|
</button>
|
|
1436
1366
|
)
|
|
1437
1367
|
}
|
|
1438
|
-
`;var
|
|
1368
|
+
`;var ce=`'use client'
|
|
1439
1369
|
|
|
1440
1370
|
import * as React from 'react'
|
|
1441
1371
|
import { cn } from '@/utils/cn'
|
|
@@ -1455,14 +1385,6 @@ interface TabsCtx {
|
|
|
1455
1385
|
setValue: (v: string) => void
|
|
1456
1386
|
}
|
|
1457
1387
|
|
|
1458
|
-
const Ctx = React.createContext<TabsCtx | null>(null)
|
|
1459
|
-
|
|
1460
|
-
function useTabs() {
|
|
1461
|
-
const ctx = React.useContext(Ctx)
|
|
1462
|
-
if (!ctx) throw new Error('Tabs compound used outside <Tabs>')
|
|
1463
|
-
return ctx
|
|
1464
|
-
}
|
|
1465
|
-
|
|
1466
1388
|
function TabsRoot({
|
|
1467
1389
|
children,
|
|
1468
1390
|
defaultValue,
|
|
@@ -1476,9 +1398,7 @@ function TabsRoot({
|
|
|
1476
1398
|
onChange?: (value: string) => void
|
|
1477
1399
|
className?: string
|
|
1478
1400
|
}) {
|
|
1479
|
-
const [uncontrolled, setUncontrolled] = React.useState(
|
|
1480
|
-
defaultValue ?? ''
|
|
1481
|
-
)
|
|
1401
|
+
const [uncontrolled, setUncontrolled] = React.useState(defaultValue ?? '')
|
|
1482
1402
|
const value = controlled ?? uncontrolled
|
|
1483
1403
|
const setValue = React.useCallback(
|
|
1484
1404
|
(v: string) => {
|
|
@@ -1513,21 +1433,19 @@ function Tab({
|
|
|
1513
1433
|
value: tabValue,
|
|
1514
1434
|
children,
|
|
1515
1435
|
className,
|
|
1436
|
+
...props
|
|
1516
1437
|
}: {
|
|
1517
1438
|
value: string
|
|
1518
1439
|
children: React.ReactNode
|
|
1519
1440
|
className?: string
|
|
1520
|
-
}) {
|
|
1441
|
+
} & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onClick'>) {
|
|
1521
1442
|
const { value, setValue } = useTabs()
|
|
1522
1443
|
const isActive = value === tabValue
|
|
1523
1444
|
return (
|
|
1524
1445
|
<button
|
|
1525
|
-
className={cn(
|
|
1526
|
-
styles.tab,
|
|
1527
|
-
isActive ? styles.active : styles.inactive,
|
|
1528
|
-
className
|
|
1529
|
-
)}
|
|
1446
|
+
className={cn(styles.tab, isActive ? styles.active : styles.inactive, className)}
|
|
1530
1447
|
onClick={() => setValue(tabValue)}
|
|
1448
|
+
{...props}
|
|
1531
1449
|
>
|
|
1532
1450
|
{children}
|
|
1533
1451
|
</button>
|
|
@@ -1548,12 +1466,20 @@ function Panel({
|
|
|
1548
1466
|
return <div className={className}>{children}</div>
|
|
1549
1467
|
}
|
|
1550
1468
|
|
|
1469
|
+
const Ctx = React.createContext<TabsCtx | null>(null)
|
|
1470
|
+
|
|
1471
|
+
function useTabs() {
|
|
1472
|
+
const ctx = React.useContext(Ctx)
|
|
1473
|
+
if (!ctx) throw new Error('Tabs compound used outside <Tabs>')
|
|
1474
|
+
return ctx
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1551
1477
|
export const Tabs = Object.assign(TabsRoot, {
|
|
1552
1478
|
List,
|
|
1553
1479
|
Tab,
|
|
1554
1480
|
Panel,
|
|
1555
1481
|
})
|
|
1556
|
-
`;var
|
|
1482
|
+
`;var ie=`import * as React from 'react'
|
|
1557
1483
|
import { cn } from '@/utils/cn'
|
|
1558
1484
|
|
|
1559
1485
|
const styles = {
|
|
@@ -1568,10 +1494,10 @@ const styles = {
|
|
|
1568
1494
|
|
|
1569
1495
|
type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>
|
|
1570
1496
|
|
|
1571
|
-
export const Textarea = React.forwardRef<
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1497
|
+
export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(({
|
|
1498
|
+
className,
|
|
1499
|
+
...props
|
|
1500
|
+
}, ref) => (
|
|
1575
1501
|
<textarea
|
|
1576
1502
|
ref={ref}
|
|
1577
1503
|
className={cn(styles.base, className)}
|
|
@@ -1580,7 +1506,7 @@ export const Textarea = React.forwardRef<
|
|
|
1580
1506
|
))
|
|
1581
1507
|
|
|
1582
1508
|
Textarea.displayName = 'Textarea'
|
|
1583
|
-
`;var
|
|
1509
|
+
`;var le=`'use client'
|
|
1584
1510
|
|
|
1585
1511
|
import * as React from 'react'
|
|
1586
1512
|
import { Toaster as Sonner, toast } from 'sonner'
|
|
@@ -1623,7 +1549,7 @@ function Toaster() {
|
|
|
1623
1549
|
}
|
|
1624
1550
|
|
|
1625
1551
|
export { Toaster, toast }
|
|
1626
|
-
`;var
|
|
1552
|
+
`;var de=`import * as React from 'react'
|
|
1627
1553
|
import { cn } from '@/utils/cn'
|
|
1628
1554
|
|
|
1629
1555
|
const styles = {
|
|
@@ -1632,7 +1558,8 @@ const styles = {
|
|
|
1632
1558
|
'absolute z-50 px-2.5 py-1.5 text-xs font-medium',
|
|
1633
1559
|
'rounded-lg bg-foreground text-background',
|
|
1634
1560
|
'whitespace-nowrap pointer-events-none',
|
|
1635
|
-
'opacity-0 group-hover:opacity-100
|
|
1561
|
+
'opacity-0 group-hover:opacity-100',
|
|
1562
|
+
'group-focus-within:opacity-100 transition-opacity'
|
|
1636
1563
|
),
|
|
1637
1564
|
positions: {
|
|
1638
1565
|
top: 'bottom-full left-1/2 -translate-x-1/2 mb-2',
|
|
@@ -1656,7 +1583,10 @@ export function Tooltip({
|
|
|
1656
1583
|
children,
|
|
1657
1584
|
}: TooltipProps) {
|
|
1658
1585
|
return (
|
|
1659
|
-
<span
|
|
1586
|
+
<span
|
|
1587
|
+
tabIndex={0}
|
|
1588
|
+
className={cn(styles.base, 'outline-none', className)}
|
|
1589
|
+
>
|
|
1660
1590
|
{children}
|
|
1661
1591
|
<span className={cn(styles.tip, styles.positions[position])}>
|
|
1662
1592
|
{content}
|
|
@@ -1664,4 +1594,4 @@ export function Tooltip({
|
|
|
1664
1594
|
</span>
|
|
1665
1595
|
)
|
|
1666
1596
|
}
|
|
1667
|
-
`;var
|
|
1597
|
+
`;var R=[{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:"button",description:"Button with variants, sizes, loading state, and icon slots",dependencies:[],npmDependencies:[]},{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:"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:"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:"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:[]}],P={accordion:W,alert:X,avatar:q,badge:J,button:K,card:Q,checkbox:Y,dialog:Z,dropdown:ee,input:te,popover:oe,progress:ne,select:re,separator:se,switch:ae,tabs:ce,textarea:ie,theme:G,toast:le,tooltip:de};async function pe(t){let n=process.cwd();e.intro("drivn add");let c=V(n);if(c||(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:R.map(s=>({label:s.name,hint:s.description,value:s.name})),required:true});e.isCancel(o)&&(e.cancel("Cancelled"),process.exit(0)),t=o;}let v=t.filter(o=>!R.find(s=>s.name===o));v.length&&(e.log.error(`Unknown components: ${v.join(", ")}`),e.log.info("Available: "+R.map(o=>o.name).join(", ")),e.outro("Cancelled"),process.exit(1));let d=t.includes("theme"),m=t.filter(o=>o!=="theme"),f=new Set,b=new Set,g=o=>{if(f.has(o))return;let s=R.find(a=>a.name===o);s&&(s.dependencies.forEach(a=>g(a)),s.npmDependencies?.forEach(a=>b.add(a)),f.add(o));};m.forEach(g),d&&b.add("next-themes");let x=[...f].filter(o=>!m.includes(o));x.length&&e.log.info(`Required dependency: ${x.join(", ")}`);let l=c.typescript?"tsx":"jsx",N=join(n,c.paths.components);for(let o of f){let s=join(N,`${o}.${l}`);if(h(s)){let w=await e.confirm({message:`${o}.${l} exists. Overwrite?`,initialValue:false});if(e.isCancel(w)||!w){e.log.warn(`Skipped ${o}`);continue}}let a=P[o];a=a.replace(/@\/utils/g,`@/${c.paths.utils.replace(/^src\//,"")}`),p(s,a),e.log.success(`${o} \u2192 ${c.paths.components}/${o}.${l}`);}if(d){let o=join(N,`theme-provider.${l}`);if(h(o)){let a=await e.confirm({message:`theme-provider.${l} exists. Overwrite?`,initialValue:false});!e.isCancel(a)&&a?(p(o,P.theme),e.log.success(`theme-provider \u2192 ${c.paths.components}/theme-provider.${l}`)):e.log.warn("Skipped theme-provider");}else p(o,P.theme),e.log.success(`theme-provider \u2192 ${c.paths.components}/theme-provider.${l}`);if(c.paths.globals){let a=join(n,c.paths.globals);if(h(a)){let w=F(a);w.includes('[data-theme="dark"]')?e.log.warn("Theme tokens already exist in globals \u2014 skipped"):(p(a,w+L),e.log.success(`Theme tokens appended to ${i.cyan(c.paths.globals)}`));}else e.log.warn(`Globals file not found at ${c.paths.globals}`);}else e.log.warn('No globals path in drivn.config.json. Add "globals" to paths');let s=c.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 "${s}/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(b.size){let o=k(n),s=[...b],a=e.spinner();a.start("Installing packages");try{execSync(y(o,s),{cwd:n,stdio:"ignore"}),a.stop("Packages installed");}catch{a.stop("Failed to install packages"),e.log.warn(`Run manually: ${y(o,s)}`);}}e.outro("Done.");}var ue={version:"1.1.0"};var D=new Command;D.name("drivn").description("Drivn \u2014 Modern UI components").version(ue.version);D.command("create").description("Initialize Drivn in your project").action(U);D.command("add [components...]").description("Add components to your project").action(pe);D.parse();
|