drivn 1.9.0 → 1.11.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 +763 -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,515 @@ 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
|
+
|
|
2044
|
+
import * as React from 'react'
|
|
2045
|
+
import { cn } from '@/utils/cn'
|
|
2046
|
+
|
|
2047
|
+
const styles = {
|
|
2048
|
+
panel: 'grid transition-[grid-template-rows] duration-200',
|
|
2049
|
+
content: 'overflow-hidden',
|
|
2050
|
+
}
|
|
2051
|
+
|
|
2052
|
+
interface CollapsibleCtx {
|
|
2053
|
+
open: boolean
|
|
2054
|
+
toggle: () => void
|
|
2055
|
+
triggerId: string
|
|
2056
|
+
contentId: string
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
function CollapsibleRoot({
|
|
2060
|
+
children,
|
|
2061
|
+
className,
|
|
2062
|
+
defaultOpen = false,
|
|
2063
|
+
open: controlledOpen,
|
|
2064
|
+
onOpenChange,
|
|
2065
|
+
}: {
|
|
2066
|
+
children: React.ReactNode
|
|
2067
|
+
className?: string
|
|
2068
|
+
defaultOpen?: boolean
|
|
2069
|
+
open?: boolean
|
|
2070
|
+
onOpenChange?: (open: boolean) => void
|
|
2071
|
+
}) {
|
|
2072
|
+
const [internalOpen, setInternalOpen] = React.useState(defaultOpen)
|
|
2073
|
+
const open = controlledOpen ?? internalOpen
|
|
2074
|
+
const id = React.useId()
|
|
2075
|
+
const triggerId = \`\${id}trigger\`
|
|
2076
|
+
const contentId = \`\${id}content\`
|
|
2077
|
+
|
|
2078
|
+
const toggle = () => {
|
|
2079
|
+
const next = !open
|
|
2080
|
+
if (controlledOpen === undefined) setInternalOpen(next)
|
|
2081
|
+
onOpenChange?.(next)
|
|
2082
|
+
}
|
|
2083
|
+
|
|
2084
|
+
return (
|
|
2085
|
+
<Ctx.Provider value={{ open, toggle, triggerId, contentId }}>
|
|
2086
|
+
<div
|
|
2087
|
+
className={className}
|
|
2088
|
+
data-state={open ? 'open' : 'closed'}
|
|
2089
|
+
>
|
|
2090
|
+
{children}
|
|
2091
|
+
</div>
|
|
2092
|
+
</Ctx.Provider>
|
|
2093
|
+
)
|
|
2094
|
+
}
|
|
2095
|
+
|
|
2096
|
+
function Trigger({
|
|
2097
|
+
children,
|
|
2098
|
+
className,
|
|
2099
|
+
...props
|
|
2100
|
+
}: {
|
|
2101
|
+
children: React.ReactNode
|
|
2102
|
+
className?: string
|
|
2103
|
+
} & React.ButtonHTMLAttributes<HTMLButtonElement>) {
|
|
2104
|
+
const { open, toggle, triggerId, contentId } = useCtx()
|
|
2105
|
+
return (
|
|
2106
|
+
<button
|
|
2107
|
+
id={triggerId}
|
|
2108
|
+
aria-expanded={open}
|
|
2109
|
+
aria-controls={contentId}
|
|
2110
|
+
data-state={open ? 'open' : 'closed'}
|
|
2111
|
+
className={className}
|
|
2112
|
+
onClick={toggle}
|
|
2113
|
+
{...props}
|
|
2114
|
+
>
|
|
2115
|
+
{children}
|
|
2116
|
+
</button>
|
|
2117
|
+
)
|
|
2118
|
+
}
|
|
2119
|
+
|
|
2120
|
+
function Content({
|
|
2121
|
+
children,
|
|
2122
|
+
className,
|
|
2123
|
+
}: {
|
|
2124
|
+
children: React.ReactNode
|
|
2125
|
+
className?: string
|
|
2126
|
+
}) {
|
|
2127
|
+
const { open, triggerId, contentId } = useCtx()
|
|
2128
|
+
return (
|
|
2129
|
+
<div
|
|
2130
|
+
id={contentId}
|
|
2131
|
+
role="region"
|
|
2132
|
+
aria-labelledby={triggerId}
|
|
2133
|
+
data-state={open ? 'open' : 'closed'}
|
|
2134
|
+
className={styles.panel}
|
|
2135
|
+
style={{ gridTemplateRows: open ? '1fr' : '0fr' }}
|
|
2136
|
+
>
|
|
2137
|
+
<div className={cn(styles.content, className)}>
|
|
2138
|
+
{children}
|
|
2139
|
+
</div>
|
|
2140
|
+
</div>
|
|
2141
|
+
)
|
|
2142
|
+
}
|
|
2143
|
+
|
|
2144
|
+
const Ctx = React.createContext<CollapsibleCtx | null>(null)
|
|
2145
|
+
|
|
2146
|
+
function useCtx() {
|
|
2147
|
+
const c = React.useContext(Ctx)
|
|
2148
|
+
if (!c) throw new Error('Collapsible compound used outside <Collapsible>')
|
|
2149
|
+
return c
|
|
2150
|
+
}
|
|
2151
|
+
|
|
2152
|
+
export const Collapsible = Object.assign(CollapsibleRoot, {
|
|
2153
|
+
Trigger,
|
|
2154
|
+
Content,
|
|
2155
|
+
})
|
|
2156
|
+
`;var pe=`'use client'
|
|
2157
|
+
|
|
1649
2158
|
import * as React from 'react'
|
|
1650
2159
|
import { X } from 'lucide-react'
|
|
1651
2160
|
import { cn } from '@/utils/cn'
|
|
@@ -1800,7 +2309,7 @@ export const Dialog = Object.assign(DialogRoot, {
|
|
|
1800
2309
|
Trigger,
|
|
1801
2310
|
Content,
|
|
1802
2311
|
})
|
|
1803
|
-
`;var
|
|
2312
|
+
`;var ue=`'use client'
|
|
1804
2313
|
|
|
1805
2314
|
import * as React from 'react'
|
|
1806
2315
|
import { X } from 'lucide-react'
|
|
@@ -2019,7 +2528,7 @@ export const Drawer = Object.assign(DrawerRoot, {
|
|
|
2019
2528
|
Header,
|
|
2020
2529
|
Footer,
|
|
2021
2530
|
})
|
|
2022
|
-
`;var
|
|
2531
|
+
`;var me=`'use client'
|
|
2023
2532
|
|
|
2024
2533
|
import * as React from 'react'
|
|
2025
2534
|
import { cn } from '@/utils/cn'
|
|
@@ -2217,7 +2726,7 @@ export const Dropdown = Object.assign(DropdownRoot, {
|
|
|
2217
2726
|
Label,
|
|
2218
2727
|
Separator: DropdownSeparator
|
|
2219
2728
|
})
|
|
2220
|
-
`;var
|
|
2729
|
+
`;var fe=`import * as React from 'react'
|
|
2221
2730
|
import { cn } from '@/utils/cn'
|
|
2222
2731
|
|
|
2223
2732
|
const styles = {
|
|
@@ -2240,7 +2749,7 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(({
|
|
|
2240
2749
|
)
|
|
2241
2750
|
|
|
2242
2751
|
Input.displayName = 'Input'
|
|
2243
|
-
`;var
|
|
2752
|
+
`;var ge=`import * as React from 'react'
|
|
2244
2753
|
import { cn } from '@/utils/cn'
|
|
2245
2754
|
|
|
2246
2755
|
const styles = {
|
|
@@ -2297,7 +2806,7 @@ function Group({
|
|
|
2297
2806
|
}
|
|
2298
2807
|
|
|
2299
2808
|
export const Kbd = Object.assign(KbdRoot, { Group })
|
|
2300
|
-
`;var
|
|
2809
|
+
`;var he=`import * as React from 'react'
|
|
2301
2810
|
import { cn } from '@/utils/cn'
|
|
2302
2811
|
|
|
2303
2812
|
export function Label({
|
|
@@ -2314,7 +2823,7 @@ export function Label({
|
|
|
2314
2823
|
/>
|
|
2315
2824
|
)
|
|
2316
2825
|
}
|
|
2317
|
-
`;var
|
|
2826
|
+
`;var be=`import * as React from 'react'
|
|
2318
2827
|
import { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react'
|
|
2319
2828
|
import { cn } from '@/utils/cn'
|
|
2320
2829
|
|
|
@@ -2447,7 +2956,7 @@ export const Pagination = Object.assign(PaginationRoot, {
|
|
|
2447
2956
|
Next,
|
|
2448
2957
|
Ellipsis: PaginationEllipsis,
|
|
2449
2958
|
})
|
|
2450
|
-
`;var
|
|
2959
|
+
`;var ve=`'use client'
|
|
2451
2960
|
|
|
2452
2961
|
import * as React from 'react'
|
|
2453
2962
|
import { cn } from '@/utils/cn'
|
|
@@ -2552,7 +3061,7 @@ export const Popover = Object.assign(PopoverRoot, {
|
|
|
2552
3061
|
Trigger,
|
|
2553
3062
|
Content
|
|
2554
3063
|
})
|
|
2555
|
-
`;var
|
|
3064
|
+
`;var xe=`import * as React from 'react'
|
|
2556
3065
|
import { cn } from '@/utils/cn'
|
|
2557
3066
|
|
|
2558
3067
|
const styles = {
|
|
@@ -2590,7 +3099,7 @@ export function Progress({
|
|
|
2590
3099
|
</div>
|
|
2591
3100
|
)
|
|
2592
3101
|
}
|
|
2593
|
-
`;var
|
|
3102
|
+
`;var ye=`'use client'
|
|
2594
3103
|
|
|
2595
3104
|
import * as React from 'react'
|
|
2596
3105
|
import { cn } from '@/utils/cn'
|
|
@@ -2739,7 +3248,7 @@ function useRadioGroup() {
|
|
|
2739
3248
|
}
|
|
2740
3249
|
|
|
2741
3250
|
export const RadioGroup = Object.assign(RadioGroupRoot, { Item })
|
|
2742
|
-
`;var
|
|
3251
|
+
`;var Ne=`'use client'
|
|
2743
3252
|
|
|
2744
3253
|
import * as React from 'react'
|
|
2745
3254
|
import { ChevronDown } from 'lucide-react'
|
|
@@ -2893,7 +3402,53 @@ export const Select = Object.assign(SelectRoot, {
|
|
|
2893
3402
|
Menu,
|
|
2894
3403
|
Option
|
|
2895
3404
|
})
|
|
2896
|
-
`;var
|
|
3405
|
+
`;var Ce=`import * as React from 'react'
|
|
3406
|
+
import { cn } from '@/utils/cn'
|
|
3407
|
+
|
|
3408
|
+
const styles = {
|
|
3409
|
+
base: cn(
|
|
3410
|
+
'relative [scrollbar-width:thin]',
|
|
3411
|
+
'[scrollbar-color:var(--border)_transparent]',
|
|
3412
|
+
'[&::-webkit-scrollbar]:w-1.5',
|
|
3413
|
+
'[&::-webkit-scrollbar]:h-1.5',
|
|
3414
|
+
'[&::-webkit-scrollbar-track]:bg-transparent',
|
|
3415
|
+
'[&::-webkit-scrollbar-track]:rounded-full',
|
|
3416
|
+
'[&::-webkit-scrollbar-thumb]:rounded-full',
|
|
3417
|
+
'[&::-webkit-scrollbar-thumb]:bg-border',
|
|
3418
|
+
'[&:hover::-webkit-scrollbar-thumb]:bg-muted-foreground/30',
|
|
3419
|
+
'[&::-webkit-scrollbar-corner]:bg-transparent'
|
|
3420
|
+
),
|
|
3421
|
+
orientations: {
|
|
3422
|
+
vertical: 'overflow-y-auto overflow-x-hidden',
|
|
3423
|
+
horizontal: 'overflow-x-auto overflow-y-hidden',
|
|
3424
|
+
},
|
|
3425
|
+
}
|
|
3426
|
+
|
|
3427
|
+
interface ScrollAreaProps
|
|
3428
|
+
extends React.HTMLAttributes<HTMLDivElement> {
|
|
3429
|
+
orientation?: 'vertical' | 'horizontal'
|
|
3430
|
+
}
|
|
3431
|
+
|
|
3432
|
+
export function ScrollArea({
|
|
3433
|
+
orientation = 'vertical',
|
|
3434
|
+
className,
|
|
3435
|
+
children,
|
|
3436
|
+
...props
|
|
3437
|
+
}: ScrollAreaProps) {
|
|
3438
|
+
return (
|
|
3439
|
+
<div
|
|
3440
|
+
className={cn(
|
|
3441
|
+
styles.base,
|
|
3442
|
+
styles.orientations[orientation],
|
|
3443
|
+
className
|
|
3444
|
+
)}
|
|
3445
|
+
{...props}
|
|
3446
|
+
>
|
|
3447
|
+
{children}
|
|
3448
|
+
</div>
|
|
3449
|
+
)
|
|
3450
|
+
}
|
|
3451
|
+
`;var Re=`import * as React from 'react'
|
|
2897
3452
|
import { cn } from '@/utils/cn'
|
|
2898
3453
|
|
|
2899
3454
|
const styles = {
|
|
@@ -2917,7 +3472,24 @@ export function Separator({
|
|
|
2917
3472
|
/>
|
|
2918
3473
|
)
|
|
2919
3474
|
}
|
|
2920
|
-
`;var
|
|
3475
|
+
`;var we=`import * as React from 'react'
|
|
3476
|
+
import { cn } from '@/utils/cn'
|
|
3477
|
+
|
|
3478
|
+
export function Skeleton({
|
|
3479
|
+
className,
|
|
3480
|
+
...props
|
|
3481
|
+
}: React.HTMLAttributes<HTMLDivElement>) {
|
|
3482
|
+
return (
|
|
3483
|
+
<div
|
|
3484
|
+
className={cn(
|
|
3485
|
+
'bg-muted/80 rounded-md animate-skeleton',
|
|
3486
|
+
className
|
|
3487
|
+
)}
|
|
3488
|
+
{...props}
|
|
3489
|
+
/>
|
|
3490
|
+
)
|
|
3491
|
+
}
|
|
3492
|
+
`;var ke=`'use client'
|
|
2921
3493
|
|
|
2922
3494
|
import * as React from 'react'
|
|
2923
3495
|
import { ChevronDown, PanelLeft } from 'lucide-react'
|
|
@@ -3203,7 +3775,7 @@ export const Sidebar = Object.assign(SidebarRoot, {
|
|
|
3203
3775
|
Separator: SidebarSeparator,
|
|
3204
3776
|
CollapseButton,
|
|
3205
3777
|
})
|
|
3206
|
-
`;var
|
|
3778
|
+
`;var Pe=`'use client'
|
|
3207
3779
|
|
|
3208
3780
|
import * as React from 'react'
|
|
3209
3781
|
import { cn } from '@/utils/cn'
|
|
@@ -3348,7 +3920,7 @@ export const Slider = React.forwardRef<HTMLInputElement, SliderProps>(({
|
|
|
3348
3920
|
)
|
|
3349
3921
|
|
|
3350
3922
|
Slider.displayName = 'Slider'
|
|
3351
|
-
`;var
|
|
3923
|
+
`;var Se=`'use client'
|
|
3352
3924
|
|
|
3353
3925
|
import * as React from 'react'
|
|
3354
3926
|
import { cn } from '@/utils/cn'
|
|
@@ -3389,7 +3961,7 @@ export function Switch({
|
|
|
3389
3961
|
</button>
|
|
3390
3962
|
)
|
|
3391
3963
|
}
|
|
3392
|
-
`;var
|
|
3964
|
+
`;var De=`'use client'
|
|
3393
3965
|
|
|
3394
3966
|
import * as React from 'react'
|
|
3395
3967
|
import { cn } from '@/utils/cn'
|
|
@@ -3503,7 +4075,7 @@ export const Tabs = Object.assign(TabsRoot, {
|
|
|
3503
4075
|
Tab,
|
|
3504
4076
|
Panel
|
|
3505
4077
|
})
|
|
3506
|
-
`;var
|
|
4078
|
+
`;var Te=`import * as React from 'react'
|
|
3507
4079
|
import { cn } from '@/utils/cn'
|
|
3508
4080
|
|
|
3509
4081
|
const styles = {
|
|
@@ -3530,7 +4102,7 @@ export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(({
|
|
|
3530
4102
|
))
|
|
3531
4103
|
|
|
3532
4104
|
Textarea.displayName = 'Textarea'
|
|
3533
|
-
`;var
|
|
4105
|
+
`;var Ie=`'use client'
|
|
3534
4106
|
|
|
3535
4107
|
import * as React from 'react'
|
|
3536
4108
|
import { Toaster as Sonner, toast } from 'sonner'
|
|
@@ -3573,7 +4145,169 @@ function Toaster() {
|
|
|
3573
4145
|
}
|
|
3574
4146
|
|
|
3575
4147
|
export { Toaster, toast }
|
|
3576
|
-
`;var
|
|
4148
|
+
`;var Ee=`'use client'
|
|
4149
|
+
|
|
4150
|
+
import * as React from 'react'
|
|
4151
|
+
import { cn } from '@/utils/cn'
|
|
4152
|
+
|
|
4153
|
+
const styles = {
|
|
4154
|
+
base: cn(
|
|
4155
|
+
'inline-flex items-center justify-center gap-2',
|
|
4156
|
+
'rounded-md text-sm font-medium',
|
|
4157
|
+
'transition-colors cursor-pointer',
|
|
4158
|
+
'focus:outline-none',
|
|
4159
|
+
'disabled:opacity-50 disabled:cursor-default'
|
|
4160
|
+
),
|
|
4161
|
+
variants: {
|
|
4162
|
+
default: cn(
|
|
4163
|
+
'bg-transparent text-muted-foreground',
|
|
4164
|
+
'hover:bg-muted hover:text-foreground',
|
|
4165
|
+
'data-[state=on]:bg-muted',
|
|
4166
|
+
'data-[state=on]:text-foreground'
|
|
4167
|
+
),
|
|
4168
|
+
outline: cn(
|
|
4169
|
+
'border border-border bg-transparent',
|
|
4170
|
+
'text-muted-foreground',
|
|
4171
|
+
'hover:border-foreground/20',
|
|
4172
|
+
'data-[state=on]:bg-muted',
|
|
4173
|
+
'data-[state=on]:text-foreground',
|
|
4174
|
+
'data-[state=on]:border-muted'
|
|
4175
|
+
),
|
|
4176
|
+
},
|
|
4177
|
+
sizes: {
|
|
4178
|
+
sm: 'h-8 px-2.5 text-xs',
|
|
4179
|
+
md: 'h-9 px-3 text-sm',
|
|
4180
|
+
lg: 'h-10 px-4 text-sm',
|
|
4181
|
+
},
|
|
4182
|
+
group: 'inline-flex items-center gap-1',
|
|
4183
|
+
vertical: 'flex-col',
|
|
4184
|
+
}
|
|
4185
|
+
|
|
4186
|
+
interface ToggleGroupCtx {
|
|
4187
|
+
type: 'single' | 'multiple'
|
|
4188
|
+
value: string | string[]
|
|
4189
|
+
onToggle: (v: string) => void
|
|
4190
|
+
disabled?: boolean
|
|
4191
|
+
}
|
|
4192
|
+
|
|
4193
|
+
interface ToggleProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'value' | 'onChange'> {
|
|
4194
|
+
pressed?: boolean
|
|
4195
|
+
defaultPressed?: boolean
|
|
4196
|
+
onChange?: (pressed: boolean) => void
|
|
4197
|
+
value?: string
|
|
4198
|
+
variant?: keyof typeof styles.variants
|
|
4199
|
+
size?: keyof typeof styles.sizes
|
|
4200
|
+
}
|
|
4201
|
+
|
|
4202
|
+
const ToggleButton = React.forwardRef<HTMLButtonElement, ToggleProps>(({
|
|
4203
|
+
pressed,
|
|
4204
|
+
defaultPressed,
|
|
4205
|
+
onChange,
|
|
4206
|
+
value,
|
|
4207
|
+
variant = 'default',
|
|
4208
|
+
size = 'md',
|
|
4209
|
+
disabled,
|
|
4210
|
+
className,
|
|
4211
|
+
children,
|
|
4212
|
+
...props
|
|
4213
|
+
}, ref) => {
|
|
4214
|
+
const ctx = React.useContext(Ctx)
|
|
4215
|
+
const [internal, setInternal] = React.useState(defaultPressed ?? false)
|
|
4216
|
+
const inGroup = ctx !== null && value !== undefined
|
|
4217
|
+
|
|
4218
|
+
const isPressed = inGroup
|
|
4219
|
+
? ctx.type === 'multiple'
|
|
4220
|
+
? (ctx.value as string[]).includes(value)
|
|
4221
|
+
: ctx.value === value
|
|
4222
|
+
: pressed ?? internal
|
|
4223
|
+
|
|
4224
|
+
return (
|
|
4225
|
+
<button
|
|
4226
|
+
ref={ref}
|
|
4227
|
+
type="button"
|
|
4228
|
+
aria-pressed={isPressed}
|
|
4229
|
+
data-state={isPressed ? 'on' : 'off'}
|
|
4230
|
+
disabled={disabled ?? (inGroup ? ctx.disabled : false)}
|
|
4231
|
+
className={cn(styles.base, styles.variants[variant], styles.sizes[size], className)}
|
|
4232
|
+
onClick={() => {
|
|
4233
|
+
if (inGroup) {
|
|
4234
|
+
ctx.onToggle(value)
|
|
4235
|
+
} else {
|
|
4236
|
+
const next = !isPressed
|
|
4237
|
+
if (pressed === undefined) setInternal(next)
|
|
4238
|
+
onChange?.(next)
|
|
4239
|
+
}
|
|
4240
|
+
}}
|
|
4241
|
+
{...props}
|
|
4242
|
+
>
|
|
4243
|
+
{children}
|
|
4244
|
+
</button>
|
|
4245
|
+
)
|
|
4246
|
+
})
|
|
4247
|
+
|
|
4248
|
+
ToggleButton.displayName = 'Toggle'
|
|
4249
|
+
|
|
4250
|
+
function ToggleGroupRoot({
|
|
4251
|
+
children,
|
|
4252
|
+
type,
|
|
4253
|
+
defaultValue,
|
|
4254
|
+
value: controlledValue,
|
|
4255
|
+
onValueChange,
|
|
4256
|
+
orientation = 'horizontal',
|
|
4257
|
+
disabled,
|
|
4258
|
+
className,
|
|
4259
|
+
}: {
|
|
4260
|
+
children: React.ReactNode
|
|
4261
|
+
type: 'single' | 'multiple'
|
|
4262
|
+
defaultValue?: string | string[]
|
|
4263
|
+
value?: string | string[]
|
|
4264
|
+
onValueChange?: (value: string | string[]) => void
|
|
4265
|
+
orientation?: 'vertical' | 'horizontal'
|
|
4266
|
+
disabled?: boolean
|
|
4267
|
+
className?: string
|
|
4268
|
+
}) {
|
|
4269
|
+
const [internal, setInternal] = React.useState<string | string[]>(defaultValue ?? (type === 'multiple' ? [] : ''))
|
|
4270
|
+
const isControlled = controlledValue !== undefined
|
|
4271
|
+
const current = isControlled ? controlledValue : internal
|
|
4272
|
+
|
|
4273
|
+
const onToggle = (itemValue: string) => {
|
|
4274
|
+
let next: string | string[]
|
|
4275
|
+
if (type === 'single') {
|
|
4276
|
+
next = current === itemValue ? '' : itemValue
|
|
4277
|
+
} else {
|
|
4278
|
+
const arr = current as string[]
|
|
4279
|
+
next = arr.includes(itemValue)
|
|
4280
|
+
? arr.filter((v) => v !== itemValue)
|
|
4281
|
+
: [...arr, itemValue]
|
|
4282
|
+
}
|
|
4283
|
+
if (!isControlled) setInternal(next)
|
|
4284
|
+
onValueChange?.(next)
|
|
4285
|
+
}
|
|
4286
|
+
|
|
4287
|
+
return (
|
|
4288
|
+
<Ctx.Provider
|
|
4289
|
+
value={{ type, value: current, onToggle, disabled }}
|
|
4290
|
+
>
|
|
4291
|
+
<div
|
|
4292
|
+
role="group"
|
|
4293
|
+
className={cn(
|
|
4294
|
+
styles.group,
|
|
4295
|
+
orientation === 'vertical' && styles.vertical,
|
|
4296
|
+
className
|
|
4297
|
+
)}
|
|
4298
|
+
>
|
|
4299
|
+
{children}
|
|
4300
|
+
</div>
|
|
4301
|
+
</Ctx.Provider>
|
|
4302
|
+
)
|
|
4303
|
+
}
|
|
4304
|
+
|
|
4305
|
+
const Ctx = React.createContext<ToggleGroupCtx | null>(null)
|
|
4306
|
+
|
|
4307
|
+
export const Toggle = Object.assign(ToggleButton, {
|
|
4308
|
+
Group: ToggleGroupRoot,
|
|
4309
|
+
})
|
|
4310
|
+
`;var Le=`import * as React from 'react'
|
|
3577
4311
|
import { cn } from '@/utils/cn'
|
|
3578
4312
|
|
|
3579
4313
|
const styles = {
|
|
@@ -3747,7 +4481,7 @@ export const Table = Object.assign(TableRoot, {
|
|
|
3747
4481
|
Head,
|
|
3748
4482
|
Cell,
|
|
3749
4483
|
})
|
|
3750
|
-
`;var
|
|
4484
|
+
`;var Oe=`import * as React from 'react'
|
|
3751
4485
|
import { cn } from '@/utils/cn'
|
|
3752
4486
|
|
|
3753
4487
|
const styles = {
|
|
@@ -3792,7 +4526,7 @@ export function Tooltip({
|
|
|
3792
4526
|
</span>
|
|
3793
4527
|
)
|
|
3794
4528
|
}
|
|
3795
|
-
`;var
|
|
4529
|
+
`;var Me=`
|
|
3796
4530
|
/* react-day-picker theme integration */
|
|
3797
4531
|
.rdp-root {
|
|
3798
4532
|
--rdp-accent-color: var(--primary);
|
|
@@ -3803,7 +4537,7 @@ export function Tooltip({
|
|
|
3803
4537
|
--rdp-selected-border: none;
|
|
3804
4538
|
--rdp-day_button-border: none;
|
|
3805
4539
|
}
|
|
3806
|
-
`,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:"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:"separator",description:"Visual divider with horizontal and vertical orientation",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:[]}],
|
|
4540
|
+
`,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
|
|
3807
4541
|
|
|
3808
4542
|
## Core Philosophy
|
|
3809
4543
|
- **Zero runtime UI deps** \u2014 No Radix, no cva, no external UI primitives. Pure React + Tailwind.
|
|
@@ -3916,13 +4650,13 @@ import { cn } from '@/utils/cn'
|
|
|
3916
4650
|
- Components declare internal deps (other Drivn components)
|
|
3917
4651
|
- Some components need npm packages (react-day-picker, cmdk, embla-carousel-react, sonner)
|
|
3918
4652
|
- The CLI resolves and installs all dependencies automatically
|
|
3919
|
-
`;var L={version:"1.
|
|
4653
|
+
`;var L={version:"1.11.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
|
|
3920
4654
|
${N} drivn@latest add ${[...d].join(" ")}`),p.size&&h.push(`# Install required npm dependencies
|
|
3921
|
-
${
|
|
4655
|
+
${m} ${[...p].join(" ")}`),h.push(`# Components will be installed to your configured components directory
|
|
3922
4656
|
# (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 === */
|
|
3923
4657
|
${C}
|
|
3924
4658
|
|
|
3925
4659
|
/* === Theme Tokens === */
|
|
3926
4660
|
${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}
|
|
3927
4661
|
|
|
3928
|
-
${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:
|
|
4662
|
+
${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();
|