drivn 1.10.0 → 1.12.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 +589 -29
- 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
|
|
2
|
+
import {Command}from'commander';import*as n from'@clack/prompts';import u from'picocolors';import {join,dirname}from'path';import {execSync}from'child_process';import {existsSync,readFileSync,writeFileSync,mkdirSync}from'fs';import {McpServer}from'@modelcontextprotocol/sdk/server/mcp.js';import {StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';import {z as z$1}from'zod';var z={next:"Next.js",react:"React"};function V(e){let r=join(e,"package.json");if(!existsSync(r))throw new Error("package.json not found");let t=JSON.parse(readFileSync(r,"utf-8")),a={...t.dependencies,...t.devDependencies},l="react";a.next&&(l="next");let d=existsSync(join(e,"src")),p=existsSync(join(e,"tsconfig.json"));return {framework:l,srcDir:d,typescript:p}}var F="drivn.config.json";function U(e){let r=join(e,F);return existsSync(r)?JSON.parse(readFileSync(r,"utf-8")):null}function K(e,r){let t=join(e,F);writeFileSync(t,JSON.stringify(r,null,2));}function Ve(e){existsSync(e)||mkdirSync(e,{recursive:true});}function b(e,r){Ve(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 W(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 Fe=`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
|
+
`,Ue=["src/app/globals.css","src/styles/globals.css","src/styles/globals.scss","app/globals.css"];function Ke(e){for(let r of Ue)if(x(join(e,r)))return r;return null}async function Y(){let e=process.cwd();console.log(""),console.log(u.bgCyan(u.bold(u.black(" Drivn "))));let r;try{r=V(e),n.log.success(`Detected ${u.cyan(z[r.framework])}`);}catch{n.log.error("No package.json found. Run this command in a project directory."),n.outro("Setup cancelled"),process.exit(1);}if(x(join(e,"drivn.config.json"))){let s=await n.confirm({message:"Config already exists. Overwrite?",initialValue:false});(n.isCancel(s)||!s)&&(n.cancel("Setup cancelled"),process.exit(0));}let t=r.srcDir?"src/components/ui":"components/ui",a=r.srcDir?"src/utils":"utils",l=await n.group({components:()=>n.text({message:"Where should components be installed?",placeholder:t,defaultValue:t}),utils:()=>n.text({message:"Where should utilities be placed?",placeholder:a,defaultValue:a})},{onCancel:()=>{n.cancel("Setup cancelled"),process.exit(0);}}),d={framework:r.framework,typescript:r.typescript,paths:{components:l.components,utils:l.utils},installed:[]},p=r.typescript?"ts":"js",f=join(e,l.utils,`cn.${p}`);x(f)||b(f,Fe);let g=Ke(e);if(g){let s=await n.confirm({message:`Found ${u.cyan(g)}. Add Drivn color tokens?`,initialValue:true});!n.isCancel(s)&&s&&(b(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)||(b(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=W(N),h=["clsx","tailwind-merge","lucide-react"],o=n.spinner();o.start("Installing dependencies");try{execSync(w(N,h),{cwd:e,stdio:"ignore"}),o.stop("Dependencies installed");}catch{o.stop("Failed to install dependencies"),n.log.warn(`Run manually: ${w(N,h)}`);}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
|
|
|
@@ -161,7 +161,7 @@ export function ThemeProvider({
|
|
|
161
161
|
</NextThemesProvider>
|
|
162
162
|
)
|
|
163
163
|
}
|
|
164
|
-
`;var
|
|
164
|
+
`;var q=`'use client'
|
|
165
165
|
|
|
166
166
|
import * as React from 'react'
|
|
167
167
|
import { ChevronDown } from 'lucide-react'
|
|
@@ -293,7 +293,7 @@ export const Accordion = Object.assign(AccordionRoot, {
|
|
|
293
293
|
Trigger,
|
|
294
294
|
Content
|
|
295
295
|
})
|
|
296
|
-
`;var
|
|
296
|
+
`;var J=`import * as React from 'react'
|
|
297
297
|
import { cn } from '@/utils/cn'
|
|
298
298
|
|
|
299
299
|
const styles = {
|
|
@@ -1646,6 +1646,401 @@ export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(({
|
|
|
1646
1646
|
Checkbox.displayName = 'Checkbox'
|
|
1647
1647
|
`;var le=`'use client'
|
|
1648
1648
|
|
|
1649
|
+
import * as React from 'react'
|
|
1650
|
+
import { Command as CommandPrimitive } from 'cmdk'
|
|
1651
|
+
import { ChevronDown, X, Check, Search } from 'lucide-react'
|
|
1652
|
+
import { cn } from '@/utils/cn'
|
|
1653
|
+
|
|
1654
|
+
const styles = {
|
|
1655
|
+
base: 'relative',
|
|
1656
|
+
trigger: {
|
|
1657
|
+
base: cn(
|
|
1658
|
+
'flex items-center justify-between w-full min-h-10',
|
|
1659
|
+
'px-3 gap-2',
|
|
1660
|
+
'border border-input rounded-[10px] text-sm',
|
|
1661
|
+
'focus:outline-none transition-colors',
|
|
1662
|
+
'cursor-pointer'
|
|
1663
|
+
),
|
|
1664
|
+
singleText: 'flex-1 truncate text-left',
|
|
1665
|
+
multiText: cn(
|
|
1666
|
+
'flex flex-1 flex-wrap items-center gap-1',
|
|
1667
|
+
'min-h-[36px] py-1'
|
|
1668
|
+
),
|
|
1669
|
+
placeholder: 'text-muted-foreground',
|
|
1670
|
+
chevron: cn(
|
|
1671
|
+
'w-4 h-4 shrink-0 text-muted-foreground',
|
|
1672
|
+
'transition-transform duration-200'
|
|
1673
|
+
),
|
|
1674
|
+
clear: cn(
|
|
1675
|
+
'w-4 h-4 shrink-0 text-muted-foreground',
|
|
1676
|
+
'hover:text-foreground transition-colors'
|
|
1677
|
+
),
|
|
1678
|
+
},
|
|
1679
|
+
tag: {
|
|
1680
|
+
base: cn(
|
|
1681
|
+
'inline-flex items-center gap-1 px-2 py-0.5',
|
|
1682
|
+
'text-xs rounded-md bg-muted text-foreground'
|
|
1683
|
+
),
|
|
1684
|
+
remove: cn(
|
|
1685
|
+
'w-3 h-3 text-muted-foreground',
|
|
1686
|
+
'hover:text-foreground cursor-pointer'
|
|
1687
|
+
),
|
|
1688
|
+
},
|
|
1689
|
+
content: cn(
|
|
1690
|
+
'absolute top-full left-0 right-0 mt-1 z-50',
|
|
1691
|
+
'bg-card border border-border rounded-[10px]',
|
|
1692
|
+
'shadow-lg overflow-hidden',
|
|
1693
|
+
'transition-[opacity,scale] duration-150 ease-out'
|
|
1694
|
+
),
|
|
1695
|
+
input: {
|
|
1696
|
+
wrapper: cn(
|
|
1697
|
+
'flex items-center gap-2 px-3',
|
|
1698
|
+
'border-b border-border'
|
|
1699
|
+
),
|
|
1700
|
+
icon: 'w-4 h-4 shrink-0 text-muted-foreground',
|
|
1701
|
+
field: cn(
|
|
1702
|
+
'flex h-10 w-full bg-transparent py-2',
|
|
1703
|
+
'text-sm text-foreground outline-none',
|
|
1704
|
+
'placeholder:text-muted-foreground'
|
|
1705
|
+
),
|
|
1706
|
+
},
|
|
1707
|
+
list: cn(
|
|
1708
|
+
'max-h-[200px] overflow-y-auto p-1',
|
|
1709
|
+
'[&_[cmdk-list-sizer]]:space-y-0.5'
|
|
1710
|
+
),
|
|
1711
|
+
empty: cn(
|
|
1712
|
+
'py-6 text-center text-sm',
|
|
1713
|
+
'text-muted-foreground'
|
|
1714
|
+
),
|
|
1715
|
+
group: cn(
|
|
1716
|
+
'overflow-hidden',
|
|
1717
|
+
'[&_[cmdk-group-heading]]:px-1.5',
|
|
1718
|
+
'[&_[cmdk-group-heading]]:py-1.5',
|
|
1719
|
+
'[&_[cmdk-group-heading]]:text-xs',
|
|
1720
|
+
'[&_[cmdk-group-heading]]:font-medium',
|
|
1721
|
+
'[&_[cmdk-group-heading]]:text-muted-foreground'
|
|
1722
|
+
),
|
|
1723
|
+
label: cn(
|
|
1724
|
+
'px-1.5 py-1.5 text-xs font-medium',
|
|
1725
|
+
'text-muted-foreground'
|
|
1726
|
+
),
|
|
1727
|
+
item: cn(
|
|
1728
|
+
'relative flex items-center gap-2 px-2.5 py-1.5',
|
|
1729
|
+
'text-sm rounded-lg cursor-default select-none',
|
|
1730
|
+
'data-[selected=true]:bg-accent',
|
|
1731
|
+
'data-[disabled=true]:pointer-events-none',
|
|
1732
|
+
'data-[disabled=true]:opacity-50'
|
|
1733
|
+
),
|
|
1734
|
+
icon: 'w-4 h-4 shrink-0 text-primary ml-auto',
|
|
1735
|
+
separator: 'w-full h-px bg-border',
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1738
|
+
type IconProp = React.ComponentType<{ className?: string }> | React.ReactElement
|
|
1739
|
+
|
|
1740
|
+
interface ComboboxCtx {
|
|
1741
|
+
open: boolean
|
|
1742
|
+
setOpen: (v: boolean) => void
|
|
1743
|
+
multiple: boolean
|
|
1744
|
+
value: string | string[]
|
|
1745
|
+
onSelect: (v: string) => void
|
|
1746
|
+
onClear: () => void
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
function ComboboxRoot({
|
|
1750
|
+
children,
|
|
1751
|
+
value,
|
|
1752
|
+
onChange,
|
|
1753
|
+
multiple = false,
|
|
1754
|
+
className,
|
|
1755
|
+
}: {
|
|
1756
|
+
children: React.ReactNode
|
|
1757
|
+
value?: string | string[]
|
|
1758
|
+
onChange?: (value: string | string[]) => void
|
|
1759
|
+
multiple?: boolean
|
|
1760
|
+
className?: string
|
|
1761
|
+
}) {
|
|
1762
|
+
const [open, setOpen] = React.useState(false)
|
|
1763
|
+
const ref = React.useRef<HTMLDivElement>(null)
|
|
1764
|
+
const close = React.useCallback(() => setOpen(false), [])
|
|
1765
|
+
|
|
1766
|
+
const onSelect = React.useCallback(
|
|
1767
|
+
(v: string) => {
|
|
1768
|
+
if (multiple) {
|
|
1769
|
+
const arr = (value as string[]) ?? []
|
|
1770
|
+
const next = arr.includes(v)
|
|
1771
|
+
? arr.filter((i) => i !== v)
|
|
1772
|
+
: [...arr, v]
|
|
1773
|
+
onChange?.(next)
|
|
1774
|
+
} else {
|
|
1775
|
+
onChange?.(v)
|
|
1776
|
+
close()
|
|
1777
|
+
}
|
|
1778
|
+
},
|
|
1779
|
+
[multiple, value, onChange, close]
|
|
1780
|
+
)
|
|
1781
|
+
|
|
1782
|
+
const onClear = React.useCallback(() => {
|
|
1783
|
+
onChange?.(multiple ? [] : '')
|
|
1784
|
+
}, [multiple, onChange])
|
|
1785
|
+
|
|
1786
|
+
React.useEffect(() => {
|
|
1787
|
+
const onClick = (e: MouseEvent) => {
|
|
1788
|
+
if (!ref.current?.contains(e.target as Node))
|
|
1789
|
+
close()
|
|
1790
|
+
}
|
|
1791
|
+
document.addEventListener('mousedown', onClick)
|
|
1792
|
+
return () =>
|
|
1793
|
+
document.removeEventListener('mousedown', onClick)
|
|
1794
|
+
}, [close])
|
|
1795
|
+
|
|
1796
|
+
return (
|
|
1797
|
+
<Ctx.Provider
|
|
1798
|
+
value={{
|
|
1799
|
+
open,
|
|
1800
|
+
setOpen,
|
|
1801
|
+
multiple,
|
|
1802
|
+
value: value ?? (multiple ? [] : ''),
|
|
1803
|
+
onSelect,
|
|
1804
|
+
onClear,
|
|
1805
|
+
}}
|
|
1806
|
+
>
|
|
1807
|
+
<div ref={ref} className={cn(styles.base, className)}>
|
|
1808
|
+
{children}
|
|
1809
|
+
</div>
|
|
1810
|
+
</Ctx.Provider>
|
|
1811
|
+
)
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
function Trigger({
|
|
1815
|
+
placeholder = 'Select...',
|
|
1816
|
+
clearable = false,
|
|
1817
|
+
children,
|
|
1818
|
+
className,
|
|
1819
|
+
...props
|
|
1820
|
+
}: {
|
|
1821
|
+
placeholder?: string
|
|
1822
|
+
clearable?: boolean
|
|
1823
|
+
children?: React.ReactNode
|
|
1824
|
+
className?: string
|
|
1825
|
+
} & Omit<
|
|
1826
|
+
React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
1827
|
+
'onClick'
|
|
1828
|
+
>) {
|
|
1829
|
+
const { open, setOpen, multiple, value, onSelect, onClear } = useCombobox()
|
|
1830
|
+
|
|
1831
|
+
const values = Array.isArray(value) ? value : []
|
|
1832
|
+
|
|
1833
|
+
const hasValue = multiple
|
|
1834
|
+
? values.length > 0
|
|
1835
|
+
: (value as string) !== ''
|
|
1836
|
+
|
|
1837
|
+
return (
|
|
1838
|
+
<button
|
|
1839
|
+
className={cn(styles.trigger.base, className)}
|
|
1840
|
+
onClick={() => setOpen(!open)}
|
|
1841
|
+
{...props}
|
|
1842
|
+
>
|
|
1843
|
+
{multiple ? (
|
|
1844
|
+
<span className={styles.trigger.multiText}>
|
|
1845
|
+
{values.length === 0 ? (
|
|
1846
|
+
<span className={styles.trigger.placeholder}>
|
|
1847
|
+
{placeholder}
|
|
1848
|
+
</span>
|
|
1849
|
+
) : (
|
|
1850
|
+
<>
|
|
1851
|
+
{values.map((v) => (
|
|
1852
|
+
<span key={v} className={styles.tag.base}>
|
|
1853
|
+
{v}
|
|
1854
|
+
<X
|
|
1855
|
+
className={styles.tag.remove}
|
|
1856
|
+
onMouseDown={(e) => {
|
|
1857
|
+
e.stopPropagation()
|
|
1858
|
+
e.preventDefault()
|
|
1859
|
+
onSelect(v)
|
|
1860
|
+
}}
|
|
1861
|
+
/>
|
|
1862
|
+
</span>
|
|
1863
|
+
))}
|
|
1864
|
+
</>
|
|
1865
|
+
)}
|
|
1866
|
+
</span>
|
|
1867
|
+
) : (
|
|
1868
|
+
<span
|
|
1869
|
+
className={cn(
|
|
1870
|
+
styles.trigger.singleText,
|
|
1871
|
+
!hasValue && styles.trigger.placeholder
|
|
1872
|
+
)}
|
|
1873
|
+
>
|
|
1874
|
+
{hasValue ? (children ?? value) : placeholder}
|
|
1875
|
+
</span>
|
|
1876
|
+
)}
|
|
1877
|
+
{clearable && hasValue ? (
|
|
1878
|
+
<X
|
|
1879
|
+
className={styles.trigger.clear}
|
|
1880
|
+
onMouseDown={(e) => {
|
|
1881
|
+
e.stopPropagation()
|
|
1882
|
+
e.preventDefault()
|
|
1883
|
+
onClear()
|
|
1884
|
+
}}
|
|
1885
|
+
/>
|
|
1886
|
+
) : (
|
|
1887
|
+
<ChevronDown className={cn(styles.trigger.chevron, open && 'rotate-180')} />
|
|
1888
|
+
)}
|
|
1889
|
+
</button>
|
|
1890
|
+
)
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
function Content({
|
|
1894
|
+
placeholder = 'Search...',
|
|
1895
|
+
children,
|
|
1896
|
+
className,
|
|
1897
|
+
}: {
|
|
1898
|
+
placeholder?: string
|
|
1899
|
+
children: React.ReactNode
|
|
1900
|
+
className?: string
|
|
1901
|
+
}) {
|
|
1902
|
+
const { open } = useCombobox()
|
|
1903
|
+
|
|
1904
|
+
return (
|
|
1905
|
+
<div
|
|
1906
|
+
className={cn(
|
|
1907
|
+
styles.content,
|
|
1908
|
+
open ? 'opacity-100 scale-100' : 'opacity-0 scale-95 pointer-events-none',
|
|
1909
|
+
className
|
|
1910
|
+
)}
|
|
1911
|
+
>
|
|
1912
|
+
<CommandPrimitive key={open ? 'open' : 'closed'} shouldFilter>
|
|
1913
|
+
<div className={styles.input.wrapper}>
|
|
1914
|
+
<Search className={styles.input.icon} />
|
|
1915
|
+
<CommandPrimitive.Input
|
|
1916
|
+
autoFocus
|
|
1917
|
+
className={styles.input.field}
|
|
1918
|
+
placeholder={placeholder}
|
|
1919
|
+
/>
|
|
1920
|
+
</div>
|
|
1921
|
+
<CommandPrimitive.List className={styles.list}>
|
|
1922
|
+
{children}
|
|
1923
|
+
</CommandPrimitive.List>
|
|
1924
|
+
</CommandPrimitive>
|
|
1925
|
+
</div>
|
|
1926
|
+
)
|
|
1927
|
+
}
|
|
1928
|
+
|
|
1929
|
+
function Empty({
|
|
1930
|
+
children,
|
|
1931
|
+
className,
|
|
1932
|
+
}: {
|
|
1933
|
+
children?: React.ReactNode
|
|
1934
|
+
className?: string
|
|
1935
|
+
}) {
|
|
1936
|
+
return (
|
|
1937
|
+
<CommandPrimitive.Empty className={cn(styles.empty, className)}>
|
|
1938
|
+
{children ?? 'No results found.'}
|
|
1939
|
+
</CommandPrimitive.Empty>
|
|
1940
|
+
)
|
|
1941
|
+
}
|
|
1942
|
+
|
|
1943
|
+
function Group({
|
|
1944
|
+
heading,
|
|
1945
|
+
children,
|
|
1946
|
+
className,
|
|
1947
|
+
}: {
|
|
1948
|
+
heading?: string
|
|
1949
|
+
children: React.ReactNode
|
|
1950
|
+
className?: string
|
|
1951
|
+
}) {
|
|
1952
|
+
return (
|
|
1953
|
+
<CommandPrimitive.Group
|
|
1954
|
+
heading={heading}
|
|
1955
|
+
className={cn(styles.group, className)}
|
|
1956
|
+
>
|
|
1957
|
+
{children}
|
|
1958
|
+
</CommandPrimitive.Group>
|
|
1959
|
+
)
|
|
1960
|
+
}
|
|
1961
|
+
|
|
1962
|
+
function ComboboxLabel({
|
|
1963
|
+
children,
|
|
1964
|
+
className,
|
|
1965
|
+
}: {
|
|
1966
|
+
children: React.ReactNode
|
|
1967
|
+
className?: string
|
|
1968
|
+
}) {
|
|
1969
|
+
return (
|
|
1970
|
+
<div className={cn(styles.label, className)}>
|
|
1971
|
+
{children}
|
|
1972
|
+
</div>
|
|
1973
|
+
)
|
|
1974
|
+
}
|
|
1975
|
+
|
|
1976
|
+
function Item({
|
|
1977
|
+
value: itemValue,
|
|
1978
|
+
icon: Icon,
|
|
1979
|
+
disabled,
|
|
1980
|
+
children,
|
|
1981
|
+
className,
|
|
1982
|
+
...props
|
|
1983
|
+
}: {
|
|
1984
|
+
value: string
|
|
1985
|
+
icon?: IconProp
|
|
1986
|
+
disabled?: boolean
|
|
1987
|
+
children: React.ReactNode
|
|
1988
|
+
className?: string
|
|
1989
|
+
} & Omit<
|
|
1990
|
+
React.ComponentProps<typeof CommandPrimitive.Item>,
|
|
1991
|
+
'onSelect' | 'value'
|
|
1992
|
+
>) {
|
|
1993
|
+
const { value, onSelect, multiple } = useCombobox()
|
|
1994
|
+
const isSelected = multiple
|
|
1995
|
+
? (value as string[]).includes(itemValue)
|
|
1996
|
+
: value === itemValue
|
|
1997
|
+
|
|
1998
|
+
return (
|
|
1999
|
+
<CommandPrimitive.Item
|
|
2000
|
+
value={itemValue}
|
|
2001
|
+
disabled={disabled}
|
|
2002
|
+
onSelect={() => onSelect(itemValue)}
|
|
2003
|
+
className={cn(styles.item, className)}
|
|
2004
|
+
{...props}
|
|
2005
|
+
>
|
|
2006
|
+
{Icon && (React.isValidElement(Icon) ? Icon : <Icon className="w-4 h-4" />)}
|
|
2007
|
+
{children}
|
|
2008
|
+
{isSelected && (
|
|
2009
|
+
<Check className={styles.icon} />
|
|
2010
|
+
)}
|
|
2011
|
+
</CommandPrimitive.Item>
|
|
2012
|
+
)
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
function ComboboxSeparator({
|
|
2016
|
+
className,
|
|
2017
|
+
}: {
|
|
2018
|
+
className?: string
|
|
2019
|
+
}) {
|
|
2020
|
+
return (
|
|
2021
|
+
<CommandPrimitive.Separator className={cn(styles.separator, className)} />
|
|
2022
|
+
)
|
|
2023
|
+
}
|
|
2024
|
+
|
|
2025
|
+
const Ctx = React.createContext<ComboboxCtx | null>(null)
|
|
2026
|
+
|
|
2027
|
+
function useCombobox() {
|
|
2028
|
+
const ctx = React.useContext(Ctx)
|
|
2029
|
+
if (!ctx) throw new Error('Combobox compound used outside <Combobox>')
|
|
2030
|
+
return ctx
|
|
2031
|
+
}
|
|
2032
|
+
|
|
2033
|
+
export const Combobox = Object.assign(ComboboxRoot, {
|
|
2034
|
+
Trigger,
|
|
2035
|
+
Content,
|
|
2036
|
+
Empty,
|
|
2037
|
+
Group,
|
|
2038
|
+
Label: ComboboxLabel,
|
|
2039
|
+
Item,
|
|
2040
|
+
Separator: ComboboxSeparator,
|
|
2041
|
+
})
|
|
2042
|
+
`;var de=`'use client'
|
|
2043
|
+
|
|
1649
2044
|
import * as React from 'react'
|
|
1650
2045
|
import { cn } from '@/utils/cn'
|
|
1651
2046
|
|
|
@@ -1758,7 +2153,7 @@ export const Collapsible = Object.assign(CollapsibleRoot, {
|
|
|
1758
2153
|
Trigger,
|
|
1759
2154
|
Content,
|
|
1760
2155
|
})
|
|
1761
|
-
`;var
|
|
2156
|
+
`;var pe=`'use client'
|
|
1762
2157
|
|
|
1763
2158
|
import * as React from 'react'
|
|
1764
2159
|
import { X } from 'lucide-react'
|
|
@@ -1914,7 +2309,7 @@ export const Dialog = Object.assign(DialogRoot, {
|
|
|
1914
2309
|
Trigger,
|
|
1915
2310
|
Content,
|
|
1916
2311
|
})
|
|
1917
|
-
`;var
|
|
2312
|
+
`;var ue=`'use client'
|
|
1918
2313
|
|
|
1919
2314
|
import * as React from 'react'
|
|
1920
2315
|
import { X } from 'lucide-react'
|
|
@@ -2331,7 +2726,7 @@ export const Dropdown = Object.assign(DropdownRoot, {
|
|
|
2331
2726
|
Label,
|
|
2332
2727
|
Separator: DropdownSeparator
|
|
2333
2728
|
})
|
|
2334
|
-
`;var
|
|
2729
|
+
`;var fe=`import * as React from 'react'
|
|
2335
2730
|
import { cn } from '@/utils/cn'
|
|
2336
2731
|
|
|
2337
2732
|
const styles = {
|
|
@@ -2354,7 +2749,7 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(({
|
|
|
2354
2749
|
)
|
|
2355
2750
|
|
|
2356
2751
|
Input.displayName = 'Input'
|
|
2357
|
-
`;var
|
|
2752
|
+
`;var ge=`import * as React from 'react'
|
|
2358
2753
|
import { cn } from '@/utils/cn'
|
|
2359
2754
|
|
|
2360
2755
|
const styles = {
|
|
@@ -2411,7 +2806,7 @@ function Group({
|
|
|
2411
2806
|
}
|
|
2412
2807
|
|
|
2413
2808
|
export const Kbd = Object.assign(KbdRoot, { Group })
|
|
2414
|
-
`;var
|
|
2809
|
+
`;var he=`import * as React from 'react'
|
|
2415
2810
|
import { cn } from '@/utils/cn'
|
|
2416
2811
|
|
|
2417
2812
|
export function Label({
|
|
@@ -2428,7 +2823,7 @@ export function Label({
|
|
|
2428
2823
|
/>
|
|
2429
2824
|
)
|
|
2430
2825
|
}
|
|
2431
|
-
`;var
|
|
2826
|
+
`;var be=`import * as React from 'react'
|
|
2432
2827
|
import { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react'
|
|
2433
2828
|
import { cn } from '@/utils/cn'
|
|
2434
2829
|
|
|
@@ -2561,7 +2956,7 @@ export const Pagination = Object.assign(PaginationRoot, {
|
|
|
2561
2956
|
Next,
|
|
2562
2957
|
Ellipsis: PaginationEllipsis,
|
|
2563
2958
|
})
|
|
2564
|
-
`;var
|
|
2959
|
+
`;var ve=`'use client'
|
|
2565
2960
|
|
|
2566
2961
|
import * as React from 'react'
|
|
2567
2962
|
import { cn } from '@/utils/cn'
|
|
@@ -2666,7 +3061,7 @@ export const Popover = Object.assign(PopoverRoot, {
|
|
|
2666
3061
|
Trigger,
|
|
2667
3062
|
Content
|
|
2668
3063
|
})
|
|
2669
|
-
`;var
|
|
3064
|
+
`;var xe=`import * as React from 'react'
|
|
2670
3065
|
import { cn } from '@/utils/cn'
|
|
2671
3066
|
|
|
2672
3067
|
const styles = {
|
|
@@ -2704,7 +3099,7 @@ export function Progress({
|
|
|
2704
3099
|
</div>
|
|
2705
3100
|
)
|
|
2706
3101
|
}
|
|
2707
|
-
`;var
|
|
3102
|
+
`;var ye=`'use client'
|
|
2708
3103
|
|
|
2709
3104
|
import * as React from 'react'
|
|
2710
3105
|
import { cn } from '@/utils/cn'
|
|
@@ -2853,7 +3248,7 @@ function useRadioGroup() {
|
|
|
2853
3248
|
}
|
|
2854
3249
|
|
|
2855
3250
|
export const RadioGroup = Object.assign(RadioGroupRoot, { Item })
|
|
2856
|
-
`;var
|
|
3251
|
+
`;var Ne=`'use client'
|
|
2857
3252
|
|
|
2858
3253
|
import * as React from 'react'
|
|
2859
3254
|
import { ChevronDown } from 'lucide-react'
|
|
@@ -2945,6 +3340,7 @@ function Trigger({
|
|
|
2945
3340
|
const { open, setOpen } = useSelect()
|
|
2946
3341
|
return (
|
|
2947
3342
|
<button
|
|
3343
|
+
type="button"
|
|
2948
3344
|
className={cn(styles.trigger, className)}
|
|
2949
3345
|
onClick={() => setOpen(!open)}
|
|
2950
3346
|
{...props}
|
|
@@ -2985,6 +3381,7 @@ function Option({
|
|
|
2985
3381
|
const { value, onSelect } = useSelect()
|
|
2986
3382
|
return (
|
|
2987
3383
|
<button
|
|
3384
|
+
type="button"
|
|
2988
3385
|
className={cn(styles.option, optValue === value && styles.selected, className)}
|
|
2989
3386
|
onClick={() => onSelect(optValue)}
|
|
2990
3387
|
{...props}
|
|
@@ -3007,7 +3404,7 @@ export const Select = Object.assign(SelectRoot, {
|
|
|
3007
3404
|
Menu,
|
|
3008
3405
|
Option
|
|
3009
3406
|
})
|
|
3010
|
-
`;var
|
|
3407
|
+
`;var Ce=`import * as React from 'react'
|
|
3011
3408
|
import { cn } from '@/utils/cn'
|
|
3012
3409
|
|
|
3013
3410
|
const styles = {
|
|
@@ -3053,7 +3450,7 @@ export function ScrollArea({
|
|
|
3053
3450
|
</div>
|
|
3054
3451
|
)
|
|
3055
3452
|
}
|
|
3056
|
-
`;var
|
|
3453
|
+
`;var Re=`import * as React from 'react'
|
|
3057
3454
|
import { cn } from '@/utils/cn'
|
|
3058
3455
|
|
|
3059
3456
|
const styles = {
|
|
@@ -3094,7 +3491,7 @@ export function Skeleton({
|
|
|
3094
3491
|
/>
|
|
3095
3492
|
)
|
|
3096
3493
|
}
|
|
3097
|
-
`;var
|
|
3494
|
+
`;var ke=`'use client'
|
|
3098
3495
|
|
|
3099
3496
|
import * as React from 'react'
|
|
3100
3497
|
import { ChevronDown, PanelLeft } from 'lucide-react'
|
|
@@ -3380,7 +3777,7 @@ export const Sidebar = Object.assign(SidebarRoot, {
|
|
|
3380
3777
|
Separator: SidebarSeparator,
|
|
3381
3778
|
CollapseButton,
|
|
3382
3779
|
})
|
|
3383
|
-
`;var
|
|
3780
|
+
`;var Pe=`'use client'
|
|
3384
3781
|
|
|
3385
3782
|
import * as React from 'react'
|
|
3386
3783
|
import { cn } from '@/utils/cn'
|
|
@@ -3525,7 +3922,7 @@ export const Slider = React.forwardRef<HTMLInputElement, SliderProps>(({
|
|
|
3525
3922
|
)
|
|
3526
3923
|
|
|
3527
3924
|
Slider.displayName = 'Slider'
|
|
3528
|
-
`;var
|
|
3925
|
+
`;var Se=`'use client'
|
|
3529
3926
|
|
|
3530
3927
|
import * as React from 'react'
|
|
3531
3928
|
import { cn } from '@/utils/cn'
|
|
@@ -3556,6 +3953,7 @@ export function Switch({
|
|
|
3556
3953
|
}: SwitchProps) {
|
|
3557
3954
|
return (
|
|
3558
3955
|
<button
|
|
3956
|
+
type="button"
|
|
3559
3957
|
role="switch"
|
|
3560
3958
|
aria-checked={checked}
|
|
3561
3959
|
onClick={() => onChange?.(!checked)}
|
|
@@ -3680,7 +4078,7 @@ export const Tabs = Object.assign(TabsRoot, {
|
|
|
3680
4078
|
Tab,
|
|
3681
4079
|
Panel
|
|
3682
4080
|
})
|
|
3683
|
-
`;var
|
|
4081
|
+
`;var Te=`import * as React from 'react'
|
|
3684
4082
|
import { cn } from '@/utils/cn'
|
|
3685
4083
|
|
|
3686
4084
|
const styles = {
|
|
@@ -3707,7 +4105,7 @@ export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(({
|
|
|
3707
4105
|
))
|
|
3708
4106
|
|
|
3709
4107
|
Textarea.displayName = 'Textarea'
|
|
3710
|
-
`;var
|
|
4108
|
+
`;var Ie=`'use client'
|
|
3711
4109
|
|
|
3712
4110
|
import * as React from 'react'
|
|
3713
4111
|
import { Toaster as Sonner, toast } from 'sonner'
|
|
@@ -3750,7 +4148,169 @@ function Toaster() {
|
|
|
3750
4148
|
}
|
|
3751
4149
|
|
|
3752
4150
|
export { Toaster, toast }
|
|
3753
|
-
`;var
|
|
4151
|
+
`;var Ee=`'use client'
|
|
4152
|
+
|
|
4153
|
+
import * as React from 'react'
|
|
4154
|
+
import { cn } from '@/utils/cn'
|
|
4155
|
+
|
|
4156
|
+
const styles = {
|
|
4157
|
+
base: cn(
|
|
4158
|
+
'inline-flex items-center justify-center gap-2',
|
|
4159
|
+
'rounded-md text-sm font-medium',
|
|
4160
|
+
'transition-colors cursor-pointer',
|
|
4161
|
+
'focus:outline-none',
|
|
4162
|
+
'disabled:opacity-50 disabled:cursor-default'
|
|
4163
|
+
),
|
|
4164
|
+
variants: {
|
|
4165
|
+
default: cn(
|
|
4166
|
+
'bg-transparent text-muted-foreground',
|
|
4167
|
+
'hover:bg-muted hover:text-foreground',
|
|
4168
|
+
'data-[state=on]:bg-muted',
|
|
4169
|
+
'data-[state=on]:text-foreground'
|
|
4170
|
+
),
|
|
4171
|
+
outline: cn(
|
|
4172
|
+
'border border-border bg-transparent',
|
|
4173
|
+
'text-muted-foreground',
|
|
4174
|
+
'hover:border-foreground/20',
|
|
4175
|
+
'data-[state=on]:bg-muted',
|
|
4176
|
+
'data-[state=on]:text-foreground',
|
|
4177
|
+
'data-[state=on]:border-muted'
|
|
4178
|
+
),
|
|
4179
|
+
},
|
|
4180
|
+
sizes: {
|
|
4181
|
+
sm: 'h-8 px-2.5 text-xs',
|
|
4182
|
+
md: 'h-9 px-3 text-sm',
|
|
4183
|
+
lg: 'h-10 px-4 text-sm',
|
|
4184
|
+
},
|
|
4185
|
+
group: 'inline-flex items-center gap-1',
|
|
4186
|
+
vertical: 'flex-col',
|
|
4187
|
+
}
|
|
4188
|
+
|
|
4189
|
+
interface ToggleGroupCtx {
|
|
4190
|
+
type: 'single' | 'multiple'
|
|
4191
|
+
value: string | string[]
|
|
4192
|
+
onToggle: (v: string) => void
|
|
4193
|
+
disabled?: boolean
|
|
4194
|
+
}
|
|
4195
|
+
|
|
4196
|
+
interface ToggleProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'value' | 'onChange'> {
|
|
4197
|
+
pressed?: boolean
|
|
4198
|
+
defaultPressed?: boolean
|
|
4199
|
+
onChange?: (pressed: boolean) => void
|
|
4200
|
+
value?: string
|
|
4201
|
+
variant?: keyof typeof styles.variants
|
|
4202
|
+
size?: keyof typeof styles.sizes
|
|
4203
|
+
}
|
|
4204
|
+
|
|
4205
|
+
const ToggleButton = React.forwardRef<HTMLButtonElement, ToggleProps>(({
|
|
4206
|
+
pressed,
|
|
4207
|
+
defaultPressed,
|
|
4208
|
+
onChange,
|
|
4209
|
+
value,
|
|
4210
|
+
variant = 'default',
|
|
4211
|
+
size = 'md',
|
|
4212
|
+
disabled,
|
|
4213
|
+
className,
|
|
4214
|
+
children,
|
|
4215
|
+
...props
|
|
4216
|
+
}, ref) => {
|
|
4217
|
+
const ctx = React.useContext(Ctx)
|
|
4218
|
+
const [internal, setInternal] = React.useState(defaultPressed ?? false)
|
|
4219
|
+
const inGroup = ctx !== null && value !== undefined
|
|
4220
|
+
|
|
4221
|
+
const isPressed = inGroup
|
|
4222
|
+
? ctx.type === 'multiple'
|
|
4223
|
+
? (ctx.value as string[]).includes(value)
|
|
4224
|
+
: ctx.value === value
|
|
4225
|
+
: pressed ?? internal
|
|
4226
|
+
|
|
4227
|
+
return (
|
|
4228
|
+
<button
|
|
4229
|
+
ref={ref}
|
|
4230
|
+
type="button"
|
|
4231
|
+
aria-pressed={isPressed}
|
|
4232
|
+
data-state={isPressed ? 'on' : 'off'}
|
|
4233
|
+
disabled={disabled ?? (inGroup ? ctx.disabled : false)}
|
|
4234
|
+
className={cn(styles.base, styles.variants[variant], styles.sizes[size], className)}
|
|
4235
|
+
onClick={() => {
|
|
4236
|
+
if (inGroup) {
|
|
4237
|
+
ctx.onToggle(value)
|
|
4238
|
+
} else {
|
|
4239
|
+
const next = !isPressed
|
|
4240
|
+
if (pressed === undefined) setInternal(next)
|
|
4241
|
+
onChange?.(next)
|
|
4242
|
+
}
|
|
4243
|
+
}}
|
|
4244
|
+
{...props}
|
|
4245
|
+
>
|
|
4246
|
+
{children}
|
|
4247
|
+
</button>
|
|
4248
|
+
)
|
|
4249
|
+
})
|
|
4250
|
+
|
|
4251
|
+
ToggleButton.displayName = 'Toggle'
|
|
4252
|
+
|
|
4253
|
+
function ToggleGroupRoot({
|
|
4254
|
+
children,
|
|
4255
|
+
type,
|
|
4256
|
+
defaultValue,
|
|
4257
|
+
value: controlledValue,
|
|
4258
|
+
onValueChange,
|
|
4259
|
+
orientation = 'horizontal',
|
|
4260
|
+
disabled,
|
|
4261
|
+
className,
|
|
4262
|
+
}: {
|
|
4263
|
+
children: React.ReactNode
|
|
4264
|
+
type: 'single' | 'multiple'
|
|
4265
|
+
defaultValue?: string | string[]
|
|
4266
|
+
value?: string | string[]
|
|
4267
|
+
onValueChange?: (value: string | string[]) => void
|
|
4268
|
+
orientation?: 'vertical' | 'horizontal'
|
|
4269
|
+
disabled?: boolean
|
|
4270
|
+
className?: string
|
|
4271
|
+
}) {
|
|
4272
|
+
const [internal, setInternal] = React.useState<string | string[]>(defaultValue ?? (type === 'multiple' ? [] : ''))
|
|
4273
|
+
const isControlled = controlledValue !== undefined
|
|
4274
|
+
const current = isControlled ? controlledValue : internal
|
|
4275
|
+
|
|
4276
|
+
const onToggle = (itemValue: string) => {
|
|
4277
|
+
let next: string | string[]
|
|
4278
|
+
if (type === 'single') {
|
|
4279
|
+
next = current === itemValue ? '' : itemValue
|
|
4280
|
+
} else {
|
|
4281
|
+
const arr = current as string[]
|
|
4282
|
+
next = arr.includes(itemValue)
|
|
4283
|
+
? arr.filter((v) => v !== itemValue)
|
|
4284
|
+
: [...arr, itemValue]
|
|
4285
|
+
}
|
|
4286
|
+
if (!isControlled) setInternal(next)
|
|
4287
|
+
onValueChange?.(next)
|
|
4288
|
+
}
|
|
4289
|
+
|
|
4290
|
+
return (
|
|
4291
|
+
<Ctx.Provider
|
|
4292
|
+
value={{ type, value: current, onToggle, disabled }}
|
|
4293
|
+
>
|
|
4294
|
+
<div
|
|
4295
|
+
role="group"
|
|
4296
|
+
className={cn(
|
|
4297
|
+
styles.group,
|
|
4298
|
+
orientation === 'vertical' && styles.vertical,
|
|
4299
|
+
className
|
|
4300
|
+
)}
|
|
4301
|
+
>
|
|
4302
|
+
{children}
|
|
4303
|
+
</div>
|
|
4304
|
+
</Ctx.Provider>
|
|
4305
|
+
)
|
|
4306
|
+
}
|
|
4307
|
+
|
|
4308
|
+
const Ctx = React.createContext<ToggleGroupCtx | null>(null)
|
|
4309
|
+
|
|
4310
|
+
export const Toggle = Object.assign(ToggleButton, {
|
|
4311
|
+
Group: ToggleGroupRoot,
|
|
4312
|
+
})
|
|
4313
|
+
`;var Le=`import * as React from 'react'
|
|
3754
4314
|
import { cn } from '@/utils/cn'
|
|
3755
4315
|
|
|
3756
4316
|
const styles = {
|
|
@@ -3924,7 +4484,7 @@ export const Table = Object.assign(TableRoot, {
|
|
|
3924
4484
|
Head,
|
|
3925
4485
|
Cell,
|
|
3926
4486
|
})
|
|
3927
|
-
`;var
|
|
4487
|
+
`;var Oe=`import * as React from 'react'
|
|
3928
4488
|
import { cn } from '@/utils/cn'
|
|
3929
4489
|
|
|
3930
4490
|
const styles = {
|
|
@@ -3969,7 +4529,7 @@ export function Tooltip({
|
|
|
3969
4529
|
</span>
|
|
3970
4530
|
)
|
|
3971
4531
|
}
|
|
3972
|
-
`;var
|
|
4532
|
+
`;var Me=`
|
|
3973
4533
|
/* react-day-picker theme integration */
|
|
3974
4534
|
.rdp-root {
|
|
3975
4535
|
--rdp-accent-color: var(--primary);
|
|
@@ -3980,7 +4540,7 @@ export function Tooltip({
|
|
|
3980
4540
|
--rdp-selected-border: none;
|
|
3981
4541
|
--rdp-day_button-border: none;
|
|
3982
4542
|
}
|
|
3983
|
-
`,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:"collapsible",description:"Toggle content visibility with smooth animation and accessible controls",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:"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:"tooltip",description:"Pure CSS tooltip with 4 position options",dependencies:[],npmDependencies:[]}],
|
|
4543
|
+
`,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:"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:"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,dialog:pe,drawer:ue,dropdown:me,input:fe,kbd:ge,label:he,pagination:be,popover:ve,progress:xe,"radio-group":ye,select:Ne,"scroll-area":Ce,separator:Re,skeleton:we,sidebar:ke,slider:Pe,switch:Se,table:Le,tabs:De,textarea:Te,theme:X,toast:Ie,toggle:Ee,tooltip:Oe};async function Ae(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",h=join(r,t.paths.components);for(let o of p){let s=join(h,`${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\//,"")}`),b(s,i),n.log.success(`${o} \u2192 ${t.paths.components}/${o}.${m}`);}if(l){let o=join(h,`theme-provider.${m}`);if(x(o)){let i=await n.confirm({message:`theme-provider.${m} exists. Overwrite?`,initialValue:false});!n.isCancel(i)&&i?(b(o,R.theme),n.log.success(`theme-provider \u2192 ${t.paths.components}/theme-provider.${m}`)):n.log.warn("Skipped theme-provider");}else b(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"):(b(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"):(b(o,s+Me),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 j=`# Drivn Component Conventions
|
|
3984
4544
|
|
|
3985
4545
|
## Core Philosophy
|
|
3986
4546
|
- **Zero runtime UI deps** \u2014 No Radix, no cva, no external UI primitives. Pure React + Tailwind.
|
|
@@ -4093,13 +4653,13 @@ import { cn } from '@/utils/cn'
|
|
|
4093
4653
|
- Components declare internal deps (other Drivn components)
|
|
4094
4654
|
- Some components need npm packages (react-day-picker, cmdk, embla-carousel-react, sonner)
|
|
4095
4655
|
- The CLI resolves and installs all dependencies automatically
|
|
4096
|
-
`;var L={version:"1.
|
|
4656
|
+
`;var L={version:"1.12.0"};function O(e){return v.find(r=>r.name===e)}function Je(e){let r=new Set,t=a=>{if(r.has(a))return;let l=O(a);l&&(l.dependencies.forEach(d=>t(d)),r.add(a));};return t(e),r.delete(e),[...r]}async function Be(){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=O(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=O(t);if(!a)return {content:[{type:"text",text:`Component "${t}" not found. Use list_components to see available components.`}],isError:true};let l=Je(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=O(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",h=[];return h.push(`# Install components via CLI
|
|
4097
4657
|
${N} drivn@latest add ${[...d].join(" ")}`),p.size&&h.push(`# Install required npm dependencies
|
|
4098
|
-
${
|
|
4658
|
+
${m} ${[...p].join(" ")}`),h.push(`# Components will be installed to your configured components directory
|
|
4099
4659
|
# (default: src/components/ui/)`),{content:[{type:"text",text:JSON.stringify({componentsToInstall:[...d],npmDependencies:[...p],steps:h},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 === */
|
|
4100
4660
|
${C}
|
|
4101
4661
|
|
|
4102
4662
|
/* === Theme Tokens === */
|
|
4103
4663
|
${k}`}]})),e.tool("get_drivn_rules","Get Drivn coding conventions and component patterns",{},async()=>({content:[{type:"text",text:j}]})),e.resource("drivn-rules","drivn://rules",{description:"Drivn coding conventions and component patterns"},async()=>({contents:[{uri:"drivn://rules",mimeType:"text/markdown",text:j}]})),e.resource("drivn-design-tokens","drivn://design-tokens",{description:"Drivn CSS globals and theme tokens"},async()=>({contents:[{uri:"drivn://design-tokens",mimeType:"text/css",text:`${C}
|
|
4104
4664
|
|
|
4105
|
-
${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:
|
|
4665
|
+
${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(Y);I.command("add [components...]").description("Add components to your project").action(Ae);I.command("mcp").description("Start the Drivn MCP server").action(Be);I.parse();
|