@rlx-ui/mcp 0.0.3 → 0.0.4
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/cli.js +300 -320
- package/dist/data/registry.json +166 -76
- package/package.json +1 -1
package/dist/data/registry.json
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
"widgets": [
|
|
3
3
|
{
|
|
4
4
|
"name": "Accordion",
|
|
5
|
+
"exportName": "Accordion",
|
|
6
|
+
"packageName": "@rlx-widgets/accordion",
|
|
5
7
|
"slug": "accordion",
|
|
6
8
|
"category": "widget",
|
|
7
9
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as AccordionPrimitive from \"@radix-ui/react-accordion\";\nimport { ChevronDownIcon } from \"lucide-react\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction Accordion({\n ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Root>) {\n return <AccordionPrimitive.Root data-slot=\"accordion\" {...props} />;\n}\n\nfunction AccordionItem({\n className,\n ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Item>) {\n return (\n <AccordionPrimitive.Item\n data-slot=\"accordion-item\"\n className={cn(\"border-b last:border-b-0\", className)}\n {...props}\n />\n );\n}\n\nfunction AccordionTrigger({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {\n return (\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger\n data-slot=\"accordion-trigger\"\n className={cn(\n \"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronDownIcon className=\"text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200\" />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n );\n}\n\nfunction AccordionContent({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Content>) {\n return (\n <AccordionPrimitive.Content\n data-slot=\"accordion-content\"\n className=\"data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm\"\n {...props}\n >\n <div className={cn(\"pt-0 pb-4\", className)}>{children}</div>\n </AccordionPrimitive.Content>\n );\n}\n\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent };\n",
|
|
@@ -26,6 +28,8 @@
|
|
|
26
28
|
},
|
|
27
29
|
{
|
|
28
30
|
"name": "Alert",
|
|
31
|
+
"exportName": "Alert",
|
|
32
|
+
"packageName": "@rlx-widgets/alert",
|
|
29
33
|
"slug": "alert",
|
|
30
34
|
"category": "widget",
|
|
31
35
|
"sourceCode": "import * as React from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@rlx-widgets/base\";\n\nconst alertVariants = cva(\n \"relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current\",\n {\n variants: {\n variant: {\n default: \"bg-card text-card-foreground\",\n destructive:\n \"text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n);\n\nfunction Alert({\n className,\n variant,\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof alertVariants>) {\n return (\n <div\n data-slot=\"alert\"\n role=\"alert\"\n className={cn(alertVariants({ variant }), className)}\n {...props}\n />\n );\n}\n\nfunction AlertTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-title\"\n className={cn(\n \"col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDescription({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-description\"\n className={cn(\n \"text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Alert, AlertTitle, AlertDescription };\n",
|
|
@@ -46,6 +50,8 @@
|
|
|
46
50
|
},
|
|
47
51
|
{
|
|
48
52
|
"name": "Alert Dialog",
|
|
53
|
+
"exportName": "AlertDialog",
|
|
54
|
+
"packageName": "@rlx-widgets/alert-dialog",
|
|
49
55
|
"slug": "alert-dialog",
|
|
50
56
|
"category": "widget",
|
|
51
57
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as AlertDialogPrimitive from \"@radix-ui/react-alert-dialog\";\nimport { cn } from \"@rlx-widgets/base\";\nimport { buttonVariants } from \"@rlx-widgets/button\";\n\nfunction AlertDialog({\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {\n return <AlertDialogPrimitive.Root data-slot=\"alert-dialog\" {...props} />;\n}\n\nfunction AlertDialogTrigger({\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {\n return (\n <AlertDialogPrimitive.Trigger data-slot=\"alert-dialog-trigger\" {...props} />\n );\n}\n\nfunction AlertDialogPortal({\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) {\n return (\n <AlertDialogPrimitive.Portal data-slot=\"alert-dialog-portal\" {...props} />\n );\n}\n\nfunction AlertDialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) {\n return (\n <AlertDialogPrimitive.Overlay\n data-slot=\"alert-dialog-overlay\"\n className={cn(\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDialogContent({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Content>) {\n return (\n <AlertDialogPortal>\n <AlertDialogOverlay />\n <AlertDialogPrimitive.Content\n data-slot=\"alert-dialog-content\"\n className={cn(\n \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg\",\n className\n )}\n {...props}\n />\n </AlertDialogPortal>\n );\n}\n\nfunction AlertDialogHeader({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-dialog-header\"\n className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n {...props}\n />\n );\n}\n\nfunction AlertDialogFooter({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {\n return (\n <AlertDialogPrimitive.Title\n data-slot=\"alert-dialog-title\"\n className={cn(\"text-lg font-semibold\", className)}\n {...props}\n />\n );\n}\n\nfunction AlertDialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {\n return (\n <AlertDialogPrimitive.Description\n data-slot=\"alert-dialog-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n );\n}\n\nfunction AlertDialogAction({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Action>) {\n return (\n <AlertDialogPrimitive.Action\n className={cn(buttonVariants(), className)}\n {...props}\n />\n );\n}\n\nfunction AlertDialogCancel({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Cancel>) {\n return (\n <AlertDialogPrimitive.Cancel\n className={cn(buttonVariants({ variant: \"outline\" }), className)}\n {...props}\n />\n );\n}\n\nexport {\n AlertDialog,\n AlertDialogPortal,\n AlertDialogOverlay,\n AlertDialogTrigger,\n AlertDialogContent,\n AlertDialogHeader,\n AlertDialogFooter,\n AlertDialogTitle,\n AlertDialogDescription,\n AlertDialogAction,\n AlertDialogCancel,\n};\n",
|
|
@@ -58,6 +64,8 @@
|
|
|
58
64
|
},
|
|
59
65
|
{
|
|
60
66
|
"name": "Aspect Ratio",
|
|
67
|
+
"exportName": "AspectRatio",
|
|
68
|
+
"packageName": "@rlx-widgets/aspect-ratio",
|
|
61
69
|
"slug": "aspect-ratio",
|
|
62
70
|
"category": "widget",
|
|
63
71
|
"sourceCode": "\"use client\";\n\nimport * as AspectRatioPrimitive from \"@radix-ui/react-aspect-ratio\";\n\nfunction AspectRatio({\n ...props\n}: React.ComponentProps<typeof AspectRatioPrimitive.Root>) {\n return <AspectRatioPrimitive.Root data-slot=\"aspect-ratio\" {...props} />;\n}\n\nexport { AspectRatio };\n",
|
|
@@ -70,6 +78,8 @@
|
|
|
70
78
|
},
|
|
71
79
|
{
|
|
72
80
|
"name": "Avatar",
|
|
81
|
+
"exportName": "Avatar",
|
|
82
|
+
"packageName": "@rlx-widgets/avatar",
|
|
73
83
|
"slug": "avatar",
|
|
74
84
|
"category": "widget",
|
|
75
85
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction Avatar({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Root>) {\n return (\n <AvatarPrimitive.Root\n data-slot=\"avatar\"\n className={cn(\n \"relative flex size-8 shrink-0 overflow-hidden rounded-full\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction AvatarImage({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Image>) {\n return (\n <AvatarPrimitive.Image\n data-slot=\"avatar-image\"\n className={cn(\"aspect-square size-full\", className)}\n {...props}\n />\n );\n}\n\nfunction AvatarFallback({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {\n return (\n <AvatarPrimitive.Fallback\n data-slot=\"avatar-fallback\"\n className={cn(\n \"bg-muted flex size-full items-center justify-center rounded-full\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Avatar, AvatarImage, AvatarFallback };\n",
|
|
@@ -90,6 +100,8 @@
|
|
|
90
100
|
},
|
|
91
101
|
{
|
|
92
102
|
"name": "Badge",
|
|
103
|
+
"exportName": "Badge",
|
|
104
|
+
"packageName": "@rlx-widgets/badge",
|
|
93
105
|
"slug": "badge",
|
|
94
106
|
"category": "widget",
|
|
95
107
|
"sourceCode": "import * as React from \"react\";\nimport { cn } from \"@rlx-widgets/base\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nconst badgeVariants = cva(\n \"inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden\",\n {\n variants: {\n variant: {\n default:\n \"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90\",\n secondary:\n \"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90\",\n destructive:\n \"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n outline:\n \"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n);\n\nfunction Badge({\n className,\n variant,\n asChild = false,\n ...props\n}: React.ComponentProps<\"span\"> &\n VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : \"span\";\n\n return (\n <Comp\n data-slot=\"badge\"\n className={cn(badgeVariants({ variant }), className)}\n {...props}\n />\n );\n}\n\nexport { Badge, badgeVariants };\n",
|
|
@@ -128,8 +140,25 @@
|
|
|
128
140
|
}
|
|
129
141
|
]
|
|
130
142
|
},
|
|
143
|
+
{
|
|
144
|
+
"name": "Base",
|
|
145
|
+
"packageName": "@rlx-widgets/base",
|
|
146
|
+
"slug": "base",
|
|
147
|
+
"category": "widget",
|
|
148
|
+
"sourceFiles": {
|
|
149
|
+
"providers/ThemeProvider/ThemeProvider.tsx": "\"use client\";\n\nimport { createContext, useContext, useEffect, useState } from \"react\";\nimport { getSystemTheme } from \"../../utils\";\nimport { Theme, ThemeProviderProps, ThemeProviderState } from \"./types\";\nimport { isDarkMode } from \"./utils\";\n\nconst initialState: ThemeProviderState = {\n theme: \"system\",\n setTheme: () => null,\n};\n\nconst ThemeProviderContext = createContext<ThemeProviderState>(initialState);\n\nexport function ThemeProvider({\n children,\n defaultTheme = \"system\",\n storageKey = \"theme\",\n ...props\n}: ThemeProviderProps) {\n const [theme, setTheme] = useState<Theme>(\n typeof window === \"undefined\"\n ? defaultTheme\n : (window.localStorage.getItem(storageKey) as Theme)\n );\n\n useEffect(() => {\n setTheme((localStorage?.getItem(storageKey) as Theme) || defaultTheme);\n }, [defaultTheme, storageKey]);\n\n useEffect(() => {\n const root = window.document.documentElement;\n\n root.classList.remove(\"light\", \"dark\");\n\n if (theme === \"system\") {\n const systemTheme = getSystemTheme();\n\n root.classList.add(systemTheme);\n return;\n }\n\n root.classList.add(theme);\n }, [theme]);\n\n const value = {\n theme,\n setTheme: (theme: Theme) => {\n localStorage.setItem(storageKey, theme);\n setTheme(theme);\n },\n };\n\n return (\n <ThemeProviderContext.Provider {...props} value={value}>\n {children}\n </ThemeProviderContext.Provider>\n );\n}\n\nexport const useTheme = () => {\n const context = useContext(ThemeProviderContext);\n\n if (context === undefined)\n throw new Error(\"useTheme must be used within a ThemeProvider\");\n\n return context;\n};\n\nexport const useIsDarkMode = () => {\n const { theme } = useTheme();\n const [isDark, setIsDark] = useState(isDarkMode(theme));\n\n useEffect(() => {\n setIsDark(isDarkMode(theme));\n }, [theme]);\n\n return isDark;\n};\n\nexport default ThemeProvider;\n",
|
|
150
|
+
"providers/ThemeProvider/types/Theme.t.ts": "export type Theme = \"dark\" | \"light\" | \"system\";\n",
|
|
151
|
+
"providers/ThemeProvider/types/ThemeProviderProps.t.ts": "import { ReactNode } from \"react\";\nimport { Theme } from \"./Theme.t\";\n\nexport type ThemeProviderProps = {\n children: ReactNode;\n defaultTheme?: Theme;\n storageKey?: string;\n};\n",
|
|
152
|
+
"providers/ThemeProvider/types/ThemeProviderState.t.ts": "import { Theme } from \"./Theme.t\";\n\nexport type ThemeProviderState = {\n theme: Theme;\n setTheme: (theme: Theme) => void;\n};\n",
|
|
153
|
+
"providers/ThemeProvider/utils/isDarkMode.ts": "import { getSystemTheme } from \"../../../utils\";\nimport { Theme } from \"../types\";\n\nexport const isDarkMode = (theme: Theme) => {\n if (theme === \"system\") {\n return getSystemTheme() === \"dark\";\n }\n return theme === \"dark\";\n};\n",
|
|
154
|
+
"utils/cn/cn.ts": "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport const cn = (...inputs: Array<ClassValue>) => {\n return twMerge(clsx(inputs));\n};\n\nexport default cn;",
|
|
155
|
+
"utils/getSystemTheme/getSystemTheme.ts": "export const getSystemTheme = () => {\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches\n ? \"dark\"\n : \"light\";\n};\n\nexport default getSystemTheme;"
|
|
156
|
+
}
|
|
157
|
+
},
|
|
131
158
|
{
|
|
132
159
|
"name": "Breadcrumb",
|
|
160
|
+
"exportName": "Breadcrumb",
|
|
161
|
+
"packageName": "@rlx-widgets/breadcrumb",
|
|
133
162
|
"slug": "breadcrumb",
|
|
134
163
|
"category": "widget",
|
|
135
164
|
"sourceCode": "import * as React from \"react\";\nimport { ChevronRight, MoreHorizontal } from \"lucide-react\";\nimport { cn } from \"@rlx-widgets/base\";\nimport { Slot } from \"@radix-ui/react-slot\";\n\nfunction Breadcrumb({ ...props }: React.ComponentProps<\"nav\">) {\n return <nav aria-label=\"breadcrumb\" data-slot=\"breadcrumb\" {...props} />;\n}\n\nfunction BreadcrumbList({ className, ...props }: React.ComponentProps<\"ol\">) {\n return (\n <ol\n data-slot=\"breadcrumb-list\"\n className={cn(\n \"text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbItem({ className, ...props }: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"breadcrumb-item\"\n className={cn(\"inline-flex items-center gap-1.5\", className)}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbLink({\n asChild,\n className,\n ...props\n}: React.ComponentProps<\"a\"> & {\n asChild?: boolean;\n}) {\n const Comp = asChild ? Slot : \"a\";\n\n return (\n <Comp\n data-slot=\"breadcrumb-link\"\n className={cn(\"hover:text-foreground transition-colors\", className)}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbPage({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"breadcrumb-page\"\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn(\"text-foreground font-normal\", className)}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbSeparator({\n children,\n className,\n ...props\n}: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"breadcrumb-separator\"\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\"[&>svg]:size-3.5\", className)}\n {...props}\n >\n {children ?? <ChevronRight />}\n </li>\n );\n}\n\nfunction BreadcrumbEllipsis({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"breadcrumb-ellipsis\"\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\"flex size-9 items-center justify-center\", className)}\n {...props}\n >\n <MoreHorizontal className=\"size-4\" />\n <span className=\"sr-only\">More</span>\n </span>\n );\n}\n\nexport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbPage,\n BreadcrumbSeparator,\n BreadcrumbEllipsis,\n};\n",
|
|
@@ -162,6 +191,8 @@
|
|
|
162
191
|
},
|
|
163
192
|
{
|
|
164
193
|
"name": "Button",
|
|
194
|
+
"exportName": "Button",
|
|
195
|
+
"packageName": "@rlx-widgets/button",
|
|
165
196
|
"slug": "button",
|
|
166
197
|
"category": "widget",
|
|
167
198
|
"sourceCode": "import * as React from \"react\";\nimport { cn } from \"@rlx-widgets/base\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive cursor-pointer\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n outline:\n \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost:\n \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n icon: \"size-9\",\n \"icon-lg\": \"size-10\",\n \"icon-sm\": \"size-8\",\n \"icon-xs\": \"size-6\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n);\n\nfunction Button({\n className,\n variant,\n size,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }) {\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\nexport { Button, buttonVariants };\n",
|
|
@@ -210,6 +241,8 @@
|
|
|
210
241
|
},
|
|
211
242
|
{
|
|
212
243
|
"name": "Button Group",
|
|
244
|
+
"exportName": "ButtonGroup",
|
|
245
|
+
"packageName": "@rlx-widgets/button-group",
|
|
213
246
|
"slug": "button-group",
|
|
214
247
|
"category": "widget",
|
|
215
248
|
"sourceCode": "import { cn } from \"@rlx-widgets/base\";\nimport { Separator } from \"@rlx-widgets/separator\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nconst buttonGroupVariants = cva(\n \"flex w-fit items-stretch [&>*]:focus-visible:z-10 [&>*]:focus-visible:relative [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md has-[>[data-slot=button-group]]:gap-2\",\n {\n variants: {\n orientation: {\n horizontal:\n \"[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none\",\n vertical:\n \"flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none\",\n },\n },\n defaultVariants: {\n orientation: \"horizontal\",\n },\n }\n);\n\nfunction ButtonGroup({\n className,\n orientation,\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof buttonGroupVariants>) {\n return (\n <div\n role=\"group\"\n data-slot=\"button-group\"\n data-orientation={orientation}\n className={cn(buttonGroupVariants({ orientation }), className)}\n {...props}\n />\n );\n}\n\nfunction ButtonGroupText({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<\"div\"> & {\n asChild?: boolean;\n}) {\n const Comp = asChild ? Slot : \"div\";\n\n return (\n <Comp\n className={cn(\n \"bg-muted flex items-center gap-2 rounded-md border px-4 text-sm font-medium shadow-xs [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction ButtonGroupSeparator({\n className,\n orientation = \"vertical\",\n ...props\n}: React.ComponentProps<typeof Separator>) {\n return (\n <Separator\n data-slot=\"button-group-separator\"\n orientation={orientation}\n className={cn(\n \"bg-input relative !m-0 self-stretch data-[orientation=vertical]:h-auto\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n ButtonGroup,\n ButtonGroupSeparator,\n ButtonGroupText,\n buttonGroupVariants,\n};\n",
|
|
@@ -262,6 +295,8 @@
|
|
|
262
295
|
},
|
|
263
296
|
{
|
|
264
297
|
"name": "Calendar",
|
|
298
|
+
"exportName": "Calendar",
|
|
299
|
+
"packageName": "@rlx-widgets/calendar",
|
|
265
300
|
"slug": "calendar",
|
|
266
301
|
"category": "widget",
|
|
267
302
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport {\n ChevronDownIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n} from \"lucide-react\";\nimport { DayButton, DayPicker, getDefaultClassNames } from \"react-day-picker\";\nimport { cn } from \"@rlx-widgets/base\";\nimport { Button, buttonVariants } from \"@rlx-widgets/button\";\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n captionLayout = \"label\",\n buttonVariant = \"ghost\",\n formatters,\n components,\n ...props\n}: React.ComponentProps<typeof DayPicker> & {\n buttonVariant?: React.ComponentProps<typeof Button>[\"variant\"];\n}) {\n const defaultClassNames = getDefaultClassNames();\n\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n className={cn(\n \"bg-background group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent\",\n String.raw`rtl:**:[.rdp-button\\_next>svg]:rotate-180`,\n String.raw`rtl:**:[.rdp-button\\_previous>svg]:rotate-180`,\n className\n )}\n captionLayout={captionLayout}\n formatters={{\n formatMonthDropdown: (date) =>\n date.toLocaleString(\"default\", { month: \"short\" }),\n ...formatters,\n }}\n classNames={{\n root: cn(\"w-fit\", defaultClassNames.root),\n months: cn(\n \"flex gap-4 flex-col md:flex-row relative\",\n defaultClassNames.months\n ),\n month: cn(\"flex flex-col w-full gap-4\", defaultClassNames.month),\n nav: cn(\n \"flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between\",\n defaultClassNames.nav\n ),\n button_previous: cn(\n buttonVariants({ variant: buttonVariant }),\n \"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none\",\n defaultClassNames.button_previous\n ),\n button_next: cn(\n buttonVariants({ variant: buttonVariant }),\n \"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none\",\n defaultClassNames.button_next\n ),\n month_caption: cn(\n \"flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)\",\n defaultClassNames.month_caption\n ),\n dropdowns: cn(\n \"w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5\",\n defaultClassNames.dropdowns\n ),\n dropdown_root: cn(\n \"relative has-focus:border-ring border border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] rounded-md\",\n defaultClassNames.dropdown_root\n ),\n dropdown: cn(\n \"absolute bg-popover inset-0 opacity-0\",\n defaultClassNames.dropdown\n ),\n caption_label: cn(\n \"select-none font-medium\",\n captionLayout === \"label\"\n ? \"text-sm\"\n : \"rounded-md pl-2 pr-1 flex items-center gap-1 text-sm h-8 [&>svg]:text-muted-foreground [&>svg]:size-3.5\",\n defaultClassNames.caption_label\n ),\n table: \"w-full border-collapse\",\n weekdays: cn(\"flex\", defaultClassNames.weekdays),\n weekday: cn(\n \"text-muted-foreground rounded-md flex-1 font-normal text-[0.8rem] select-none\",\n defaultClassNames.weekday\n ),\n week: cn(\"flex w-full mt-2\", defaultClassNames.week),\n week_number_header: cn(\n \"select-none w-(--cell-size)\",\n defaultClassNames.week_number_header\n ),\n week_number: cn(\n \"text-[0.8rem] select-none text-muted-foreground\",\n defaultClassNames.week_number\n ),\n day: cn(\n \"relative w-full h-full p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md group/day aspect-square select-none\",\n defaultClassNames.day\n ),\n range_start: cn(\n \"rounded-l-md bg-accent\",\n defaultClassNames.range_start\n ),\n range_middle: cn(\"rounded-none\", defaultClassNames.range_middle),\n range_end: cn(\"rounded-r-md bg-accent\", defaultClassNames.range_end),\n today: cn(\n \"bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none\",\n defaultClassNames.today\n ),\n outside: cn(\n \"text-muted-foreground aria-selected:text-muted-foreground\",\n defaultClassNames.outside\n ),\n disabled: cn(\n \"text-muted-foreground opacity-50\",\n defaultClassNames.disabled\n ),\n hidden: cn(\"invisible\", defaultClassNames.hidden),\n ...classNames,\n }}\n components={{\n Root: ({ className, rootRef, ...props }) => {\n return (\n <div\n data-slot=\"calendar\"\n ref={rootRef}\n className={cn(className)}\n {...props}\n />\n );\n },\n Chevron: ({ className, orientation, ...props }) => {\n if (orientation === \"left\") {\n return (\n <ChevronLeftIcon className={cn(\"size-4\", className)} {...props} />\n );\n }\n\n if (orientation === \"right\") {\n return (\n <ChevronRightIcon\n className={cn(\"size-4\", className)}\n {...props}\n />\n );\n }\n\n return (\n <ChevronDownIcon className={cn(\"size-4\", className)} {...props} />\n );\n },\n DayButton: CalendarDayButton,\n WeekNumber: ({ children, ...props }) => {\n return (\n <td {...props}>\n <div className=\"flex size-(--cell-size) items-center justify-center text-center\">\n {children}\n </div>\n </td>\n );\n },\n ...components,\n }}\n {...props}\n />\n );\n}\n\nfunction CalendarDayButton({\n className,\n day,\n modifiers,\n ...props\n}: React.ComponentProps<typeof DayButton>) {\n const defaultClassNames = getDefaultClassNames();\n\n const ref = React.useRef<HTMLButtonElement>(null);\n React.useEffect(() => {\n if (modifiers.focused) ref.current?.focus();\n }, [modifiers.focused]);\n\n return (\n <Button\n ref={ref}\n variant=\"ghost\"\n size=\"icon\"\n data-day={day.date.toLocaleDateString()}\n data-selected-single={\n modifiers.selected &&\n !modifiers.range_start &&\n !modifiers.range_end &&\n !modifiers.range_middle\n }\n data-range-start={modifiers.range_start}\n data-range-end={modifiers.range_end}\n data-range-middle={modifiers.range_middle}\n className={cn(\n \"data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 dark:hover:text-accent-foreground flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md [&>span]:text-xs [&>span]:opacity-70\",\n defaultClassNames.day,\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Calendar, CalendarDayButton };\n",
|
|
@@ -298,6 +333,8 @@
|
|
|
298
333
|
},
|
|
299
334
|
{
|
|
300
335
|
"name": "Card",
|
|
336
|
+
"exportName": "Card",
|
|
337
|
+
"packageName": "@rlx-widgets/card",
|
|
301
338
|
"slug": "card",
|
|
302
339
|
"category": "widget",
|
|
303
340
|
"sourceCode": "import * as React from \"react\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction Card({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card\"\n className={cn(\n \"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n \"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn(\"leading-none font-semibold\", className)}\n {...props}\n />\n );\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n );\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn(\n \"col-start-2 row-span-2 row-start-1 self-start justify-self-end\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-content\"\n className={cn(\"px-6\", className)}\n {...props}\n />\n );\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn(\"flex items-center px-6 [.border-t]:pt-6\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n};\n",
|
|
@@ -310,6 +347,8 @@
|
|
|
310
347
|
},
|
|
311
348
|
{
|
|
312
349
|
"name": "Carousel",
|
|
350
|
+
"exportName": "Carousel",
|
|
351
|
+
"packageName": "@rlx-widgets/carousel",
|
|
313
352
|
"slug": "carousel",
|
|
314
353
|
"category": "widget",
|
|
315
354
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport useEmblaCarousel, {\n type UseEmblaCarouselType,\n} from \"embla-carousel-react\";\nimport { ArrowLeft, ArrowRight } from \"lucide-react\";\n\nimport { cn } from \"@rlx-widgets/base\";\nimport { Button } from \"@rlx-widgets/button\";\n\ntype CarouselApi = UseEmblaCarouselType[1];\ntype UseCarouselParameters = Parameters<typeof useEmblaCarousel>;\ntype CarouselOptions = UseCarouselParameters[0];\ntype CarouselPlugin = UseCarouselParameters[1];\n\ntype CarouselProps = {\n opts?: CarouselOptions;\n plugins?: CarouselPlugin;\n orientation?: \"horizontal\" | \"vertical\";\n setApi?: (api: CarouselApi) => void;\n};\n\ntype CarouselContextProps = {\n carouselRef: ReturnType<typeof useEmblaCarousel>[0];\n api: ReturnType<typeof useEmblaCarousel>[1];\n scrollPrev: () => void;\n scrollNext: () => void;\n canScrollPrev: boolean;\n canScrollNext: boolean;\n} & CarouselProps;\n\nconst CarouselContext = React.createContext<CarouselContextProps | null>(null);\n\nfunction useCarousel() {\n const context = React.useContext(CarouselContext);\n\n if (!context) {\n throw new Error(\"useCarousel must be used within a <Carousel />\");\n }\n\n return context;\n}\n\nfunction Carousel({\n orientation = \"horizontal\",\n opts,\n setApi,\n plugins,\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & CarouselProps) {\n const [carouselRef, api] = useEmblaCarousel(\n {\n ...opts,\n axis: orientation === \"horizontal\" ? \"x\" : \"y\",\n },\n plugins\n );\n const [canScrollPrev, setCanScrollPrev] = React.useState(false);\n const [canScrollNext, setCanScrollNext] = React.useState(false);\n\n const onSelect = React.useCallback((api: CarouselApi) => {\n if (!api) return;\n setCanScrollPrev(api.canScrollPrev());\n setCanScrollNext(api.canScrollNext());\n }, []);\n\n const scrollPrev = React.useCallback(() => {\n api?.scrollPrev();\n }, [api]);\n\n const scrollNext = React.useCallback(() => {\n api?.scrollNext();\n }, [api]);\n\n const handleKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n scrollPrev();\n } else if (event.key === \"ArrowRight\") {\n event.preventDefault();\n scrollNext();\n }\n },\n [scrollPrev, scrollNext]\n );\n\n React.useEffect(() => {\n if (!api || !setApi) return;\n setApi(api);\n }, [api, setApi]);\n\n React.useEffect(() => {\n if (!api) return;\n onSelect(api);\n api.on(\"reInit\", onSelect);\n api.on(\"select\", onSelect);\n\n return () => {\n api?.off(\"select\", onSelect);\n };\n }, [api, onSelect]);\n\n return (\n <CarouselContext.Provider\n value={{\n carouselRef,\n api: api,\n opts,\n orientation:\n orientation || (opts?.axis === \"y\" ? \"vertical\" : \"horizontal\"),\n scrollPrev,\n scrollNext,\n canScrollPrev,\n canScrollNext,\n }}\n >\n <div\n onKeyDownCapture={handleKeyDown}\n className={cn(\"relative\", className)}\n role=\"region\"\n aria-roledescription=\"carousel\"\n data-slot=\"carousel\"\n {...props}\n >\n {children}\n </div>\n </CarouselContext.Provider>\n );\n}\n\nfunction CarouselContent({ className, ...props }: React.ComponentProps<\"div\">) {\n const { carouselRef, orientation } = useCarousel();\n\n return (\n <div\n ref={carouselRef}\n className=\"overflow-hidden\"\n data-slot=\"carousel-content\"\n >\n <div\n className={cn(\n \"flex\",\n orientation === \"horizontal\" ? \"-ml-4\" : \"-mt-4 flex-col\",\n className\n )}\n {...props}\n />\n </div>\n );\n}\n\nfunction CarouselItem({ className, ...props }: React.ComponentProps<\"div\">) {\n const { orientation } = useCarousel();\n\n return (\n <div\n role=\"group\"\n aria-roledescription=\"slide\"\n data-slot=\"carousel-item\"\n className={cn(\n \"min-w-0 shrink-0 grow-0 basis-full\",\n orientation === \"horizontal\" ? \"pl-4\" : \"pt-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction CarouselPrevious({\n className,\n variant = \"outline\",\n size = \"icon\",\n ...props\n}: React.ComponentProps<typeof Button>) {\n const { orientation, scrollPrev, canScrollPrev } = useCarousel();\n\n return (\n <Button\n data-slot=\"carousel-previous\"\n variant={variant}\n size={size}\n className={cn(\n \"absolute size-8 rounded-full\",\n orientation === \"horizontal\"\n ? \"top-1/2 -left-12 -translate-y-1/2\"\n : \"-top-12 left-1/2 -translate-x-1/2 rotate-90\",\n className\n )}\n disabled={!canScrollPrev}\n onClick={scrollPrev}\n {...props}\n >\n <ArrowLeft />\n <span className=\"sr-only\">Previous slide</span>\n </Button>\n );\n}\n\nfunction CarouselNext({\n className,\n variant = \"outline\",\n size = \"icon\",\n ...props\n}: React.ComponentProps<typeof Button>) {\n const { orientation, scrollNext, canScrollNext } = useCarousel();\n\n return (\n <Button\n data-slot=\"carousel-next\"\n variant={variant}\n size={size}\n className={cn(\n \"absolute size-8 rounded-full\",\n orientation === \"horizontal\"\n ? \"top-1/2 -right-12 -translate-y-1/2\"\n : \"-bottom-12 left-1/2 -translate-x-1/2 rotate-90\",\n className\n )}\n disabled={!canScrollNext}\n onClick={scrollNext}\n {...props}\n >\n <ArrowRight />\n <span className=\"sr-only\">Next slide</span>\n </Button>\n );\n}\n\nexport {\n type CarouselApi,\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselPrevious,\n CarouselNext,\n};\n",
|
|
@@ -338,6 +377,8 @@
|
|
|
338
377
|
},
|
|
339
378
|
{
|
|
340
379
|
"name": "Checkbox",
|
|
380
|
+
"exportName": "Checkbox",
|
|
381
|
+
"packageName": "@rlx-widgets/checkbox",
|
|
341
382
|
"slug": "checkbox",
|
|
342
383
|
"category": "widget",
|
|
343
384
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as CheckboxPrimitive from \"@radix-ui/react-checkbox\";\nimport { CheckIcon } from \"lucide-react\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction Checkbox({\n className,\n ...props\n}: React.ComponentProps<typeof CheckboxPrimitive.Root>) {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n \"peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n data-slot=\"checkbox-indicator\"\n className=\"flex items-center justify-center text-current transition-none\"\n >\n <CheckIcon className=\"size-3.5\" />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n );\n}\n\nexport { Checkbox };\n",
|
|
@@ -354,6 +395,8 @@
|
|
|
354
395
|
},
|
|
355
396
|
{
|
|
356
397
|
"name": "Collapsible",
|
|
398
|
+
"exportName": "Collapsible",
|
|
399
|
+
"packageName": "@rlx-widgets/collapsible",
|
|
357
400
|
"slug": "collapsible",
|
|
358
401
|
"category": "widget",
|
|
359
402
|
"sourceCode": "\"use client\"\n\nimport * as CollapsiblePrimitive from \"@radix-ui/react-collapsible\"\n\nfunction Collapsible({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n return (\n <CollapsiblePrimitive.CollapsibleTrigger\n data-slot=\"collapsible-trigger\"\n {...props}\n />\n )\n}\n\nfunction CollapsibleContent({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n return (\n <CollapsiblePrimitive.CollapsibleContent\n data-slot=\"collapsible-content\"\n {...props}\n />\n )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n",
|
|
@@ -364,35 +407,10 @@
|
|
|
364
407
|
}
|
|
365
408
|
]
|
|
366
409
|
},
|
|
367
|
-
{
|
|
368
|
-
"name": "Combobox",
|
|
369
|
-
"slug": "combobox",
|
|
370
|
-
"category": "widget",
|
|
371
|
-
"demos": [
|
|
372
|
-
{
|
|
373
|
-
"name": "default",
|
|
374
|
-
"code": "\"use client\";\n\nimport * as React from \"react\";\nimport { Check, ChevronsUpDown } from \"lucide-react\";\nimport { cn } from \"@rlx-widgets/base\";\nimport { Button } from \"@rlx-widgets/button\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@rlx-widgets/command\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@rlx-widgets/popover\";\n\nconst frameworks = [\n {\n value: \"next.js\",\n label: \"Next.js\",\n },\n {\n value: \"sveltekit\",\n label: \"SvelteKit\",\n },\n {\n value: \"nuxt.js\",\n label: \"Nuxt.js\",\n },\n {\n value: \"remix\",\n label: \"Remix\",\n },\n {\n value: \"astro\",\n label: \"Astro\",\n },\n];\n\nexport const Preview = () => {\n const [open, setOpen] = React.useState(false);\n const [value, setValue] = React.useState(\"\");\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n className=\"w-[200px] justify-between\"\n >\n {value\n ? frameworks.find((framework) => framework.value === value)?.label\n : \"Select framework...\"}\n <ChevronsUpDown className=\"opacity-50\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-[200px] p-0\">\n <Command>\n <CommandInput placeholder=\"Search framework...\" className=\"h-9\" />\n <CommandList>\n <CommandEmpty>No framework found.</CommandEmpty>\n <CommandGroup>\n {frameworks.map((framework) => (\n <CommandItem\n key={framework.value}\n value={framework.value}\n onSelect={(currentValue) => {\n setValue(currentValue === value ? \"\" : currentValue);\n setOpen(false);\n }}\n >\n {framework.label}\n <Check\n className={cn(\n \"ml-auto\",\n value === framework.value ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n );\n};\n"
|
|
375
|
-
},
|
|
376
|
-
{
|
|
377
|
-
"name": "dropdown-menu",
|
|
378
|
-
"code": "\"use client\";\n\nimport * as React from \"react\";\nimport { MoreHorizontal } from \"lucide-react\";\nimport { Button } from \"@rlx-widgets/button\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@rlx-widgets/command\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from \"@rlx-widgets/dropdown-menu\";\n\nconst labels = [\n \"feature\",\n \"bug\",\n \"enhancement\",\n \"documentation\",\n \"design\",\n \"question\",\n \"maintenance\",\n];\n\nexport const Preview = () => {\n const [label, setLabel] = React.useState(\"feature\");\n const [open, setOpen] = React.useState(false);\n\n return (\n <div className=\"flex w-full flex-col items-start justify-between rounded-md border px-4 py-3 sm:flex-row sm:items-center\">\n <p className=\"text-sm leading-none font-medium\">\n <span className=\"bg-primary text-primary-foreground mr-2 rounded-lg px-2 py-1 text-xs\">\n {label}\n </span>\n <span className=\"text-muted-foreground\">Create a new project</span>\n </p>\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"sm\">\n <MoreHorizontal />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-[200px]\">\n <DropdownMenuLabel>Actions</DropdownMenuLabel>\n <DropdownMenuGroup>\n <DropdownMenuItem>Assign to...</DropdownMenuItem>\n <DropdownMenuItem>Set due date...</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuSub>\n <DropdownMenuSubTrigger>Apply label</DropdownMenuSubTrigger>\n <DropdownMenuSubContent className=\"p-0\">\n <Command>\n <CommandInput\n placeholder=\"Filter label...\"\n autoFocus={true}\n className=\"h-9\"\n />\n <CommandList>\n <CommandEmpty>No label found.</CommandEmpty>\n <CommandGroup>\n {labels.map((label) => (\n <CommandItem\n key={label}\n value={label}\n onSelect={(value) => {\n setLabel(value);\n setOpen(false);\n }}\n >\n {label}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </DropdownMenuSubContent>\n </DropdownMenuSub>\n <DropdownMenuSeparator />\n <DropdownMenuItem className=\"text-red-600\">\n Delete\n <DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut>\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n );\n};\n"
|
|
379
|
-
},
|
|
380
|
-
{
|
|
381
|
-
"name": "form",
|
|
382
|
-
"code": "\"use client\";\n\nimport { Button } from \"@rlx-widgets/button\";\nimport { Check, ChevronsUpDown } from \"lucide-react\";\nimport { cn } from \"@rlx-widgets/base\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@rlx-widgets/popover\";\nimport { toast } from \"sonner\";\nimport { useForm } from \"react-hook-form\";\nimport { z } from \"zod\";\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@rlx-widgets/command\";\nimport {\n Form,\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from \"@rlx-widgets/form\";\n\nconst languages = [\n { label: \"English\", value: \"en\" },\n { label: \"French\", value: \"fr\" },\n { label: \"German\", value: \"de\" },\n { label: \"Spanish\", value: \"es\" },\n { label: \"Portuguese\", value: \"pt\" },\n { label: \"Russian\", value: \"ru\" },\n { label: \"Japanese\", value: \"ja\" },\n { label: \"Korean\", value: \"ko\" },\n { label: \"Chinese\", value: \"zh\" },\n] as const;\n\nconst FormSchema = z.object({\n language: z.string({\n error: \"Please select a language.\",\n }),\n});\n\nexport const Preview = () => {\n const form = useForm<z.infer<typeof FormSchema>>({\n resolver: zodResolver(FormSchema),\n });\n\n function onSubmit(data: z.infer<typeof FormSchema>) {\n toast(\"You submitted the following values\", {\n description: (\n <pre className=\"mt-2 w-[320px] rounded-md bg-neutral-950 p-4\">\n <code className=\"text-white\">{JSON.stringify(data, null, 2)}</code>\n </pre>\n ),\n });\n }\n\n return (\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-6\">\n <FormField\n control={form.control}\n name=\"language\"\n render={({ field }) => (\n <FormItem className=\"flex flex-col\">\n <FormLabel>Language</FormLabel>\n <Popover>\n <PopoverTrigger asChild>\n <FormControl>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n className={cn(\n \"w-[200px] justify-between\",\n !field.value && \"text-muted-foreground\"\n )}\n >\n {field.value\n ? languages.find(\n (language) => language.value === field.value\n )?.label\n : \"Select language\"}\n <ChevronsUpDown className=\"opacity-50\" />\n </Button>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent className=\"w-[200px] p-0\">\n <Command>\n <CommandInput\n placeholder=\"Search framework...\"\n className=\"h-9\"\n />\n <CommandList>\n <CommandEmpty>No framework found.</CommandEmpty>\n <CommandGroup>\n {languages.map((language) => (\n <CommandItem\n value={language.label}\n key={language.value}\n onSelect={() => {\n form.setValue(\"language\", language.value);\n }}\n >\n {language.label}\n <Check\n className={cn(\n \"ml-auto\",\n language.value === field.value\n ? \"opacity-100\"\n : \"opacity-0\"\n )}\n />\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n <FormDescription>\n This is the language that will be used in the dashboard.\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n <Button type=\"submit\">Submit</Button>\n </form>\n </Form>\n );\n};\n"
|
|
383
|
-
},
|
|
384
|
-
{
|
|
385
|
-
"name": "popover",
|
|
386
|
-
"code": "\"use client\";\n\nimport * as React from \"react\";\nimport { Button } from \"@rlx-widgets/button\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@rlx-widgets/command\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@rlx-widgets/popover\";\n\ntype Status = {\n value: string;\n label: string;\n};\n\nconst statuses: Status[] = [\n {\n value: \"backlog\",\n label: \"Backlog\",\n },\n {\n value: \"todo\",\n label: \"Todo\",\n },\n {\n value: \"in progress\",\n label: \"In Progress\",\n },\n {\n value: \"done\",\n label: \"Done\",\n },\n {\n value: \"canceled\",\n label: \"Canceled\",\n },\n];\n\nexport const Preview = () => {\n const [open, setOpen] = React.useState(false);\n const [selectedStatus, setSelectedStatus] = React.useState<Status | null>(\n null\n );\n\n return (\n <div className=\"flex items-center space-x-4\">\n <p className=\"text-muted-foreground text-sm\">Status</p>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button variant=\"outline\" className=\"w-[150px] justify-start\">\n {selectedStatus ? <>{selectedStatus.label}</> : <>+ Set status</>}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"p-0\" side=\"right\" align=\"start\">\n <Command>\n <CommandInput placeholder=\"Change status...\" />\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup>\n {statuses.map((status) => (\n <CommandItem\n key={status.value}\n value={status.value}\n onSelect={(value) => {\n setSelectedStatus(\n statuses.find((priority) => priority.value === value) ||\n null\n );\n setOpen(false);\n }}\n >\n {status.label}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n </div>\n );\n};\n"
|
|
387
|
-
},
|
|
388
|
-
{
|
|
389
|
-
"name": "responsive",
|
|
390
|
-
"code": "\"use client\";\n\nimport * as React from \"react\";\nimport { useMediaQuery } from \"@rlx-hooks/use-media-query\";\nimport { Button } from \"@rlx-widgets/button\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@rlx-widgets/command\";\nimport { Drawer, DrawerContent, DrawerTrigger } from \"@rlx-widgets/drawer\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@rlx-widgets/popover\";\n\ntype Status = {\n value: string;\n label: string;\n};\n\nconst statuses: Status[] = [\n {\n value: \"backlog\",\n label: \"Backlog\",\n },\n {\n value: \"todo\",\n label: \"Todo\",\n },\n {\n value: \"in progress\",\n label: \"In Progress\",\n },\n {\n value: \"done\",\n label: \"Done\",\n },\n {\n value: \"canceled\",\n label: \"Canceled\",\n },\n];\n\nexport const Preview = () => {\n const [open, setOpen] = React.useState(false);\n const isDesktop = useMediaQuery(\"(min-width: 768px)\");\n const [selectedStatus, setSelectedStatus] = React.useState<Status | null>(\n null\n );\n\n if (isDesktop) {\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button variant=\"outline\" className=\"w-[150px] justify-start\">\n {selectedStatus ? <>{selectedStatus.label}</> : <>+ Set status</>}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-[200px] p-0\" align=\"start\">\n <StatusList setOpen={setOpen} setSelectedStatus={setSelectedStatus} />\n </PopoverContent>\n </Popover>\n );\n }\n\n return (\n <Drawer open={open} onOpenChange={setOpen}>\n <DrawerTrigger asChild>\n <Button variant=\"outline\" className=\"w-[150px] justify-start\">\n {selectedStatus ? <>{selectedStatus.label}</> : <>+ Set status</>}\n </Button>\n </DrawerTrigger>\n <DrawerContent>\n <div className=\"mt-4 border-t\">\n <StatusList setOpen={setOpen} setSelectedStatus={setSelectedStatus} />\n </div>\n </DrawerContent>\n </Drawer>\n );\n};\n\nfunction StatusList({\n setOpen,\n setSelectedStatus,\n}: {\n setOpen: (open: boolean) => void;\n setSelectedStatus: (status: Status | null) => void;\n}) {\n return (\n <Command>\n <CommandInput placeholder=\"Filter status...\" />\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup>\n {statuses.map((status) => (\n <CommandItem\n key={status.value}\n value={status.value}\n onSelect={(value) => {\n setSelectedStatus(\n statuses.find((priority) => priority.value === value) || null\n );\n setOpen(false);\n }}\n >\n {status.label}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n );\n}\n"
|
|
391
|
-
}
|
|
392
|
-
]
|
|
393
|
-
},
|
|
394
410
|
{
|
|
395
411
|
"name": "Command",
|
|
412
|
+
"exportName": "Command",
|
|
413
|
+
"packageName": "@rlx-widgets/command",
|
|
396
414
|
"slug": "command",
|
|
397
415
|
"category": "widget",
|
|
398
416
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport { SearchIcon } from \"lucide-react\";\nimport { cn } from \"@rlx-widgets/base\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from \"@rlx-widgets/dialog\";\n\nfunction Command({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive>) {\n return (\n <CommandPrimitive\n data-slot=\"command\"\n className={cn(\n \"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction CommandDialog({\n title = \"Command Palette\",\n description = \"Search for a command to run...\",\n children,\n className,\n showCloseButton = true,\n ...props\n}: React.ComponentProps<typeof Dialog> & {\n title?: string;\n description?: string;\n className?: string;\n showCloseButton?: boolean;\n}) {\n return (\n <Dialog {...props}>\n <DialogHeader className=\"sr-only\">\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n <DialogContent\n className={cn(\"overflow-hidden p-0\", className)}\n showCloseButton={showCloseButton}\n >\n <Command className=\"[&_[cmdk-group-heading]]:text-muted-foreground **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n {children}\n </Command>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction CommandInput({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n return (\n <div\n data-slot=\"command-input-wrapper\"\n className=\"flex h-9 items-center gap-2 border-b px-3\"\n >\n <SearchIcon className=\"size-4 shrink-0 opacity-50\" />\n <CommandPrimitive.Input\n data-slot=\"command-input\"\n className={cn(\n \"placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n />\n </div>\n );\n}\n\nfunction CommandList({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.List>) {\n return (\n <CommandPrimitive.List\n data-slot=\"command-list\"\n className={cn(\n \"max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction CommandEmpty({\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n return (\n <CommandPrimitive.Empty\n data-slot=\"command-empty\"\n className=\"py-6 text-center text-sm\"\n {...props}\n />\n );\n}\n\nfunction CommandGroup({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n return (\n <CommandPrimitive.Group\n data-slot=\"command-group\"\n className={cn(\n \"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction CommandSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n return (\n <CommandPrimitive.Separator\n data-slot=\"command-separator\"\n className={cn(\"bg-border -mx-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nfunction CommandItem({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Item>) {\n return (\n <CommandPrimitive.Item\n data-slot=\"command-item\"\n className={cn(\n \"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction CommandShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"command-shortcut\"\n className={cn(\n \"text-muted-foreground ml-auto text-xs tracking-widest\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n};\n",
|
|
@@ -409,6 +427,8 @@
|
|
|
409
427
|
},
|
|
410
428
|
{
|
|
411
429
|
"name": "Context Menu",
|
|
430
|
+
"exportName": "ContextMenu",
|
|
431
|
+
"packageName": "@rlx-widgets/context-menu",
|
|
412
432
|
"slug": "context-menu",
|
|
413
433
|
"category": "widget",
|
|
414
434
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as ContextMenuPrimitive from \"@radix-ui/react-context-menu\";\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction ContextMenu({\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Root>) {\n return <ContextMenuPrimitive.Root data-slot=\"context-menu\" {...props} />;\n}\n\nfunction ContextMenuTrigger({\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Trigger>) {\n return (\n <ContextMenuPrimitive.Trigger data-slot=\"context-menu-trigger\" {...props} />\n );\n}\n\nfunction ContextMenuGroup({\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Group>) {\n return (\n <ContextMenuPrimitive.Group data-slot=\"context-menu-group\" {...props} />\n );\n}\n\nfunction ContextMenuPortal({\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Portal>) {\n return (\n <ContextMenuPrimitive.Portal data-slot=\"context-menu-portal\" {...props} />\n );\n}\n\nfunction ContextMenuSub({\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Sub>) {\n return <ContextMenuPrimitive.Sub data-slot=\"context-menu-sub\" {...props} />;\n}\n\nfunction ContextMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.RadioGroup>) {\n return (\n <ContextMenuPrimitive.RadioGroup\n data-slot=\"context-menu-radio-group\"\n {...props}\n />\n );\n}\n\nfunction ContextMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n}) {\n return (\n <ContextMenuPrimitive.SubTrigger\n data-slot=\"context-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto\" />\n </ContextMenuPrimitive.SubTrigger>\n );\n}\n\nfunction ContextMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.SubContent>) {\n return (\n <ContextMenuPrimitive.SubContent\n data-slot=\"context-menu-sub-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction ContextMenuContent({\n className,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Content>) {\n return (\n <ContextMenuPrimitive.Portal>\n <ContextMenuPrimitive.Content\n data-slot=\"context-menu-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-context-menu-content-available-height) min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md\",\n className\n )}\n {...props}\n />\n </ContextMenuPrimitive.Portal>\n );\n}\n\nfunction ContextMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: \"default\" | \"destructive\";\n}) {\n return (\n <ContextMenuPrimitive.Item\n data-slot=\"context-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction ContextMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.CheckboxItem>) {\n return (\n <ContextMenuPrimitive.CheckboxItem\n data-slot=\"context-menu-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <ContextMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </ContextMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </ContextMenuPrimitive.CheckboxItem>\n );\n}\n\nfunction ContextMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.RadioItem>) {\n return (\n <ContextMenuPrimitive.RadioItem\n data-slot=\"context-menu-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <ContextMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </ContextMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </ContextMenuPrimitive.RadioItem>\n );\n}\n\nfunction ContextMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Label> & {\n inset?: boolean;\n}) {\n return (\n <ContextMenuPrimitive.Label\n data-slot=\"context-menu-label\"\n data-inset={inset}\n className={cn(\n \"text-foreground px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction ContextMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Separator>) {\n return (\n <ContextMenuPrimitive.Separator\n data-slot=\"context-menu-separator\"\n className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nfunction ContextMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"context-menu-shortcut\"\n className={cn(\n \"text-muted-foreground ml-auto text-xs tracking-widest\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n ContextMenu,\n ContextMenuTrigger,\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuCheckboxItem,\n ContextMenuRadioItem,\n ContextMenuLabel,\n ContextMenuSeparator,\n ContextMenuShortcut,\n ContextMenuGroup,\n ContextMenuPortal,\n ContextMenuSub,\n ContextMenuSubContent,\n ContextMenuSubTrigger,\n ContextMenuRadioGroup,\n};\n",
|
|
@@ -421,6 +441,8 @@
|
|
|
421
441
|
},
|
|
422
442
|
{
|
|
423
443
|
"name": "Dialog",
|
|
444
|
+
"exportName": "Dialog",
|
|
445
|
+
"packageName": "@rlx-widgets/dialog",
|
|
424
446
|
"slug": "dialog",
|
|
425
447
|
"category": "widget",
|
|
426
448
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { XIcon } from \"lucide-react\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction Dialog({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Root>) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />;\n}\n\nfunction DialogTrigger({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\nfunction DialogPortal({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\n}\n\nfunction DialogClose({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Close>) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\n}\n\nfunction DialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction DialogContent({\n className,\n children,\n showCloseButton = true,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n showCloseButton?: boolean;\n}) {\n return (\n <DialogPortal data-slot=\"dialog-portal\">\n <DialogOverlay />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n >\n <XIcon />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n );\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n {...props}\n />\n );\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction DialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\"text-lg leading-none font-semibold\", className)}\n {...props}\n />\n );\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n};\n",
|
|
@@ -437,6 +459,8 @@
|
|
|
437
459
|
},
|
|
438
460
|
{
|
|
439
461
|
"name": "Drawer",
|
|
462
|
+
"exportName": "Drawer",
|
|
463
|
+
"packageName": "@rlx-widgets/drawer",
|
|
440
464
|
"slug": "drawer",
|
|
441
465
|
"category": "widget",
|
|
442
466
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@rlx-widgets/base\";\nimport { Drawer as DrawerPrimitive } from \"vaul\";\n\nfunction Drawer({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Root>) {\n return <DrawerPrimitive.Root data-slot=\"drawer\" {...props} />;\n}\n\nfunction DrawerTrigger({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {\n return <DrawerPrimitive.Trigger data-slot=\"drawer-trigger\" {...props} />;\n}\n\nfunction DrawerPortal({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Portal>) {\n return <DrawerPrimitive.Portal data-slot=\"drawer-portal\" {...props} />;\n}\n\nfunction DrawerClose({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Close>) {\n return <DrawerPrimitive.Close data-slot=\"drawer-close\" {...props} />;\n}\n\nfunction DrawerOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {\n return (\n <DrawerPrimitive.Overlay\n data-slot=\"drawer-overlay\"\n className={cn(\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction DrawerContent({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Content>) {\n return (\n <DrawerPortal data-slot=\"drawer-portal\">\n <DrawerOverlay />\n <DrawerPrimitive.Content\n data-slot=\"drawer-content\"\n className={cn(\n \"group/drawer-content bg-background fixed z-50 flex h-auto flex-col\",\n \"data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-lg data-[vaul-drawer-direction=top]:border-b\",\n \"data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-lg data-[vaul-drawer-direction=bottom]:border-t\",\n \"data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=right]:sm:max-w-sm\",\n \"data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=left]:sm:max-w-sm\",\n className\n )}\n {...props}\n >\n <div className=\"bg-muted mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full group-data-[vaul-drawer-direction=bottom]/drawer-content:block\" />\n {children}\n </DrawerPrimitive.Content>\n </DrawerPortal>\n );\n}\n\nfunction DrawerHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"drawer-header\"\n className={cn(\n \"flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-1.5 md:text-left\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction DrawerFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"drawer-footer\"\n className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n );\n}\n\nfunction DrawerTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Title>) {\n return (\n <DrawerPrimitive.Title\n data-slot=\"drawer-title\"\n className={cn(\"text-foreground font-semibold\", className)}\n {...props}\n />\n );\n}\n\nfunction DrawerDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Description>) {\n return (\n <DrawerPrimitive.Description\n data-slot=\"drawer-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Drawer,\n DrawerPortal,\n DrawerOverlay,\n DrawerTrigger,\n DrawerClose,\n DrawerContent,\n DrawerHeader,\n DrawerFooter,\n DrawerTitle,\n DrawerDescription,\n};\n",
|
|
@@ -457,6 +481,8 @@
|
|
|
457
481
|
},
|
|
458
482
|
{
|
|
459
483
|
"name": "Dropdown Menu",
|
|
484
|
+
"exportName": "DropdownMenu",
|
|
485
|
+
"packageName": "@rlx-widgets/dropdown-menu",
|
|
460
486
|
"slug": "dropdown-menu",
|
|
461
487
|
"category": "widget",
|
|
462
488
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction DropdownMenu({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nfunction DropdownMenuPortal({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n return (\n <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n );\n}\n\nfunction DropdownMenuTrigger({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return (\n <DropdownMenuPrimitive.Trigger\n data-slot=\"dropdown-menu-trigger\"\n {...props}\n />\n );\n}\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md\",\n className\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nfunction DropdownMenuGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return (\n <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n );\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: \"default\" | \"destructive\";\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n );\n}\n\nfunction DropdownMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n return (\n <DropdownMenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n );\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n );\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n \"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n \"text-muted-foreground ml-auto text-xs tracking-widest\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSub({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n );\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n};\n",
|
|
@@ -473,6 +499,8 @@
|
|
|
473
499
|
},
|
|
474
500
|
{
|
|
475
501
|
"name": "Empty",
|
|
502
|
+
"exportName": "Empty",
|
|
503
|
+
"packageName": "@rlx-widgets/empty",
|
|
476
504
|
"slug": "empty",
|
|
477
505
|
"category": "widget",
|
|
478
506
|
"sourceCode": "import { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction Empty({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"empty\"\n className={cn(\n \"flex min-w-0 flex-1 flex-col items-center justify-center gap-6 rounded-lg border-dashed p-6 text-center text-balance md:p-12\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction EmptyHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"empty-header\"\n className={cn(\n \"flex max-w-sm flex-col items-center gap-2 text-center\",\n className\n )}\n {...props}\n />\n );\n}\n\nconst emptyMediaVariants = cva(\n \"flex shrink-0 items-center justify-center mb-2 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: \"bg-transparent\",\n icon: \"bg-muted text-foreground flex size-10 shrink-0 items-center justify-center rounded-lg [&_svg:not([class*='size-'])]:size-6\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n);\n\nfunction EmptyMedia({\n className,\n variant = \"default\",\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof emptyMediaVariants>) {\n return (\n <div\n data-slot=\"empty-icon\"\n data-variant={variant}\n className={cn(emptyMediaVariants({ variant, className }))}\n {...props}\n />\n );\n}\n\nfunction EmptyTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"empty-title\"\n className={cn(\"text-lg font-medium tracking-tight\", className)}\n {...props}\n />\n );\n}\n\nfunction EmptyDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n return (\n <div\n data-slot=\"empty-description\"\n className={cn(\n \"text-muted-foreground [&>a:hover]:text-primary text-sm/relaxed [&>a]:underline [&>a]:underline-offset-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction EmptyContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"empty-content\"\n className={cn(\n \"flex w-full max-w-sm min-w-0 flex-col items-center gap-4 text-sm text-balance\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n Empty,\n EmptyHeader,\n EmptyTitle,\n EmptyDescription,\n EmptyContent,\n EmptyMedia,\n};\n",
|
|
@@ -505,6 +533,8 @@
|
|
|
505
533
|
},
|
|
506
534
|
{
|
|
507
535
|
"name": "Field",
|
|
536
|
+
"exportName": "Field",
|
|
537
|
+
"packageName": "@rlx-widgets/field",
|
|
508
538
|
"slug": "field",
|
|
509
539
|
"category": "widget",
|
|
510
540
|
"sourceCode": "\"use client\";\n\nimport { useMemo } from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@rlx-widgets/base\";\nimport { Label } from \"@rlx-widgets/label\";\nimport { Separator } from \"@rlx-widgets/separator\";\n\nfunction FieldSet({ className, ...props }: React.ComponentProps<\"fieldset\">) {\n return (\n <fieldset\n data-slot=\"field-set\"\n className={cn(\n \"flex flex-col gap-6\",\n \"has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction FieldLegend({\n className,\n variant = \"legend\",\n ...props\n}: React.ComponentProps<\"legend\"> & { variant?: \"legend\" | \"label\" }) {\n return (\n <legend\n data-slot=\"field-legend\"\n data-variant={variant}\n className={cn(\n \"mb-3 font-medium\",\n \"data-[variant=legend]:text-base\",\n \"data-[variant=label]:text-sm\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction FieldGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"field-group\"\n className={cn(\n \"group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nconst fieldVariants = cva(\n \"group/field flex w-full gap-3 data-[invalid=true]:text-destructive\",\n {\n variants: {\n orientation: {\n vertical: [\"flex-col [&>*]:w-full [&>.sr-only]:w-auto\"],\n horizontal: [\n \"flex-row items-center\",\n \"[&>[data-slot=field-label]]:flex-auto\",\n \"has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px\",\n ],\n responsive: [\n \"flex-col [&>*]:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto\",\n \"@md/field-group:[&>[data-slot=field-label]]:flex-auto\",\n \"@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px\",\n ],\n },\n },\n defaultVariants: {\n orientation: \"vertical\",\n },\n }\n);\n\nfunction Field({\n className,\n orientation = \"vertical\",\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof fieldVariants>) {\n return (\n <div\n role=\"group\"\n data-slot=\"field\"\n data-orientation={orientation}\n className={cn(fieldVariants({ orientation }), className)}\n {...props}\n />\n );\n}\n\nfunction FieldContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"field-content\"\n className={cn(\n \"group/field-content flex flex-1 flex-col gap-1.5 leading-snug\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction FieldLabel({\n className,\n ...props\n}: React.ComponentProps<typeof Label>) {\n return (\n <Label\n data-slot=\"field-label\"\n className={cn(\n \"group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50\",\n \"has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4\",\n \"has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction FieldTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"field-label\"\n className={cn(\n \"flex w-fit items-center gap-2 text-sm leading-snug font-medium group-data-[disabled=true]/field:opacity-50\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction FieldDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n return (\n <p\n data-slot=\"field-description\"\n className={cn(\n \"text-muted-foreground text-sm leading-normal font-normal group-has-[[data-orientation=horizontal]]/field:text-balance\",\n \"last:mt-0 nth-last-2:-mt-1 [[data-variant=legend]+&]:-mt-1.5\",\n \"[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction FieldSeparator({\n children,\n className,\n ...props\n}: React.ComponentProps<\"div\"> & {\n children?: React.ReactNode;\n}) {\n return (\n <div\n data-slot=\"field-separator\"\n data-content={!!children}\n className={cn(\n \"relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2\",\n className\n )}\n {...props}\n >\n <Separator className=\"absolute inset-0 top-1/2\" />\n {children && (\n <span\n className=\"bg-background text-muted-foreground relative mx-auto block w-fit px-2\"\n data-slot=\"field-separator-content\"\n >\n {children}\n </span>\n )}\n </div>\n );\n}\n\nfunction FieldError({\n className,\n children,\n errors,\n ...props\n}: React.ComponentProps<\"div\"> & {\n errors?: Array<{ message?: string } | undefined>;\n}) {\n const content = useMemo(() => {\n if (children) {\n return children;\n }\n\n if (!errors) {\n return null;\n }\n\n if (errors?.length === 1 && errors[0]?.message) {\n return errors[0].message;\n }\n\n return (\n <ul className=\"ml-4 flex list-disc flex-col gap-1\">\n {errors.map(\n (error, index) =>\n error?.message && <li key={index}>{error.message}</li>\n )}\n </ul>\n );\n }, [children, errors]);\n\n if (!content) {\n return null;\n }\n\n return (\n <div\n role=\"alert\"\n data-slot=\"field-error\"\n className={cn(\"text-destructive text-sm font-normal\", className)}\n {...props}\n >\n {content}\n </div>\n );\n}\n\nexport {\n Field,\n FieldLabel,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n FieldContent,\n FieldTitle,\n};\n",
|
|
@@ -559,8 +589,18 @@
|
|
|
559
589
|
}
|
|
560
590
|
]
|
|
561
591
|
},
|
|
592
|
+
{
|
|
593
|
+
"name": "Form",
|
|
594
|
+
"exportName": "Form",
|
|
595
|
+
"packageName": "@rlx-widgets/form",
|
|
596
|
+
"slug": "form",
|
|
597
|
+
"category": "widget",
|
|
598
|
+
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as LabelPrimitive from \"@radix-ui/react-label\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport {\n Controller,\n FormProvider,\n useFormContext,\n useFormState,\n type ControllerProps,\n type FieldPath,\n type FieldValues,\n} from \"react-hook-form\";\nimport { cn } from \"@rlx-widgets/base\";\nimport { Label } from \"@rlx-widgets/label\";\n\nconst Form = FormProvider;\n\ntype FormFieldContextValue<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\n> = {\n name: TName;\n};\n\nconst FormFieldContext = React.createContext<FormFieldContextValue>(\n {} as FormFieldContextValue\n);\n\nconst FormField = <\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\n>({\n ...props\n}: ControllerProps<TFieldValues, TName>) => {\n return (\n <FormFieldContext.Provider value={{ name: props.name }}>\n <Controller {...props} />\n </FormFieldContext.Provider>\n );\n};\n\nconst useFormField = () => {\n const fieldContext = React.useContext(FormFieldContext);\n const itemContext = React.useContext(FormItemContext);\n const { getFieldState } = useFormContext();\n const formState = useFormState({ name: fieldContext.name });\n const fieldState = getFieldState(fieldContext.name, formState);\n\n if (!fieldContext) {\n throw new Error(\"useFormField should be used within <FormField>\");\n }\n\n const { id } = itemContext;\n\n return {\n id,\n name: fieldContext.name,\n formItemId: `${id}-form-item`,\n formDescriptionId: `${id}-form-item-description`,\n formMessageId: `${id}-form-item-message`,\n ...fieldState,\n };\n};\n\ntype FormItemContextValue = {\n id: string;\n};\n\nconst FormItemContext = React.createContext<FormItemContextValue>(\n {} as FormItemContextValue\n);\n\nfunction FormItem({ className, ...props }: React.ComponentProps<\"div\">) {\n const id = React.useId();\n\n return (\n <FormItemContext.Provider value={{ id }}>\n <div\n data-slot=\"form-item\"\n className={cn(\"grid gap-2\", className)}\n {...props}\n />\n </FormItemContext.Provider>\n );\n}\n\nfunction FormLabel({\n className,\n ...props\n}: React.ComponentProps<typeof LabelPrimitive.Root>) {\n const { error, formItemId } = useFormField();\n\n return (\n <Label\n data-slot=\"form-label\"\n data-error={!!error}\n className={cn(\"data-[error=true]:text-destructive\", className)}\n htmlFor={formItemId}\n {...props}\n />\n );\n}\n\nfunction FormControl({ ...props }: React.ComponentProps<typeof Slot>) {\n const { error, formItemId, formDescriptionId, formMessageId } =\n useFormField();\n\n return (\n <Slot\n data-slot=\"form-control\"\n id={formItemId}\n aria-describedby={\n !error\n ? `${formDescriptionId}`\n : `${formDescriptionId} ${formMessageId}`\n }\n aria-invalid={!!error}\n {...props}\n />\n );\n}\n\nfunction FormDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n const { formDescriptionId } = useFormField();\n\n return (\n <p\n data-slot=\"form-description\"\n id={formDescriptionId}\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n );\n}\n\nfunction FormMessage({ className, ...props }: React.ComponentProps<\"p\">) {\n const { error, formMessageId } = useFormField();\n const body = error ? String(error?.message ?? \"\") : props.children;\n\n if (!body) {\n return null;\n }\n\n return (\n <p\n data-slot=\"form-message\"\n id={formMessageId}\n className={cn(\"text-destructive text-sm\", className)}\n {...props}\n >\n {body}\n </p>\n );\n}\n\nexport {\n useFormField,\n Form,\n FormItem,\n FormLabel,\n FormControl,\n FormDescription,\n FormMessage,\n FormField,\n};\n"
|
|
599
|
+
},
|
|
562
600
|
{
|
|
563
601
|
"name": "Hover Card",
|
|
602
|
+
"exportName": "HoverCard",
|
|
603
|
+
"packageName": "@rlx-widgets/hover-card",
|
|
564
604
|
"slug": "hover-card",
|
|
565
605
|
"category": "widget",
|
|
566
606
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as HoverCardPrimitive from \"@radix-ui/react-hover-card\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction HoverCard({\n ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Root>) {\n return <HoverCardPrimitive.Root data-slot=\"hover-card\" {...props} />;\n}\n\nfunction HoverCardTrigger({\n ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {\n return (\n <HoverCardPrimitive.Trigger data-slot=\"hover-card-trigger\" {...props} />\n );\n}\n\nfunction HoverCardContent({\n className,\n align = \"center\",\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Content>) {\n return (\n <HoverCardPrimitive.Portal data-slot=\"hover-card-portal\">\n <HoverCardPrimitive.Content\n data-slot=\"hover-card-content\"\n align={align}\n sideOffset={sideOffset}\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden\",\n className\n )}\n {...props}\n />\n </HoverCardPrimitive.Portal>\n );\n}\n\nexport { HoverCard, HoverCardTrigger, HoverCardContent };\n",
|
|
@@ -573,6 +613,8 @@
|
|
|
573
613
|
},
|
|
574
614
|
{
|
|
575
615
|
"name": "Input",
|
|
616
|
+
"exportName": "Input",
|
|
617
|
+
"packageName": "@rlx-widgets/input",
|
|
576
618
|
"slug": "input",
|
|
577
619
|
"category": "widget",
|
|
578
620
|
"sourceCode": "import * as React from \"react\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <input\n type={type}\n data-slot=\"input\"\n className={cn(\n \"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n \"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Input };\n",
|
|
@@ -605,6 +647,8 @@
|
|
|
605
647
|
},
|
|
606
648
|
{
|
|
607
649
|
"name": "Input Group",
|
|
650
|
+
"exportName": "InputGroup",
|
|
651
|
+
"packageName": "@rlx-widgets/input-group",
|
|
608
652
|
"slug": "input-group",
|
|
609
653
|
"category": "widget",
|
|
610
654
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport { Button } from \"@rlx-widgets/button\";\nimport { cn } from \"@rlx-widgets/base\";\nimport { Input } from \"@rlx-widgets/input\";\nimport { Textarea } from \"@rlx-widgets/textarea\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nfunction InputGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"input-group\"\n role=\"group\"\n className={cn(\n \"group/input-group border-input dark:bg-input/30 relative flex w-full items-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none\",\n \"h-9 min-w-0 has-[>textarea]:h-auto\",\n\n // Variants based on alignment.\n \"has-[>[data-align=inline-start]]:[&>input]:pl-2\",\n \"has-[>[data-align=inline-end]]:[&>input]:pr-2\",\n \"has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3\",\n \"has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3\",\n\n // Focus state.\n \"has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot=input-group-control]:focus-visible]:ring-[3px]\",\n\n // Error state.\n \"has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40\",\n\n className\n )}\n {...props}\n />\n );\n}\n\nconst inputGroupAddonVariants = cva(\n \"text-muted-foreground flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium select-none [&>svg:not([class*='size-'])]:size-4 [&>kbd]:rounded-[calc(var(--radius)-5px)] group-data-[disabled=true]/input-group:opacity-50\",\n {\n variants: {\n align: {\n \"inline-start\":\n \"order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]\",\n \"inline-end\":\n \"order-last pr-3 has-[>button]:mr-[-0.45rem] has-[>kbd]:mr-[-0.35rem]\",\n \"block-start\":\n \"order-first w-full justify-start px-3 pt-3 [.border-b]:pb-3 group-has-[>input]/input-group:pt-2.5\",\n \"block-end\":\n \"order-last w-full justify-start px-3 pb-3 [.border-t]:pt-3 group-has-[>input]/input-group:pb-2.5\",\n },\n },\n defaultVariants: {\n align: \"inline-start\",\n },\n }\n);\n\nfunction InputGroupAddon({\n className,\n align = \"inline-start\",\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof inputGroupAddonVariants>) {\n return (\n <div\n role=\"group\"\n data-slot=\"input-group-addon\"\n data-align={align}\n className={cn(inputGroupAddonVariants({ align }), className)}\n onClick={(e) => {\n if ((e.target as HTMLElement).closest(\"button\")) {\n return;\n }\n e.currentTarget.parentElement?.querySelector(\"input\")?.focus();\n }}\n {...props}\n />\n );\n}\n\nconst inputGroupButtonVariants = cva(\n \"text-sm shadow-none flex gap-2 items-center\",\n {\n variants: {\n size: {\n xs: \"h-6 gap-1 px-2 rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-3.5 has-[>svg]:px-2\",\n sm: \"h-8 px-2.5 gap-1.5 rounded-md has-[>svg]:px-2.5\",\n \"icon-xs\":\n \"size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0\",\n \"icon-sm\": \"size-8 p-0 has-[>svg]:p-0\",\n },\n },\n defaultVariants: {\n size: \"xs\",\n },\n }\n);\n\nfunction InputGroupButton({\n className,\n type = \"button\",\n variant = \"ghost\",\n size = \"xs\",\n ...props\n}: Omit<React.ComponentProps<typeof Button>, \"size\"> &\n VariantProps<typeof inputGroupButtonVariants>) {\n return (\n <Button\n type={type}\n data-size={size}\n variant={variant}\n className={cn(inputGroupButtonVariants({ size }), className)}\n {...props}\n />\n );\n}\n\nfunction InputGroupText({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n className={cn(\n \"text-muted-foreground flex items-center gap-2 text-sm [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction InputGroupInput({\n className,\n ...props\n}: React.ComponentProps<\"input\">) {\n return (\n <Input\n data-slot=\"input-group-control\"\n className={cn(\n \"flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction InputGroupTextarea({\n className,\n ...props\n}: React.ComponentProps<\"textarea\">) {\n return (\n <Textarea\n data-slot=\"input-group-control\"\n className={cn(\n \"flex-1 resize-none rounded-none border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 dark:bg-transparent\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupText,\n InputGroupInput,\n InputGroupTextarea,\n};\n",
|
|
@@ -657,6 +701,7 @@
|
|
|
657
701
|
},
|
|
658
702
|
{
|
|
659
703
|
"name": "Input Otp",
|
|
704
|
+
"packageName": "@rlx-widgets/input-otp",
|
|
660
705
|
"slug": "input-otp",
|
|
661
706
|
"category": "widget",
|
|
662
707
|
"demos": [
|
|
@@ -680,10 +725,15 @@
|
|
|
680
725
|
"name": "separator",
|
|
681
726
|
"code": "import React from \"react\";\nimport {\n InputOTP,\n InputOTPGroup,\n InputOTPSeparator,\n InputOTPSlot,\n} from \"@rlx-widgets/input-otp\";\n\nexport const Preview = () => {\n return (\n <InputOTP maxLength={6}>\n <InputOTPGroup>\n <InputOTPSlot index={0} />\n <InputOTPSlot index={1} />\n </InputOTPGroup>\n <InputOTPSeparator />\n <InputOTPGroup>\n <InputOTPSlot index={2} />\n <InputOTPSlot index={3} />\n </InputOTPGroup>\n <InputOTPSeparator />\n <InputOTPGroup>\n <InputOTPSlot index={4} />\n <InputOTPSlot index={5} />\n </InputOTPGroup>\n </InputOTP>\n );\n};\n"
|
|
682
727
|
}
|
|
683
|
-
]
|
|
728
|
+
],
|
|
729
|
+
"sourceFiles": {
|
|
730
|
+
"components/InputOTP/InputOTP.tsx": "\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@rlx-widgets/base\";\nimport { OTPInput, OTPInputContext } from \"input-otp\";\nimport { MinusIcon } from \"lucide-react\";\n\nfunction InputOTP({\n className,\n containerClassName,\n ...props\n}: React.ComponentProps<typeof OTPInput> & {\n containerClassName?: string;\n}) {\n return (\n <OTPInput\n data-slot=\"input-otp\"\n containerClassName={cn(\n \"flex items-center gap-2 has-disabled:opacity-50\",\n containerClassName\n )}\n className={cn(\"disabled:cursor-not-allowed\", className)}\n {...props}\n />\n );\n}\n\nfunction InputOTPGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"input-otp-group\"\n className={cn(\"flex items-center\", className)}\n {...props}\n />\n );\n}\n\nfunction InputOTPSlot({\n index,\n className,\n ...props\n}: React.ComponentProps<\"div\"> & {\n index: number;\n}) {\n const inputOTPContext = React.useContext(OTPInputContext);\n const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {};\n\n return (\n <div\n data-slot=\"input-otp-slot\"\n data-active={isActive}\n className={cn(\n \"data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive dark:bg-input/30 border-input relative flex h-9 w-9 items-center justify-center border-y border-r text-sm shadow-xs transition-all outline-none first:rounded-l-md first:border-l last:rounded-r-md data-[active=true]:z-10 data-[active=true]:ring-[3px]\",\n className\n )}\n {...props}\n >\n {char}\n {hasFakeCaret && (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center\">\n <div className=\"animate-caret-blink bg-foreground h-4 w-px duration-1000\" />\n </div>\n )}\n </div>\n );\n}\n\nfunction InputOTPSeparator({ ...props }: React.ComponentProps<\"div\">) {\n return (\n <div data-slot=\"input-otp-separator\" role=\"separator\" {...props}>\n <MinusIcon />\n </div>\n );\n}\n\nexport { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };\n"
|
|
731
|
+
}
|
|
684
732
|
},
|
|
685
733
|
{
|
|
686
734
|
"name": "Item",
|
|
735
|
+
"exportName": "Item",
|
|
736
|
+
"packageName": "@rlx-widgets/item",
|
|
687
737
|
"slug": "item",
|
|
688
738
|
"category": "widget",
|
|
689
739
|
"sourceCode": "import * as React from \"react\";\nimport { cn } from \"@rlx-widgets/base\";\nimport { Separator } from \"@rlx-widgets/separator\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nfunction ItemGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n role=\"list\"\n data-slot=\"item-group\"\n className={cn(\"group/item-group flex flex-col\", className)}\n {...props}\n />\n );\n}\n\nfunction ItemSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof Separator>) {\n return (\n <Separator\n data-slot=\"item-separator\"\n orientation=\"horizontal\"\n className={cn(\"my-0\", className)}\n {...props}\n />\n );\n}\n\nconst itemVariants = cva(\n \"group/item flex items-center border border-transparent text-sm rounded-md transition-colors [a]:hover:bg-accent/50 [a]:transition-colors duration-100 flex-wrap outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n {\n variants: {\n variant: {\n default: \"bg-transparent\",\n outline: \"border-border\",\n muted: \"bg-muted/50\",\n },\n size: {\n default: \"p-4 gap-4 \",\n sm: \"py-3 px-4 gap-2.5\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n);\n\nfunction Item({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: React.ComponentProps<\"div\"> &\n VariantProps<typeof itemVariants> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : \"div\";\n return (\n <Comp\n data-slot=\"item\"\n data-variant={variant}\n data-size={size}\n className={cn(itemVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nconst itemMediaVariants = cva(\n \"flex shrink-0 items-center justify-center gap-2 group-has-[[data-slot=item-description]]/item:self-start [&_svg]:pointer-events-none group-has-[[data-slot=item-description]]/item:translate-y-0.5\",\n {\n variants: {\n variant: {\n default: \"bg-transparent\",\n icon: \"size-8 border rounded-sm bg-muted [&_svg:not([class*='size-'])]:size-4\",\n image:\n \"size-10 rounded-sm overflow-hidden [&_img]:size-full [&_img]:object-cover\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n);\n\nfunction ItemMedia({\n className,\n variant = \"default\",\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof itemMediaVariants>) {\n return (\n <div\n data-slot=\"item-media\"\n data-variant={variant}\n className={cn(itemMediaVariants({ variant, className }))}\n {...props}\n />\n );\n}\n\nfunction ItemContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"item-content\"\n className={cn(\n \"flex flex-1 flex-col gap-1 [&+[data-slot=item-content]]:flex-none\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction ItemTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"item-title\"\n className={cn(\n \"flex w-fit items-center gap-2 text-sm leading-snug font-medium\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction ItemDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n return (\n <p\n data-slot=\"item-description\"\n className={cn(\n \"text-muted-foreground line-clamp-2 text-sm leading-normal font-normal text-balance\",\n \"[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction ItemActions({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"item-actions\"\n className={cn(\"flex items-center gap-2\", className)}\n {...props}\n />\n );\n}\n\nfunction ItemHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"item-header\"\n className={cn(\n \"flex basis-full items-center justify-between gap-2\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction ItemFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"item-footer\"\n className={cn(\n \"flex basis-full items-center justify-between gap-2\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n Item,\n ItemMedia,\n ItemContent,\n ItemActions,\n ItemGroup,\n ItemSeparator,\n ItemTitle,\n ItemDescription,\n ItemHeader,\n ItemFooter,\n};\n",
|
|
@@ -732,6 +782,8 @@
|
|
|
732
782
|
},
|
|
733
783
|
{
|
|
734
784
|
"name": "Kbd",
|
|
785
|
+
"exportName": "Kbd",
|
|
786
|
+
"packageName": "@rlx-widgets/kbd",
|
|
735
787
|
"slug": "kbd",
|
|
736
788
|
"category": "widget",
|
|
737
789
|
"sourceCode": "import { cn } from \"@rlx-widgets/base\";\n\nfunction Kbd({ className, ...props }: React.ComponentProps<\"kbd\">) {\n return (\n <kbd\n data-slot=\"kbd\"\n className={cn(\n \"bg-muted text-muted-foreground pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-sm px-1 font-sans text-xs font-medium select-none\",\n \"[&_svg:not([class*='size-'])]:size-3\",\n \"[[data-slot=tooltip-content]_&]:bg-background/20 [[data-slot=tooltip-content]_&]:text-background dark:[[data-slot=tooltip-content]_&]:bg-background/10\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction KbdGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <kbd\n data-slot=\"kbd-group\"\n className={cn(\"inline-flex items-center gap-1\", className)}\n {...props}\n />\n );\n}\n\nexport { Kbd, KbdGroup };\n",
|
|
@@ -760,6 +812,8 @@
|
|
|
760
812
|
},
|
|
761
813
|
{
|
|
762
814
|
"name": "Label",
|
|
815
|
+
"exportName": "Label",
|
|
816
|
+
"packageName": "@rlx-widgets/label",
|
|
763
817
|
"slug": "label",
|
|
764
818
|
"category": "widget",
|
|
765
819
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as LabelPrimitive from \"@radix-ui/react-label\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction Label({\n className,\n ...props\n}: React.ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n \"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Label };\n",
|
|
@@ -772,6 +826,8 @@
|
|
|
772
826
|
},
|
|
773
827
|
{
|
|
774
828
|
"name": "Menubar",
|
|
829
|
+
"exportName": "Menubar",
|
|
830
|
+
"packageName": "@rlx-widgets/menubar",
|
|
775
831
|
"slug": "menubar",
|
|
776
832
|
"category": "widget",
|
|
777
833
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as MenubarPrimitive from \"@radix-ui/react-menubar\";\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction Menubar({\n className,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Root>) {\n return (\n <MenubarPrimitive.Root\n data-slot=\"menubar\"\n className={cn(\n \"bg-background flex h-9 items-center gap-1 rounded-md border p-1 shadow-xs\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction MenubarMenu({\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Menu>) {\n return <MenubarPrimitive.Menu data-slot=\"menubar-menu\" {...props} />;\n}\n\nfunction MenubarGroup({\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Group>) {\n return <MenubarPrimitive.Group data-slot=\"menubar-group\" {...props} />;\n}\n\nfunction MenubarPortal({\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Portal>) {\n return <MenubarPrimitive.Portal data-slot=\"menubar-portal\" {...props} />;\n}\n\nfunction MenubarRadioGroup({\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.RadioGroup>) {\n return (\n <MenubarPrimitive.RadioGroup data-slot=\"menubar-radio-group\" {...props} />\n );\n}\n\nfunction MenubarTrigger({\n className,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Trigger>) {\n return (\n <MenubarPrimitive.Trigger\n data-slot=\"menubar-trigger\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex items-center rounded-sm px-2 py-1 text-sm font-medium outline-hidden select-none\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction MenubarContent({\n className,\n align = \"start\",\n alignOffset = -4,\n sideOffset = 8,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Content>) {\n return (\n <MenubarPortal>\n <MenubarPrimitive.Content\n data-slot=\"menubar-content\"\n align={align}\n alignOffset={alignOffset}\n sideOffset={sideOffset}\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[12rem] origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-md\",\n className\n )}\n {...props}\n />\n </MenubarPortal>\n );\n}\n\nfunction MenubarItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Item> & {\n inset?: boolean;\n variant?: \"default\" | \"destructive\";\n}) {\n return (\n <MenubarPrimitive.Item\n data-slot=\"menubar-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction MenubarCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.CheckboxItem>) {\n return (\n <MenubarPrimitive.CheckboxItem\n data-slot=\"menubar-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <MenubarPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </MenubarPrimitive.ItemIndicator>\n </span>\n {children}\n </MenubarPrimitive.CheckboxItem>\n );\n}\n\nfunction MenubarRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.RadioItem>) {\n return (\n <MenubarPrimitive.RadioItem\n data-slot=\"menubar-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <MenubarPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </MenubarPrimitive.ItemIndicator>\n </span>\n {children}\n </MenubarPrimitive.RadioItem>\n );\n}\n\nfunction MenubarLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Label> & {\n inset?: boolean;\n}) {\n return (\n <MenubarPrimitive.Label\n data-slot=\"menubar-label\"\n data-inset={inset}\n className={cn(\n \"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction MenubarSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Separator>) {\n return (\n <MenubarPrimitive.Separator\n data-slot=\"menubar-separator\"\n className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nfunction MenubarShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"menubar-shortcut\"\n className={cn(\n \"text-muted-foreground ml-auto text-xs tracking-widest\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction MenubarSub({\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Sub>) {\n return <MenubarPrimitive.Sub data-slot=\"menubar-sub\" {...props} />;\n}\n\nfunction MenubarSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.SubTrigger> & {\n inset?: boolean;\n}) {\n return (\n <MenubarPrimitive.SubTrigger\n data-slot=\"menubar-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[inset]:pl-8\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto h-4 w-4\" />\n </MenubarPrimitive.SubTrigger>\n );\n}\n\nfunction MenubarSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.SubContent>) {\n return (\n <MenubarPrimitive.SubContent\n data-slot=\"menubar-sub-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n Menubar,\n MenubarPortal,\n MenubarMenu,\n MenubarTrigger,\n MenubarContent,\n MenubarGroup,\n MenubarSeparator,\n MenubarLabel,\n MenubarItem,\n MenubarShortcut,\n MenubarCheckboxItem,\n MenubarRadioGroup,\n MenubarRadioItem,\n MenubarSub,\n MenubarSubTrigger,\n MenubarSubContent,\n};\n",
|
|
@@ -784,6 +840,8 @@
|
|
|
784
840
|
},
|
|
785
841
|
{
|
|
786
842
|
"name": "Navigation Menu",
|
|
843
|
+
"exportName": "NavigationMenu",
|
|
844
|
+
"packageName": "@rlx-widgets/navigation-menu",
|
|
787
845
|
"slug": "navigation-menu",
|
|
788
846
|
"category": "widget",
|
|
789
847
|
"sourceCode": "import * as NavigationMenuPrimitive from \"@radix-ui/react-navigation-menu\";\nimport * as React from \"react\";\nimport { ChevronDownIcon } from \"lucide-react\";\nimport { cn } from \"@rlx-widgets/base\";\nimport { cva } from \"class-variance-authority\";\n\nfunction NavigationMenu({\n className,\n children,\n viewport = true,\n ...props\n}: React.ComponentProps<typeof NavigationMenuPrimitive.Root> & {\n viewport?: boolean;\n}) {\n return (\n <NavigationMenuPrimitive.Root\n data-slot=\"navigation-menu\"\n data-viewport={viewport}\n className={cn(\n \"group/navigation-menu relative flex max-w-max flex-1 items-center justify-center\",\n className\n )}\n {...props}\n >\n {children}\n {viewport && <NavigationMenuViewport />}\n </NavigationMenuPrimitive.Root>\n );\n}\n\nfunction NavigationMenuList({\n className,\n ...props\n}: React.ComponentProps<typeof NavigationMenuPrimitive.List>) {\n return (\n <NavigationMenuPrimitive.List\n data-slot=\"navigation-menu-list\"\n className={cn(\n \"group flex flex-1 list-none items-center justify-center gap-1\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction NavigationMenuItem({\n className,\n ...props\n}: React.ComponentProps<typeof NavigationMenuPrimitive.Item>) {\n return (\n <NavigationMenuPrimitive.Item\n data-slot=\"navigation-menu-item\"\n className={cn(\"relative\", className)}\n {...props}\n />\n );\n}\n\nconst navigationMenuTriggerStyle = cva(\n \"group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:bg-accent/50 focus-visible:ring-ring/50 outline-none transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1\"\n);\n\nfunction NavigationMenuTrigger({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof NavigationMenuPrimitive.Trigger>) {\n return (\n <NavigationMenuPrimitive.Trigger\n data-slot=\"navigation-menu-trigger\"\n className={cn(navigationMenuTriggerStyle(), \"group\", className)}\n {...props}\n >\n {children}{\" \"}\n <ChevronDownIcon\n className=\"relative top-[1px] ml-1 size-3 transition duration-300 group-data-[state=open]:rotate-180\"\n aria-hidden=\"true\"\n />\n </NavigationMenuPrimitive.Trigger>\n );\n}\n\nfunction NavigationMenuContent({\n className,\n ...props\n}: React.ComponentProps<typeof NavigationMenuPrimitive.Content>) {\n return (\n <NavigationMenuPrimitive.Content\n data-slot=\"navigation-menu-content\"\n className={cn(\n \"data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 top-0 left-0 w-full p-2 pr-2.5 md:absolute md:w-auto\",\n \"group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:data-[state=open]:animate-in group-data-[viewport=false]/navigation-menu:data-[state=closed]:animate-out group-data-[viewport=false]/navigation-menu:data-[state=closed]:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:fade-in-0 group-data-[viewport=false]/navigation-menu:data-[state=closed]:fade-out-0 group-data-[viewport=false]/navigation-menu:top-full group-data-[viewport=false]/navigation-menu:mt-1.5 group-data-[viewport=false]/navigation-menu:overflow-hidden group-data-[viewport=false]/navigation-menu:rounded-md group-data-[viewport=false]/navigation-menu:border group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:duration-200 **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction NavigationMenuViewport({\n className,\n ...props\n}: React.ComponentProps<typeof NavigationMenuPrimitive.Viewport>) {\n return (\n <div\n className={cn(\n \"absolute top-full left-0 isolate z-50 flex justify-center\"\n )}\n >\n <NavigationMenuPrimitive.Viewport\n data-slot=\"navigation-menu-viewport\"\n className={cn(\n \"origin-top-center bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border shadow md:w-[var(--radix-navigation-menu-viewport-width)]\",\n className\n )}\n {...props}\n />\n </div>\n );\n}\n\nfunction NavigationMenuLink({\n className,\n ...props\n}: React.ComponentProps<typeof NavigationMenuPrimitive.Link>) {\n return (\n <NavigationMenuPrimitive.Link\n data-slot=\"navigation-menu-link\"\n className={cn(\n \"data-[active=true]:focus:bg-accent data-[active=true]:hover:bg-accent data-[active=true]:bg-accent/50 data-[active=true]:text-accent-foreground hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus-visible:ring-ring/50 [&_svg:not([class*='text-'])]:text-muted-foreground flex flex-col gap-1 rounded-sm p-2 text-sm transition-all outline-none focus-visible:ring-[3px] focus-visible:outline-1 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction NavigationMenuIndicator({\n className,\n ...props\n}: React.ComponentProps<typeof NavigationMenuPrimitive.Indicator>) {\n return (\n <NavigationMenuPrimitive.Indicator\n data-slot=\"navigation-menu-indicator\"\n className={cn(\n \"data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden\",\n className\n )}\n {...props}\n >\n <div className=\"bg-border relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm shadow-md\" />\n </NavigationMenuPrimitive.Indicator>\n );\n}\n\nexport {\n NavigationMenu,\n NavigationMenuList,\n NavigationMenuItem,\n NavigationMenuContent,\n NavigationMenuTrigger,\n NavigationMenuLink,\n NavigationMenuIndicator,\n NavigationMenuViewport,\n navigationMenuTriggerStyle,\n};\n",
|
|
@@ -796,6 +854,8 @@
|
|
|
796
854
|
},
|
|
797
855
|
{
|
|
798
856
|
"name": "Pagination",
|
|
857
|
+
"exportName": "Pagination",
|
|
858
|
+
"packageName": "@rlx-widgets/pagination",
|
|
799
859
|
"slug": "pagination",
|
|
800
860
|
"category": "widget",
|
|
801
861
|
"sourceCode": "import * as React from \"react\";\nimport { Button, buttonVariants } from \"@rlx-widgets/button\";\nimport { cn } from \"@rlx-widgets/base\";\nimport {\n ChevronLeftIcon,\n ChevronRightIcon,\n MoreHorizontalIcon,\n} from \"lucide-react\";\n\nfunction Pagination({ className, ...props }: React.ComponentProps<\"nav\">) {\n return (\n <nav\n role=\"navigation\"\n aria-label=\"pagination\"\n data-slot=\"pagination\"\n className={cn(\"mx-auto flex w-full justify-center\", className)}\n {...props}\n />\n );\n}\n\nfunction PaginationContent({\n className,\n ...props\n}: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"pagination-content\"\n className={cn(\"flex flex-row items-center gap-1\", className)}\n {...props}\n />\n );\n}\n\nfunction PaginationItem({ ...props }: React.ComponentProps<\"li\">) {\n return <li data-slot=\"pagination-item\" {...props} />;\n}\n\ntype PaginationLinkProps = {\n isActive?: boolean;\n} & Pick<React.ComponentProps<typeof Button>, \"size\"> &\n React.ComponentProps<\"a\">;\n\nfunction PaginationLink({\n className,\n isActive,\n size = \"icon\",\n ...props\n}: PaginationLinkProps) {\n return (\n <a\n aria-current={isActive ? \"page\" : undefined}\n data-slot=\"pagination-link\"\n data-active={isActive}\n className={cn(\n buttonVariants({\n variant: isActive ? \"outline\" : \"ghost\",\n size,\n }),\n className\n )}\n {...props}\n />\n );\n}\n\nfunction PaginationPrevious({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) {\n return (\n <PaginationLink\n aria-label=\"Go to previous page\"\n size=\"default\"\n className={cn(\"gap-1 px-2.5 sm:pl-2.5\", className)}\n {...props}\n >\n <ChevronLeftIcon />\n <span className=\"hidden sm:block\">Previous</span>\n </PaginationLink>\n );\n}\n\nfunction PaginationNext({\n className,\n ...props\n}: React.ComponentProps<typeof PaginationLink>) {\n return (\n <PaginationLink\n aria-label=\"Go to next page\"\n size=\"default\"\n className={cn(\"gap-1 px-2.5 sm:pr-2.5\", className)}\n {...props}\n >\n <span className=\"hidden sm:block\">Next</span>\n <ChevronRightIcon />\n </PaginationLink>\n );\n}\n\nfunction PaginationEllipsis({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n aria-hidden\n data-slot=\"pagination-ellipsis\"\n className={cn(\"flex size-9 items-center justify-center\", className)}\n {...props}\n >\n <MoreHorizontalIcon className=\"size-4\" />\n <span className=\"sr-only\">More pages</span>\n </span>\n );\n}\n\nexport {\n Pagination,\n PaginationContent,\n PaginationLink,\n PaginationItem,\n PaginationPrevious,\n PaginationNext,\n PaginationEllipsis,\n};\n",
|
|
@@ -808,6 +868,8 @@
|
|
|
808
868
|
},
|
|
809
869
|
{
|
|
810
870
|
"name": "Popover",
|
|
871
|
+
"exportName": "Popover",
|
|
872
|
+
"packageName": "@rlx-widgets/popover",
|
|
811
873
|
"slug": "popover",
|
|
812
874
|
"category": "widget",
|
|
813
875
|
"sourceCode": "\"use client\"\n\nimport * as React from \"react\"\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\"\nimport { cn } from \"@rlx-widgets/base\"\n\nfunction Popover({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Root>) {\n return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />\n}\n\nfunction PopoverTrigger({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />\n}\n\nfunction PopoverContent({\n className,\n align = \"center\",\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Content>) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n data-slot=\"popover-content\"\n align={align}\n sideOffset={sideOffset}\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden\",\n className\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n )\n}\n\nfunction PopoverAnchor({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {\n return <PopoverPrimitive.Anchor data-slot=\"popover-anchor\" {...props} />\n}\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }\n",
|
|
@@ -820,6 +882,8 @@
|
|
|
820
882
|
},
|
|
821
883
|
{
|
|
822
884
|
"name": "Progress",
|
|
885
|
+
"exportName": "Progress",
|
|
886
|
+
"packageName": "@rlx-widgets/progress",
|
|
823
887
|
"slug": "progress",
|
|
824
888
|
"category": "widget",
|
|
825
889
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as ProgressPrimitive from \"@radix-ui/react-progress\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction Progress({\n className,\n value,\n ...props\n}: React.ComponentProps<typeof ProgressPrimitive.Root>) {\n return (\n <ProgressPrimitive.Root\n data-slot=\"progress\"\n className={cn(\n \"bg-primary/20 relative h-2 w-full overflow-hidden rounded-full\",\n className\n )}\n {...props}\n >\n <ProgressPrimitive.Indicator\n data-slot=\"progress-indicator\"\n className=\"bg-primary h-full w-full flex-1 transition-all\"\n style={{ transform: `translateX(-${100 - (value || 0)}%)` }}\n />\n </ProgressPrimitive.Root>\n );\n}\n\nexport { Progress };\n",
|
|
@@ -832,6 +896,8 @@
|
|
|
832
896
|
},
|
|
833
897
|
{
|
|
834
898
|
"name": "Radio Group",
|
|
899
|
+
"exportName": "RadioGroup",
|
|
900
|
+
"packageName": "@rlx-widgets/radio-group",
|
|
835
901
|
"slug": "radio-group",
|
|
836
902
|
"category": "widget",
|
|
837
903
|
"sourceCode": "\"use client\";\n\nimport * as RadioGroupPrimitive from \"@radix-ui/react-radio-group\";\nimport * as React from \"react\";\nimport { CircleIcon } from \"lucide-react\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction RadioGroup({\n className,\n ...props\n}: React.ComponentProps<typeof RadioGroupPrimitive.Root>) {\n return (\n <RadioGroupPrimitive.Root\n data-slot=\"radio-group\"\n className={cn(\"grid gap-3\", className)}\n {...props}\n />\n );\n}\n\nfunction RadioGroupItem({\n className,\n ...props\n}: React.ComponentProps<typeof RadioGroupPrimitive.Item>) {\n return (\n <RadioGroupPrimitive.Item\n data-slot=\"radio-group-item\"\n className={cn(\n \"border-input text-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 aspect-square size-4 shrink-0 rounded-full border shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n >\n <RadioGroupPrimitive.Indicator\n data-slot=\"radio-group-indicator\"\n className=\"relative flex items-center justify-center\"\n >\n <CircleIcon className=\"fill-primary absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2\" />\n </RadioGroupPrimitive.Indicator>\n </RadioGroupPrimitive.Item>\n );\n}\n\nexport { RadioGroup, RadioGroupItem };\n",
|
|
@@ -848,6 +914,8 @@
|
|
|
848
914
|
},
|
|
849
915
|
{
|
|
850
916
|
"name": "Resizable",
|
|
917
|
+
"exportName": "Resizable",
|
|
918
|
+
"packageName": "@rlx-widgets/resizable",
|
|
851
919
|
"slug": "resizable",
|
|
852
920
|
"category": "widget",
|
|
853
921
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport { GripVerticalIcon } from \"lucide-react\";\nimport * as ResizablePrimitive from \"react-resizable-panels\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction ResizablePanelGroup({\n className,\n ...props\n}: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) {\n return (\n <ResizablePrimitive.PanelGroup\n data-slot=\"resizable-panel-group\"\n className={cn(\n \"flex h-full w-full data-[panel-group-direction=vertical]:flex-col\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction ResizablePanel({\n ...props\n}: React.ComponentProps<typeof ResizablePrimitive.Panel>) {\n return <ResizablePrimitive.Panel data-slot=\"resizable-panel\" {...props} />;\n}\n\nfunction ResizableHandle({\n withHandle,\n className,\n ...props\n}: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {\n withHandle?: boolean;\n}) {\n return (\n <ResizablePrimitive.PanelResizeHandle\n data-slot=\"resizable-handle\"\n className={cn(\n \"bg-border focus-visible:ring-ring relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:outline-hidden data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:translate-x-0 data-[panel-group-direction=vertical]:after:-translate-y-1/2 [&[data-panel-group-direction=vertical]>div]:rotate-90\",\n className\n )}\n {...props}\n >\n {withHandle && (\n <div className=\"bg-border z-10 flex h-4 w-3 items-center justify-center rounded-xs border\">\n <GripVerticalIcon className=\"size-2.5\" />\n </div>\n )}\n </ResizablePrimitive.PanelResizeHandle>\n );\n}\n\nexport { ResizablePanelGroup, ResizablePanel, ResizableHandle };\n",
|
|
@@ -868,6 +936,8 @@
|
|
|
868
936
|
},
|
|
869
937
|
{
|
|
870
938
|
"name": "Scroll Area",
|
|
939
|
+
"exportName": "ScrollArea",
|
|
940
|
+
"packageName": "@rlx-widgets/scroll-area",
|
|
871
941
|
"slug": "scroll-area",
|
|
872
942
|
"category": "widget",
|
|
873
943
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as ScrollAreaPrimitive from \"@radix-ui/react-scroll-area\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction ScrollArea({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {\n return (\n <ScrollAreaPrimitive.Root\n data-slot=\"scroll-area\"\n className={cn(\"relative\", className)}\n {...props}\n >\n <ScrollAreaPrimitive.Viewport\n data-slot=\"scroll-area-viewport\"\n className=\"focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1\"\n >\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n );\n}\n\nfunction ScrollBar({\n className,\n orientation = \"vertical\",\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {\n return (\n <ScrollAreaPrimitive.ScrollAreaScrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation={orientation}\n className={cn(\n \"flex touch-none p-px transition-colors select-none\",\n orientation === \"vertical\" &&\n \"h-full w-2.5 border-l border-l-transparent\",\n orientation === \"horizontal\" &&\n \"h-2.5 flex-col border-t border-t-transparent\",\n className\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb\n data-slot=\"scroll-area-thumb\"\n className=\"bg-border relative flex-1 rounded-full\"\n />\n </ScrollAreaPrimitive.ScrollAreaScrollbar>\n );\n}\n\nexport { ScrollArea, ScrollBar };\n",
|
|
@@ -884,6 +954,8 @@
|
|
|
884
954
|
},
|
|
885
955
|
{
|
|
886
956
|
"name": "Select",
|
|
957
|
+
"exportName": "Select",
|
|
958
|
+
"packageName": "@rlx-widgets/select",
|
|
887
959
|
"slug": "select",
|
|
888
960
|
"category": "widget",
|
|
889
961
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction Select({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Root>) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />;\n}\n\nfunction SelectGroup({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Group>) {\n return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />;\n}\n\nfunction SelectValue({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Value>) {\n return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />;\n}\n\nfunction SelectTrigger({\n className,\n size = \"default\",\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n size?: \"sm\" | \"default\";\n}) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n data-size={size}\n className={cn(\n \"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon className=\"size-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n );\n}\n\nfunction SelectContent({\n className,\n children,\n position = \"popper\",\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md\",\n position === \"popper\" &&\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n className\n )}\n position={position}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n \"p-1\",\n position === \"popper\" &&\n \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\"\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n );\n}\n\nfunction SelectLabel({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Label>) {\n return (\n <SelectPrimitive.Label\n data-slot=\"select-label\"\n className={cn(\"text-muted-foreground px-2 py-1.5 text-xs\", className)}\n {...props}\n />\n );\n}\n\nfunction SelectItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n className\n )}\n {...props}\n >\n <span className=\"absolute right-2 flex size-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n );\n}\n\nfunction SelectSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n return (\n <SelectPrimitive.Separator\n data-slot=\"select-separator\"\n className={cn(\"bg-border pointer-events-none -mx-1 my-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n return (\n <SelectPrimitive.ScrollUpButton\n data-slot=\"select-scroll-up-button\"\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className\n )}\n {...props}\n >\n <ChevronUpIcon className=\"size-4\" />\n </SelectPrimitive.ScrollUpButton>\n );\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n return (\n <SelectPrimitive.ScrollDownButton\n data-slot=\"select-scroll-down-button\"\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className\n )}\n {...props}\n >\n <ChevronDownIcon className=\"size-4\" />\n </SelectPrimitive.ScrollDownButton>\n );\n}\n\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n};\n",
|
|
@@ -904,6 +976,8 @@
|
|
|
904
976
|
},
|
|
905
977
|
{
|
|
906
978
|
"name": "Separator",
|
|
979
|
+
"exportName": "Separator",
|
|
980
|
+
"packageName": "@rlx-widgets/separator",
|
|
907
981
|
"slug": "separator",
|
|
908
982
|
"category": "widget",
|
|
909
983
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as SeparatorPrimitive from \"@radix-ui/react-separator\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction Separator({\n className,\n orientation = \"horizontal\",\n decorative = true,\n ...props\n}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {\n return (\n <SeparatorPrimitive.Root\n data-slot=\"separator\"\n decorative={decorative}\n orientation={orientation}\n className={cn(\n \"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Separator };\n",
|
|
@@ -916,6 +990,8 @@
|
|
|
916
990
|
},
|
|
917
991
|
{
|
|
918
992
|
"name": "Sheet",
|
|
993
|
+
"exportName": "Sheet",
|
|
994
|
+
"packageName": "@rlx-widgets/sheet",
|
|
919
995
|
"slug": "sheet",
|
|
920
996
|
"category": "widget",
|
|
921
997
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\";\nimport { XIcon } from \"lucide-react\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {\n return <SheetPrimitive.Root data-slot=\"sheet\" {...props} />;\n}\n\nfunction SheetTrigger({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />;\n}\n\nfunction SheetClose({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Close>) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />;\n}\n\nfunction SheetPortal({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Portal>) {\n return <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props} />;\n}\n\nfunction SheetOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Overlay>) {\n return (\n <SheetPrimitive.Overlay\n data-slot=\"sheet-overlay\"\n className={cn(\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SheetContent({\n className,\n children,\n side = \"right\",\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Content> & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n}) {\n return (\n <SheetPortal>\n <SheetOverlay />\n <SheetPrimitive.Content\n data-slot=\"sheet-content\"\n className={cn(\n \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500\",\n side === \"right\" &&\n \"data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm\",\n side === \"left\" &&\n \"data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm\",\n side === \"top\" &&\n \"data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b\",\n side === \"bottom\" &&\n \"data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t\",\n className\n )}\n {...props}\n >\n {children}\n <SheetPrimitive.Close className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none\">\n <XIcon className=\"size-4\" />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n </SheetPrimitive.Content>\n </SheetPortal>\n );\n}\n\nfunction SheetHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn(\"flex flex-col gap-1.5 p-4\", className)}\n {...props}\n />\n );\n}\n\nfunction SheetFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n );\n}\n\nfunction SheetTitle({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Title>) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn(\"text-foreground font-semibold\", className)}\n {...props}\n />\n );\n}\n\nfunction SheetDescription({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Description>) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n};\n",
|
|
@@ -928,12 +1004,16 @@
|
|
|
928
1004
|
},
|
|
929
1005
|
{
|
|
930
1006
|
"name": "Sidebar",
|
|
1007
|
+
"exportName": "Sidebar",
|
|
1008
|
+
"packageName": "@rlx-widgets/sidebar",
|
|
931
1009
|
"slug": "sidebar",
|
|
932
1010
|
"category": "widget",
|
|
933
1011
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport { Button } from \"@rlx-widgets/button\";\nimport { cn } from \"@rlx-widgets/base\";\nimport { cva, VariantProps } from \"class-variance-authority\";\nimport { Input } from \"@rlx-widgets/input\";\nimport { PanelLeftIcon } from \"lucide-react\";\nimport { Separator } from \"@rlx-widgets/separator\";\nimport { Skeleton } from \"@rlx-widgets/skeleton\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { useIsMobile } from \"@rlx-hooks/use-is-mobile\";\nimport {\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n} from \"@rlx-widgets/sheet\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"@rlx-widgets/tooltip\";\n\nconst SIDEBAR_COOKIE_NAME = \"sidebar_state\";\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;\nconst SIDEBAR_WIDTH = \"16rem\";\nconst SIDEBAR_WIDTH_MOBILE = \"18rem\";\nconst SIDEBAR_WIDTH_ICON = \"3rem\";\nconst SIDEBAR_KEYBOARD_SHORTCUT = \"b\";\n\ntype SidebarContextProps = {\n state: \"expanded\" | \"collapsed\";\n open: boolean;\n setOpen: (open: boolean) => void;\n openMobile: boolean;\n setOpenMobile: (open: boolean) => void;\n isMobile: boolean;\n toggleSidebar: () => void;\n};\n\nconst SidebarContext = React.createContext<SidebarContextProps | null>(null);\n\nfunction useSidebar() {\n const context = React.useContext(SidebarContext);\n if (!context) {\n throw new Error(\"useSidebar must be used within a SidebarProvider.\");\n }\n\n return context;\n}\n\nfunction SidebarProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n defaultOpen?: boolean;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}) {\n const isMobile = useIsMobile();\n const [openMobile, setOpenMobile] = React.useState(false);\n\n // This is the internal state of the sidebar.\n // We use openProp and setOpenProp for control from outside the component.\n const [_open, _setOpen] = React.useState(defaultOpen);\n const open = openProp ?? _open;\n const setOpen = React.useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === \"function\" ? value(open) : value;\n if (setOpenProp) {\n setOpenProp(openState);\n } else {\n _setOpen(openState);\n }\n\n // This sets the cookie to keep the sidebar state.\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;\n },\n [setOpenProp, open]\n );\n\n // Helper to toggle the sidebar.\n const toggleSidebar = React.useCallback(() => {\n return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open);\n }, [isMobile, setOpen, setOpenMobile]);\n\n // Adds a keyboard shortcut to toggle the sidebar.\n React.useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (\n event.key === SIDEBAR_KEYBOARD_SHORTCUT &&\n (event.metaKey || event.ctrlKey)\n ) {\n event.preventDefault();\n toggleSidebar();\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [toggleSidebar]);\n\n // We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\n // This makes it easier to style the sidebar with Tailwind classes.\n const state = open ? \"expanded\" : \"collapsed\";\n\n const contextValue = React.useMemo<SidebarContextProps>(\n () => ({\n state,\n open,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n }),\n [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]\n );\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <TooltipProvider delayDuration={0}>\n <div\n data-slot=\"sidebar-wrapper\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH,\n \"--sidebar-width-icon\": SIDEBAR_WIDTH_ICON,\n ...style,\n } as React.CSSProperties\n }\n className={cn(\n \"group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n </TooltipProvider>\n </SidebarContext.Provider>\n );\n}\n\n/**\n * tw v4\n */\nfunction Sidebar({\n side = \"left\",\n variant = \"sidebar\",\n collapsible = \"offcanvas\",\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n side?: \"left\" | \"right\";\n variant?: \"sidebar\" | \"floating\" | \"inset\";\n collapsible?: \"offcanvas\" | \"icon\" | \"none\";\n}) {\n const { isMobile, state, openMobile, setOpenMobile } = useSidebar();\n\n if (collapsible === \"none\") {\n return (\n <div\n data-slot=\"sidebar\"\n className={cn(\n \"bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n );\n }\n\n if (isMobile) {\n return (\n <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>\n <SheetContent\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar\"\n data-mobile=\"true\"\n className=\"bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH_MOBILE,\n } as React.CSSProperties\n }\n side={side}\n >\n <SheetHeader className=\"sr-only\">\n <SheetTitle>Sidebar</SheetTitle>\n <SheetDescription>Displays the mobile sidebar.</SheetDescription>\n </SheetHeader>\n <div className=\"flex h-full w-full flex-col\">{children}</div>\n </SheetContent>\n </Sheet>\n );\n }\n\n return (\n <div\n className=\"group peer text-sidebar-foreground hidden md:block\"\n data-state={state}\n data-collapsible={state === \"collapsed\" ? collapsible : \"\"}\n data-variant={variant}\n data-side={side}\n data-slot=\"sidebar\"\n >\n {/* This is what handles the sidebar gap on desktop */}\n <div\n data-slot=\"sidebar-gap\"\n className={cn(\n \"relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear\",\n \"group-data-[collapsible=offcanvas]:w-0\",\n \"group-data-[side=right]:rotate-180\",\n variant === \"floating\" || variant === \"inset\"\n ? \"group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon)\"\n )}\n />\n <div\n data-slot=\"sidebar-container\"\n className={cn(\n \"fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex\",\n side === \"left\"\n ? \"left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]\"\n : \"right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]\",\n // Adjust the padding for floating and inset variants.\n variant === \"floating\" || variant === \"inset\"\n ? \"p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l\",\n className\n )}\n {...props}\n >\n <div\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar-inner\"\n className=\"bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm\"\n >\n {children}\n </div>\n </div>\n </div>\n );\n}\n\nfunction SidebarTrigger({\n className,\n onClick,\n ...props\n}: React.ComponentProps<typeof Button>) {\n const { toggleSidebar } = useSidebar();\n\n return (\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"size-7\", className)}\n onClick={(event) => {\n onClick?.(event);\n toggleSidebar();\n }}\n {...props}\n >\n <PanelLeftIcon />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n );\n}\n\nfunction SidebarRail({ className, ...props }: React.ComponentProps<\"button\">) {\n const { toggleSidebar } = useSidebar();\n\n return (\n <button\n data-sidebar=\"rail\"\n data-slot=\"sidebar-rail\"\n aria-label=\"Toggle Sidebar\"\n tabIndex={-1}\n onClick={toggleSidebar}\n title=\"Toggle Sidebar\"\n className={cn(\n \"hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex\",\n \"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize\",\n \"[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize\",\n \"hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full\",\n \"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2\",\n \"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarInset({ className, ...props }: React.ComponentProps<\"main\">) {\n return (\n <main\n data-slot=\"sidebar-inset\"\n className={cn(\n \"bg-background relative flex w-full flex-1 flex-col\",\n \"md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarInput({\n className,\n ...props\n}: React.ComponentProps<typeof Input>) {\n return (\n <Input\n data-slot=\"sidebar-input\"\n data-sidebar=\"input\"\n className={cn(\"bg-background h-8 w-full shadow-none\", className)}\n {...props}\n />\n );\n}\n\nfunction SidebarHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-header\"\n data-sidebar=\"header\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n );\n}\n\nfunction SidebarFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-footer\"\n data-sidebar=\"footer\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n );\n}\n\nfunction SidebarSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof Separator>) {\n return (\n <Separator\n data-slot=\"sidebar-separator\"\n data-sidebar=\"separator\"\n className={cn(\"bg-sidebar-border mx-2 w-auto\", className)}\n {...props}\n />\n );\n}\n\nfunction SidebarContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-content\"\n data-sidebar=\"content\"\n className={cn(\n \"flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group\"\n data-sidebar=\"group\"\n className={cn(\"relative flex w-full min-w-0 flex-col p-2\", className)}\n {...props}\n />\n );\n}\n\nfunction SidebarGroupLabel({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<\"div\"> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : \"div\";\n\n return (\n <Comp\n data-slot=\"sidebar-group-label\"\n data-sidebar=\"group-label\"\n className={cn(\n \"text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n \"group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarGroupAction({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : \"button\";\n\n return (\n <Comp\n data-slot=\"sidebar-group-action\"\n data-sidebar=\"group-action\"\n className={cn(\n \"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n // Increases the hit area of the button on mobile.\n \"after:absolute after:-inset-2 md:after:hidden\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarGroupContent({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group-content\"\n data-sidebar=\"group-content\"\n className={cn(\"w-full text-sm\", className)}\n {...props}\n />\n );\n}\n\nfunction SidebarMenu({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu\"\n data-sidebar=\"menu\"\n className={cn(\"flex w-full min-w-0 flex-col gap-1\", className)}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuItem({ className, ...props }: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-item\"\n data-sidebar=\"menu-item\"\n className={cn(\"group/menu-item relative\", className)}\n {...props}\n />\n );\n}\n\nconst sidebarMenuButtonVariants = cva(\n \"peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: \"hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n outline:\n \"bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]\",\n },\n size: {\n default: \"h-8 text-sm\",\n sm: \"h-7 text-xs\",\n lg: \"h-12 text-sm group-data-[collapsible=icon]:p-0!\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n);\n\nfunction SidebarMenuButton({\n asChild = false,\n isActive = false,\n variant = \"default\",\n size = \"default\",\n tooltip,\n className,\n ...props\n}: React.ComponentProps<\"button\"> & {\n asChild?: boolean;\n isActive?: boolean;\n tooltip?: string | React.ComponentProps<typeof TooltipContent>;\n} & VariantProps<typeof sidebarMenuButtonVariants>) {\n const Comp = asChild ? Slot : \"button\";\n const { isMobile, state } = useSidebar();\n\n const button = (\n <Comp\n data-slot=\"sidebar-menu-button\"\n data-sidebar=\"menu-button\"\n data-size={size}\n data-active={isActive}\n className={cn(sidebarMenuButtonVariants({ variant, size }), className)}\n {...props}\n />\n );\n\n if (!tooltip) {\n return button;\n }\n\n if (typeof tooltip === \"string\") {\n tooltip = {\n children: tooltip,\n };\n }\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent\n side=\"right\"\n align=\"center\"\n hidden={state !== \"collapsed\" || isMobile}\n {...tooltip}\n />\n </Tooltip>\n );\n}\n\nfunction SidebarMenuAction({\n className,\n asChild = false,\n showOnHover = false,\n ...props\n}: React.ComponentProps<\"button\"> & {\n asChild?: boolean;\n showOnHover?: boolean;\n}) {\n const Comp = asChild ? Slot : \"button\";\n\n return (\n <Comp\n data-slot=\"sidebar-menu-action\"\n data-sidebar=\"menu-action\"\n className={cn(\n \"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n // Increases the hit area of the button on mobile.\n \"after:absolute after:-inset-2 md:after:hidden\",\n \"peer-data-[size=sm]/menu-button:top-1\",\n \"peer-data-[size=default]/menu-button:top-1.5\",\n \"peer-data-[size=lg]/menu-button:top-2.5\",\n \"group-data-[collapsible=icon]:hidden\",\n showOnHover &&\n \"peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuBadge({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-menu-badge\"\n data-sidebar=\"menu-badge\"\n className={cn(\n \"text-sidebar-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none\",\n \"peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground\",\n \"peer-data-[size=sm]/menu-button:top-1\",\n \"peer-data-[size=default]/menu-button:top-1.5\",\n \"peer-data-[size=lg]/menu-button:top-2.5\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuSkeleton({\n className,\n showIcon = false,\n ...props\n}: React.ComponentProps<\"div\"> & {\n showIcon?: boolean;\n}) {\n // Random width between 50 to 90%.\n const width = React.useMemo(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`;\n }, []);\n\n return (\n <div\n data-slot=\"sidebar-menu-skeleton\"\n data-sidebar=\"menu-skeleton\"\n className={cn(\"flex h-8 items-center gap-2 rounded-md px-2\", className)}\n {...props}\n >\n {showIcon && (\n <Skeleton\n className=\"size-4 rounded-md\"\n data-sidebar=\"menu-skeleton-icon\"\n />\n )}\n <Skeleton\n className=\"h-4 max-w-(--skeleton-width) flex-1\"\n data-sidebar=\"menu-skeleton-text\"\n style={\n {\n \"--skeleton-width\": width,\n } as React.CSSProperties\n }\n />\n </div>\n );\n}\n\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu-sub\"\n data-sidebar=\"menu-sub\"\n className={cn(\n \"border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuSubItem({\n className,\n ...props\n}: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-sub-item\"\n data-sidebar=\"menu-sub-item\"\n className={cn(\"group/menu-sub-item relative\", className)}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuSubButton({\n asChild = false,\n size = \"md\",\n isActive = false,\n className,\n ...props\n}: React.ComponentProps<\"a\"> & {\n asChild?: boolean;\n size?: \"sm\" | \"md\";\n isActive?: boolean;\n}) {\n const Comp = asChild ? Slot : \"a\";\n\n return (\n <Comp\n data-slot=\"sidebar-menu-sub-button\"\n data-sidebar=\"menu-sub-button\"\n data-size={size}\n data-active={isActive}\n className={cn(\n \"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0\",\n \"data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground\",\n size === \"sm\" && \"text-xs\",\n size === \"md\" && \"text-sm\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInput,\n SidebarInset,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarProvider,\n SidebarRail,\n SidebarSeparator,\n SidebarTrigger,\n useSidebar,\n};\n"
|
|
934
1012
|
},
|
|
935
1013
|
{
|
|
936
1014
|
"name": "Skeleton",
|
|
1015
|
+
"exportName": "Skeleton",
|
|
1016
|
+
"packageName": "@rlx-widgets/skeleton",
|
|
937
1017
|
"slug": "skeleton",
|
|
938
1018
|
"category": "widget",
|
|
939
1019
|
"sourceCode": "import { cn } from \"@rlx-widgets/base\";\n\nfunction Skeleton({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"skeleton\"\n className={cn(\"bg-accent animate-pulse rounded-md\", className)}\n {...props}\n />\n );\n}\n\nexport { Skeleton };\n",
|
|
@@ -946,6 +1026,8 @@
|
|
|
946
1026
|
},
|
|
947
1027
|
{
|
|
948
1028
|
"name": "Slider",
|
|
1029
|
+
"exportName": "Slider",
|
|
1030
|
+
"packageName": "@rlx-widgets/slider",
|
|
949
1031
|
"slug": "slider",
|
|
950
1032
|
"category": "widget",
|
|
951
1033
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as SliderPrimitive from \"@radix-ui/react-slider\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction Slider({\n className,\n defaultValue,\n value,\n min = 0,\n max = 100,\n ...props\n}: React.ComponentProps<typeof SliderPrimitive.Root>) {\n const _values = React.useMemo(\n () =>\n Array.isArray(value)\n ? value\n : Array.isArray(defaultValue)\n ? defaultValue\n : [min, max],\n [value, defaultValue, min, max]\n );\n\n return (\n <SliderPrimitive.Root\n data-slot=\"slider\"\n defaultValue={defaultValue}\n value={value}\n min={min}\n max={max}\n className={cn(\n \"relative flex w-full touch-none items-center select-none data-[disabled]:opacity-50 data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col\",\n className\n )}\n {...props}\n >\n <SliderPrimitive.Track\n data-slot=\"slider-track\"\n className={cn(\n \"bg-muted relative grow overflow-hidden rounded-full data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5\"\n )}\n >\n <SliderPrimitive.Range\n data-slot=\"slider-range\"\n className={cn(\n \"bg-primary absolute data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full\"\n )}\n />\n </SliderPrimitive.Track>\n {Array.from({ length: _values.length }, (_, index) => (\n <SliderPrimitive.Thumb\n data-slot=\"slider-thumb\"\n key={index}\n className=\"border-primary bg-background ring-ring/50 block size-4 shrink-0 rounded-full border shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50\"\n />\n ))}\n </SliderPrimitive.Root>\n );\n}\n\nexport { Slider };\n",
|
|
@@ -956,19 +1038,10 @@
|
|
|
956
1038
|
}
|
|
957
1039
|
]
|
|
958
1040
|
},
|
|
959
|
-
{
|
|
960
|
-
"name": "Sonner",
|
|
961
|
-
"slug": "sonner",
|
|
962
|
-
"category": "widget",
|
|
963
|
-
"demos": [
|
|
964
|
-
{
|
|
965
|
-
"name": "default",
|
|
966
|
-
"code": "\"use client\";\n\nimport { toast, Toaster } from \"sonner\";\n\nimport { Button } from \"@rlx-widgets/button\";\nimport { useTheme } from \"@rlx-widgets/base\";\n\nexport const Preview = () => {\n const themeContext = useTheme();\n const theme = themeContext.theme;\n return (\n <div>\n <Toaster\n theme={theme}\n toastOptions={{\n style: {\n background: \"var(--color-muted)\",\n border: \"var(--color-border)\",\n },\n }}\n position=\"top-center\"\n />\n <Button\n variant=\"outline\"\n onClick={() =>\n toast(\"Event has been created\", {\n description: \"Sunday, December 03, 2023 at 9:00 AM\",\n action: {\n label: \"Undo\",\n onClick: () => console.log(\"Undo\"),\n },\n })\n }\n >\n Show Toast\n </Button>\n </div>\n );\n};\n"
|
|
967
|
-
}
|
|
968
|
-
]
|
|
969
|
-
},
|
|
970
1041
|
{
|
|
971
1042
|
"name": "Spinner",
|
|
1043
|
+
"exportName": "Spinner",
|
|
1044
|
+
"packageName": "@rlx-widgets/spinner",
|
|
972
1045
|
"slug": "spinner",
|
|
973
1046
|
"category": "widget",
|
|
974
1047
|
"sourceCode": "import { cn } from \"@rlx-widgets/base\";\nimport { Loader2Icon } from \"lucide-react\";\n\nexport const Spinner = ({\n className,\n ...props\n}: React.ComponentProps<\"svg\">) => {\n return (\n <Loader2Icon\n role=\"status\"\n aria-label=\"Loading\"\n className={cn(\"size-4 animate-spin\", className)}\n {...props}\n />\n );\n};\n",
|
|
@@ -1013,6 +1086,8 @@
|
|
|
1013
1086
|
},
|
|
1014
1087
|
{
|
|
1015
1088
|
"name": "Switch",
|
|
1089
|
+
"exportName": "Switch",
|
|
1090
|
+
"packageName": "@rlx-widgets/switch",
|
|
1016
1091
|
"slug": "switch",
|
|
1017
1092
|
"category": "widget",
|
|
1018
1093
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as SwitchPrimitive from \"@radix-ui/react-switch\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction Switch({\n className,\n ...props\n}: React.ComponentProps<typeof SwitchPrimitive.Root>) {\n return (\n <SwitchPrimitive.Root\n data-slot=\"switch\"\n className={cn(\n \"peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 inline-flex h-[1.15rem] w-8 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n >\n <SwitchPrimitive.Thumb\n data-slot=\"switch-thumb\"\n className={cn(\n \"bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block size-4 rounded-full ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0\"\n )}\n />\n </SwitchPrimitive.Root>\n );\n}\n\nexport { Switch };\n",
|
|
@@ -1029,6 +1104,8 @@
|
|
|
1029
1104
|
},
|
|
1030
1105
|
{
|
|
1031
1106
|
"name": "Table",
|
|
1107
|
+
"exportName": "Table",
|
|
1108
|
+
"packageName": "@rlx-widgets/table",
|
|
1032
1109
|
"slug": "table",
|
|
1033
1110
|
"category": "widget",
|
|
1034
1111
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction Table({ className, ...props }: React.ComponentProps<\"table\">) {\n return (\n <div\n data-slot=\"table-container\"\n className=\"relative w-full overflow-x-auto\"\n >\n <table\n data-slot=\"table\"\n className={cn(\"w-full caption-bottom text-sm\", className)}\n {...props}\n />\n </div>\n );\n}\n\nfunction TableHeader({ className, ...props }: React.ComponentProps<\"thead\">) {\n return (\n <thead\n data-slot=\"table-header\"\n className={cn(\"[&_tr]:border-b\", className)}\n {...props}\n />\n );\n}\n\nfunction TableBody({ className, ...props }: React.ComponentProps<\"tbody\">) {\n return (\n <tbody\n data-slot=\"table-body\"\n className={cn(\"[&_tr:last-child]:border-0\", className)}\n {...props}\n />\n );\n}\n\nfunction TableFooter({ className, ...props }: React.ComponentProps<\"tfoot\">) {\n return (\n <tfoot\n data-slot=\"table-footer\"\n className={cn(\n \"bg-muted/50 border-t font-medium [&>tr]:last:border-b-0\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction TableRow({ className, ...props }: React.ComponentProps<\"tr\">) {\n return (\n <tr\n data-slot=\"table-row\"\n className={cn(\n \"hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction TableHead({ className, ...props }: React.ComponentProps<\"th\">) {\n return (\n <th\n data-slot=\"table-head\"\n className={cn(\n \"text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction TableCell({ className, ...props }: React.ComponentProps<\"td\">) {\n return (\n <td\n data-slot=\"table-cell\"\n className={cn(\n \"p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction TableCaption({\n className,\n ...props\n}: React.ComponentProps<\"caption\">) {\n return (\n <caption\n data-slot=\"table-caption\"\n className={cn(\"text-muted-foreground mt-4 text-sm\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n};\n",
|
|
@@ -1041,6 +1118,8 @@
|
|
|
1041
1118
|
},
|
|
1042
1119
|
{
|
|
1043
1120
|
"name": "Tabs",
|
|
1121
|
+
"exportName": "Tabs",
|
|
1122
|
+
"packageName": "@rlx-widgets/tabs",
|
|
1044
1123
|
"slug": "tabs",
|
|
1045
1124
|
"category": "widget",
|
|
1046
1125
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as TabsPrimitive from \"@radix-ui/react-tabs\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction Tabs({\n className,\n ...props\n}: React.ComponentProps<typeof TabsPrimitive.Root>) {\n return (\n <TabsPrimitive.Root\n data-slot=\"tabs\"\n className={cn(\"flex flex-col gap-2\", className)}\n {...props}\n />\n );\n}\n\nfunction TabsList({\n className,\n ...props\n}: React.ComponentProps<typeof TabsPrimitive.List>) {\n return (\n <TabsPrimitive.List\n data-slot=\"tabs-list\"\n className={cn(\n \"bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction TabsTrigger({\n className,\n ...props\n}: React.ComponentProps<typeof TabsPrimitive.Trigger>) {\n return (\n <TabsPrimitive.Trigger\n data-slot=\"tabs-trigger\"\n className={cn(\n \"data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction TabsContent({\n className,\n ...props\n}: React.ComponentProps<typeof TabsPrimitive.Content>) {\n return (\n <TabsPrimitive.Content\n data-slot=\"tabs-content\"\n className={cn(\"flex-1 outline-none\", className)}\n {...props}\n />\n );\n}\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent };\n",
|
|
@@ -1053,6 +1132,8 @@
|
|
|
1053
1132
|
},
|
|
1054
1133
|
{
|
|
1055
1134
|
"name": "Textarea",
|
|
1135
|
+
"exportName": "Textarea",
|
|
1136
|
+
"packageName": "@rlx-widgets/textarea",
|
|
1056
1137
|
"slug": "textarea",
|
|
1057
1138
|
"category": "widget",
|
|
1058
1139
|
"sourceCode": "import * as React from \"react\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n return (\n <textarea\n data-slot=\"textarea\"\n className={cn(\n \"border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Textarea };\n",
|
|
@@ -1065,6 +1146,8 @@
|
|
|
1065
1146
|
},
|
|
1066
1147
|
{
|
|
1067
1148
|
"name": "Toggle",
|
|
1149
|
+
"exportName": "Toggle",
|
|
1150
|
+
"packageName": "@rlx-widgets/toggle",
|
|
1068
1151
|
"slug": "toggle",
|
|
1069
1152
|
"category": "widget",
|
|
1070
1153
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@rlx-widgets/base\";\n\nconst toggleVariants = cva(\n \"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap\",\n {\n variants: {\n variant: {\n default: \"bg-transparent\",\n outline:\n \"border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground\",\n },\n size: {\n default: \"h-9 px-2 min-w-9\",\n sm: \"h-8 px-1.5 min-w-8\",\n lg: \"h-10 px-2.5 min-w-10\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n);\n\nfunction Toggle({\n className,\n variant,\n size,\n ...props\n}: React.ComponentProps<typeof TogglePrimitive.Root> &\n VariantProps<typeof toggleVariants>) {\n return (\n <TogglePrimitive.Root\n data-slot=\"toggle\"\n className={cn(toggleVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nexport { Toggle, toggleVariants };\n",
|
|
@@ -1097,6 +1180,8 @@
|
|
|
1097
1180
|
},
|
|
1098
1181
|
{
|
|
1099
1182
|
"name": "Toggle Group",
|
|
1183
|
+
"exportName": "ToggleGroup",
|
|
1184
|
+
"packageName": "@rlx-widgets/toggle-group",
|
|
1100
1185
|
"slug": "toggle-group",
|
|
1101
1186
|
"category": "widget",
|
|
1102
1187
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as ToggleGroupPrimitive from \"@radix-ui/react-toggle-group\";\nimport { cn } from \"@rlx-widgets/base\";\nimport { toggleVariants } from \"@rlx-widgets/toggle\";\nimport { type VariantProps } from \"class-variance-authority\";\n\nconst ToggleGroupContext = React.createContext<\n VariantProps<typeof toggleVariants>\n>({\n size: \"default\",\n variant: \"default\",\n});\n\nfunction ToggleGroup({\n className,\n variant,\n size,\n children,\n ...props\n}: React.ComponentProps<typeof ToggleGroupPrimitive.Root> &\n VariantProps<typeof toggleVariants>) {\n return (\n <ToggleGroupPrimitive.Root\n data-slot=\"toggle-group\"\n data-variant={variant}\n data-size={size}\n className={cn(\n \"group/toggle-group flex w-fit items-center rounded-md data-[variant=outline]:shadow-xs\",\n className\n )}\n {...props}\n >\n <ToggleGroupContext.Provider value={{ variant, size }}>\n {children}\n </ToggleGroupContext.Provider>\n </ToggleGroupPrimitive.Root>\n );\n}\n\nfunction ToggleGroupItem({\n className,\n children,\n variant,\n size,\n ...props\n}: React.ComponentProps<typeof ToggleGroupPrimitive.Item> &\n VariantProps<typeof toggleVariants>) {\n const context = React.useContext(ToggleGroupContext);\n\n return (\n <ToggleGroupPrimitive.Item\n data-slot=\"toggle-group-item\"\n data-variant={context.variant || variant}\n data-size={context.size || size}\n className={cn(\n toggleVariants({\n variant: context.variant || variant,\n size: context.size || size,\n }),\n \"min-w-0 flex-1 shrink-0 rounded-none shadow-none first:rounded-l-md last:rounded-r-md focus:z-10 focus-visible:z-10 data-[variant=outline]:border-l-0 data-[variant=outline]:first:border-l\",\n className\n )}\n {...props}\n >\n {children}\n </ToggleGroupPrimitive.Item>\n );\n}\n\nexport { ToggleGroup, ToggleGroupItem };\n",
|
|
@@ -1129,6 +1214,8 @@
|
|
|
1129
1214
|
},
|
|
1130
1215
|
{
|
|
1131
1216
|
"name": "Tooltip",
|
|
1217
|
+
"exportName": "Tooltip",
|
|
1218
|
+
"packageName": "@rlx-widgets/tooltip",
|
|
1132
1219
|
"slug": "tooltip",
|
|
1133
1220
|
"category": "widget",
|
|
1134
1221
|
"sourceCode": "\"use client\";\n\nimport * as React from \"react\";\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\nimport { cn } from \"@rlx-widgets/base\";\n\nfunction TooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n );\n}\n\nfunction Tooltip({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return (\n <TooltipProvider>\n <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n </TooltipProvider>\n );\n}\n\nfunction TooltipTrigger({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance\",\n className\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\n",
|
|
@@ -1141,6 +1228,8 @@
|
|
|
1141
1228
|
},
|
|
1142
1229
|
{
|
|
1143
1230
|
"name": "Typography",
|
|
1231
|
+
"exportName": "Typography",
|
|
1232
|
+
"packageName": "@rlx-widgets/typography",
|
|
1144
1233
|
"slug": "typography",
|
|
1145
1234
|
"category": "widget",
|
|
1146
1235
|
"sourceCode": "import { cn } from \"@rlx-widgets/base\";\nimport { FC, HTMLAttributes } from \"react\";\n\nexport function Heading1({\n children,\n className,\n}: {\n children: React.ReactNode;\n className?: string;\n}) {\n return (\n <h1\n className={cn(\n \"scroll-m-20 text-4xl font-extrabold text-balance\",\n className\n )}\n >\n {children}\n </h1>\n );\n}\n\nexport function Heading2({\n children,\n className,\n}: {\n children: React.ReactNode;\n className?: string;\n}) {\n return (\n <h2\n className={cn(\"scroll-m-20 text-3xl font-semibold first:mt-0\", className)}\n >\n {children}\n </h2>\n );\n}\n\nexport function Heading3({\n children,\n className,\n}: {\n children: React.ReactNode;\n className?: string;\n}) {\n return (\n <h3 className={cn(\"scroll-m-20 text-2xl font-semibold\", className)}>\n {children}\n </h3>\n );\n}\n\nexport function Heading4({\n children,\n className,\n}: {\n children: React.ReactNode;\n className?: string;\n}) {\n return (\n <h4 className={cn(\"scroll-m-20 text-xl font-semibold\", className)}>\n {children}\n </h4>\n );\n}\n\nexport function Heading5({\n children,\n className,\n}: {\n children: React.ReactNode;\n className?: string;\n}) {\n return (\n <h4 className={cn(\"scroll-m-20 text-lg font-semibold\", className)}>\n {children}\n </h4>\n );\n}\n\nexport function Heading6({\n children,\n className,\n}: {\n children: React.ReactNode;\n className?: string;\n}) {\n return (\n <h4 className={cn(\"scroll-m-20 text-base font-semibold\", className)}>\n {children}\n </h4>\n );\n}\n\nexport function Paragraph({\n children,\n className,\n}: {\n children: React.ReactNode;\n className?: string;\n}) {\n return <p className={cn(\"leading-7\", className)}>{children}</p>;\n}\n\nexport const Blockquote: FC<HTMLAttributes<HTMLQuoteElement>> = ({\n children,\n className,\n ...props\n}) => {\n return (\n <blockquote\n className={cn(\"mt-6 border-l-2 pl-6 italic\", className)}\n {...props}\n >\n {children}\n </blockquote>\n );\n};\n",
|
|
@@ -1155,6 +1244,8 @@
|
|
|
1155
1244
|
"components": [
|
|
1156
1245
|
{
|
|
1157
1246
|
"name": "Blur Reveal",
|
|
1247
|
+
"exportName": "BlurReveal",
|
|
1248
|
+
"packageName": "@rlx-components/blur-reveal",
|
|
1158
1249
|
"slug": "blur-reveal",
|
|
1159
1250
|
"category": "component",
|
|
1160
1251
|
"sourceCode": "\"use client\";\n\nimport { cva, VariantProps } from \"class-variance-authority\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { useState, MouseEvent, useEffect } from \"react\";\nimport { cn } from \"@rlx-widgets/base\";\n\nconst blurRevealVariants = cva(\n \"transition-all duration-100 cursor-pointer select-none\",\n {\n variants: {\n blur: {\n extraSmall: \"blur-xs\",\n small: \"blur-sm\",\n medium: \"blur-md\",\n large: \"blur-lg\",\n extraLarge: \"blur-2xl\",\n },\n },\n defaultVariants: {\n blur: \"extraSmall\",\n },\n }\n);\n\nconst BlurReveal = ({\n blur,\n children,\n className,\n asChild,\n onClick,\n reveal = false,\n ...props\n}: React.ComponentProps<\"div\"> &\n VariantProps<typeof blurRevealVariants> & {\n asChild?: boolean;\n reveal?: boolean;\n }) => {\n const [showBlur, setShowBlur] = useState(!reveal);\n const Comp = asChild ? Slot : \"div\";\n\n useEffect(() => {\n setShowBlur(!reveal);\n }, [reveal]);\n\n const handleClick = (e: MouseEvent<HTMLDivElement>) => {\n if (onClick) {\n onClick?.(e);\n return;\n }\n setShowBlur(false);\n };\n\n return (\n <Comp\n className={cn(\n blurRevealVariants({ blur, className }),\n !showBlur && \"blur-none cursor-auto select-auto\"\n )}\n onClick={handleClick}\n {...props}\n >\n {children}\n </Comp>\n );\n};\n\nexport { BlurReveal, blurRevealVariants };\n",
|
|
@@ -1175,6 +1266,8 @@
|
|
|
1175
1266
|
},
|
|
1176
1267
|
{
|
|
1177
1268
|
"name": "Code Preview Tabs",
|
|
1269
|
+
"exportName": "CodePreviewTabs",
|
|
1270
|
+
"packageName": "@rlx-components/code-preview-tabs",
|
|
1178
1271
|
"slug": "code-preview-tabs",
|
|
1179
1272
|
"category": "component",
|
|
1180
1273
|
"sourceCode": "\"use client\";\n\nimport { cn } from \"@rlx-widgets/base\";\nimport { CodePreviewTabsProps, PreviewVariants, TabType } from \"./types\";\nimport { ShikiCodeBlock } from \"@rlx-components/shiki-code-block\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"@rlx-widgets/tabs\";\nimport { TabTypeEnum } from \"./enums\";\nimport { useMemo, useState } from \"react\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@rlx-widgets/select\";\n\nconst defaultClassNames = {};\n\nexport const CodePreviewTabs = ({\n variants: variantsProp,\n preview,\n code,\n classNames = defaultClassNames,\n lang = \"tsx\",\n}: CodePreviewTabsProps) => {\n const variants = useMemo(() => {\n return variantsProp || { Default: { preview, code } };\n }, [variantsProp, preview, code]);\n\n const [value, setValue] = useState<TabType>(\"preview\");\n const [variant, setVariant] = useState<string>(Object.keys(variants)[0]);\n\n const handleValueChange = (newValue: string) => {\n setValue(newValue as TabType);\n };\n\n return (\n <Tabs\n value={value}\n onValueChange={handleValueChange}\n className=\"relative mt-6 w-full\"\n >\n <div className=\"flex items-center justify-between\">\n <TabsList>\n <TabsTrigger value={TabTypeEnum.PREVIEW}>Preview</TabsTrigger>\n <TabsTrigger value={TabTypeEnum.CODE}>Code</TabsTrigger>\n </TabsList>\n {Object.keys(variants).length > 1 && (\n <Select\n onValueChange={setVariant}\n defaultValue={Object.keys(variants)[0]}\n value={variant}\n >\n <SelectTrigger>\n <SelectValue placeholder=\"Default\" />\n </SelectTrigger>\n <SelectContent>\n {Object.keys(variants).map((variant) => (\n <SelectItem key={variant} value={variant}>\n {variant}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n </div>\n\n <TabsContent value={TabTypeEnum.PREVIEW}>\n <div\n className={cn(\"rounded-md border p-14 h-[400px]\", classNames.preview)}\n >\n <Preview variant={variant} variants={variants} />\n </div>\n </TabsContent>\n\n <TabsContent value={TabTypeEnum.CODE}>\n <ShikiCodeBlock\n code={variants[variant].code}\n lang={lang}\n className={classNames.code}\n />\n </TabsContent>\n </Tabs>\n );\n};\n\nconst Preview = ({\n variant,\n variants,\n}: {\n variant: string;\n variants: PreviewVariants;\n}) => {\n if (typeof variants[variant].preview !== \"function\") {\n return <>{variants[variant].preview}</>;\n }\n\n const Component = variants[variant].preview;\n\n return <Component />;\n};\n",
|
|
@@ -1198,6 +1291,8 @@
|
|
|
1198
1291
|
},
|
|
1199
1292
|
{
|
|
1200
1293
|
"name": "Shiki Code Block",
|
|
1294
|
+
"exportName": "ShikiCodeBlock",
|
|
1295
|
+
"packageName": "@rlx-components/shiki-code-block",
|
|
1201
1296
|
"slug": "shiki-code-block",
|
|
1202
1297
|
"category": "component",
|
|
1203
1298
|
"sourceCode": "\"use client\";\n\nimport { JSX, useLayoutEffect, useState } from \"react\";\nimport { highlight } from \"./utils\";\nimport { Button } from \"@rlx-widgets/button\";\nimport { cn } from \"@rlx-widgets/base\";\nimport { BundledLanguage } from \"shiki/bundle/web\";\nimport { Copy } from \"lucide-react\";\n\nexport const ShikiCodeBlock = ({\n code,\n lang,\n className,\n}: {\n code: string;\n lang: BundledLanguage;\n className?: string;\n}) => {\n const [onHover, setOnHover] = useState(false);\n const [highlightedCode, setHighlightedCode] = useState<JSX.Element>();\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n };\n\n useLayoutEffect(() => {\n void highlight({\n code,\n lang,\n className: cn(\"h-[400px]\", className),\n }).then(setHighlightedCode);\n }, [className, code, lang]);\n\n return (\n <div\n onMouseEnter={() => setOnHover(true)}\n onMouseLeave={() => setOnHover(false)}\n >\n <div className=\"relative\">\n <div>{highlightedCode ?? <p>Loading...</p>}</div>\n <span\n className={cn(\n \"absolute top-[8px] right-[16px]\",\n \"text-xs\",\n onHover && \"hidden\"\n )}\n >\n {lang}\n </span>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleCopy}\n className={cn(\n \"absolute top-[8px] right-[16px]\",\n \"cursor-pointer\",\n !onHover && \"hidden\"\n )}\n >\n <Copy /> {copied ? \"Copied!\" : \"Copy\"}\n </Button>\n </div>\n </div>\n );\n};\n",
|
|
@@ -1213,6 +1308,8 @@
|
|
|
1213
1308
|
},
|
|
1214
1309
|
{
|
|
1215
1310
|
"name": "Stacked Cards",
|
|
1311
|
+
"exportName": "StackedCards",
|
|
1312
|
+
"packageName": "@rlx-components/stacked-cards",
|
|
1216
1313
|
"slug": "stacked-cards",
|
|
1217
1314
|
"category": "component",
|
|
1218
1315
|
"sourceCode": "\"use client\";\n\nimport { cn } from \"@rlx-widgets/base\";\nimport StackedCard from \"./StackedCard\";\nimport { Code } from \"lucide-react\";\nimport {\n MouseEventHandler,\n ReactNode,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { parseTranslate } from \"../../utils\";\n\nconst DEFAULT_TRANSFORM = \"rotateX(60deg) rotateY(0deg) rotateZ(-30deg)\";\nconst HOVERED_TRANSFORM = \"rotateX(0deg) rotateY(0deg) rotateZ(0deg)\";\n\nconst HOVERED_TRANSLATE = \"calc(-50% - 20px) 0px 50px\";\nconst getDefaultTranslate = (index: number) => {\n return `-50% ${index * 4}px -200px`;\n};\n\nconst parseRotationValues = (transform: string): [number, number, number] => {\n const xMatch = transform.match(/rotateX\\(([-\\d.]+)deg\\)/);\n const yMatch = transform.match(/rotateY\\(([-\\d.]+)deg\\)/);\n const zMatch = transform.match(/rotateZ\\(([-\\d.]+)deg\\)/);\n\n return [\n xMatch ? parseFloat(xMatch[1]) : 0,\n yMatch ? parseFloat(yMatch[1]) : 0,\n zMatch ? parseFloat(zMatch[1]) : 0,\n ];\n};\n\nconst mDown = (translate: string, distance: number) => {\n const { x, y: _y, z } = parseTranslate(translate);\n const y = _y.replace(\"px\", \"\");\n\n return `${x} ${+y + distance}px ${z}`;\n};\n\nconst rX = (transform: string, angle: number) => {\n const [x, y, z] = parseRotationValues(transform);\n return `rotateX(${x + angle}deg) rotateY(${y}deg) rotateZ(${z}deg)`;\n};\n\nexport const StackedCards = ({\n items: _items,\n onAnimationEnd,\n classNames: _classNames,\n}: {\n items: Array<{\n id?: string;\n icon: ReactNode;\n text: string;\n }>;\n onAnimationEnd?: (id: string) => void;\n classNames?: {\n root?: string;\n card?: string;\n };\n}) => {\n const [items, setItems] = useState(_items);\n const [isHovered, setIsHovered] = useState(false);\n const [isHoveredOnCard, setIsHoveredOnCard] = useState(false);\n const [isAnimating, setIsAnimating] = useState(false);\n const cardRefs = useRef<Array<HTMLDivElement | null>>([]);\n\n const handleClick: MouseEventHandler<HTMLDivElement> = async (e) => {\n e.stopPropagation();\n const $card = cardRefs.current[0];\n if (!$card) {\n return;\n }\n const cardId = $card.getAttribute(\"data-id\") || \"\";\n if (isAnimating) {\n $card.getAnimations().forEach((animation) => animation.finish());\n onAnimationEnd?.(cardId);\n } else {\n setIsAnimating(true);\n const animation = await $card.animate(\n [\n {\n translate: $card.style.translate,\n transform: $card.style.transform,\n },\n {\n translate: mDown($card.style.translate, 100),\n },\n {\n translate: mDown(mDown($card.style.translate, 100), 50),\n transform: rX($card.style.transform, 80),\n },\n {\n translate: getDefaultTranslate(items.length),\n transform: DEFAULT_TRANSFORM,\n },\n ],\n { duration: 1100, easing: \"ease-out\", fill: \"both\" }\n ).finished;\n onAnimationEnd?.(cardId);\n\n animation.commitStyles();\n animation.cancel();\n }\n\n cardRefs.current = [...cardRefs.current.slice(1), cardRefs.current[0]];\n setItems([...items.slice(1), items[0]]);\n setIsAnimating(false);\n };\n\n useLayoutEffect(() => {\n cardRefs.current.forEach((card, index) => {\n if (card) {\n card.style.transform = DEFAULT_TRANSFORM;\n card.style.translate = getDefaultTranslate(index);\n }\n });\n\n setItems((prev) => [...prev].reverse());\n }, []);\n\n const isAnimatingRef = useRef(isAnimating);\n const isHoveredRef = useRef(isHovered);\n const isHoveredOnCardRef = useRef(isHoveredOnCard);\n useEffect(() => {\n isHoveredRef.current = isHovered;\n isHoveredOnCardRef.current = isHoveredOnCard;\n\n if (isAnimating) {\n isAnimatingRef.current = isAnimating;\n return;\n }\n\n if (isAnimatingRef.current !== isAnimating) {\n isAnimatingRef.current = isAnimating;\n return;\n }\n\n if (cardRefs.current?.[0]) {\n if (isHovered || isHoveredOnCard) {\n cardRefs.current[0].style.transform = HOVERED_TRANSFORM;\n cardRefs.current[0].style.translate = HOVERED_TRANSLATE;\n } else {\n cardRefs.current[0].style.transform = DEFAULT_TRANSFORM;\n cardRefs.current[0].style.translate = getDefaultTranslate(0);\n }\n }\n }, [isHovered, isHoveredOnCard, isAnimating]);\n\n useEffect(() => {\n cardRefs.current.forEach((card, index) => {\n if (!card) {\n return;\n }\n if (index === 0 && (isHoveredRef.current || isHoveredOnCardRef.current)) {\n card.style.transform = HOVERED_TRANSFORM;\n card.style.translate = HOVERED_TRANSLATE;\n return;\n }\n card.style.transform = DEFAULT_TRANSFORM;\n card.style.translate = getDefaultTranslate(index);\n });\n }, [items]);\n\n return (\n <div\n className={cn(\"transform-3d hover:cursor-pointer\", _classNames?.root)}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={handleClick}\n >\n {items.map((item, index) => (\n <StackedCard\n ref={(el) => {\n cardRefs.current[index] = el;\n }}\n key={item.id || item.text}\n className={cn(\"absolute select-none left-1/2\", _classNames?.card)}\n onMouseEnter={() => {\n if (index === 0) {\n setIsHoveredOnCard(true);\n }\n }}\n onMouseLeave={() => {\n if (index === 0) {\n setIsHoveredOnCard(false);\n }\n }}\n onClick={handleClick}\n data-id={item.id || item.text}\n style={{\n transform: `translateX(-50%)`, // To ensure the card is centered as soon as it is rendered\n }}\n >\n {item.icon || <Code className=\"size-8 text-primary\" />}\n <p className=\"text-2xl text-center\">{item.text}</p>\n </StackedCard>\n ))}\n </div>\n );\n};\n\nexport default StackedCards;\n",
|
|
@@ -1232,6 +1329,8 @@
|
|
|
1232
1329
|
},
|
|
1233
1330
|
{
|
|
1234
1331
|
"name": "Theme Toggle",
|
|
1332
|
+
"exportName": "ThemeToggle",
|
|
1333
|
+
"packageName": "@rlx-components/theme-toggle",
|
|
1235
1334
|
"slug": "theme-toggle",
|
|
1236
1335
|
"category": "component",
|
|
1237
1336
|
"sourceCode": "\"use client\";\n\nimport { Button } from \"@rlx-widgets/button\";\nimport { Moon, Sun } from \"lucide-react\";\nimport { useTheme } from \"@rlx-widgets/base\";\n\nexport const ThemeToggle = () => {\n const { setTheme, theme } = useTheme();\n\n return (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setTheme(theme === \"light\" ? \"dark\" : \"light\")}\n >\n <Sun className=\"h-6 w-[1.3rem] dark:hidden\" />\n <Moon className=\"hidden h-5 w-5 dark:block\" />\n <span className=\"sr-only\">Toggle theme</span>\n </Button>\n );\n};\n",
|
|
@@ -1244,6 +1343,8 @@
|
|
|
1244
1343
|
},
|
|
1245
1344
|
{
|
|
1246
1345
|
"name": "Timeline",
|
|
1346
|
+
"exportName": "Timeline",
|
|
1347
|
+
"packageName": "@rlx-components/timeline",
|
|
1247
1348
|
"slug": "timeline",
|
|
1248
1349
|
"category": "component",
|
|
1249
1350
|
"sourceCode": "import { cn } from \"@rlx-widgets/base\";\nimport { StatusIndicator } from \"./components\";\nimport { TimelineProps } from \"./types\";\n\nconst Timeline = ({\n items,\n orientation = \"vertical\",\n className,\n connectorColor = \"bg-border\",\n connectorVerticalPosition = \"center\",\n}: TimelineProps) => {\n if (orientation === \"horizontal\") {\n return (\n <div className={cn(\"overflow-x-auto\", className)}>\n <div className=\"inline-flex items-center gap-4 pb-4 relative\">\n <div\n className={cn(\"absolute top-0 left-0 h-px right-0\", connectorColor)}\n />\n {items.map((item, index) => (\n <div key={index} className=\"relative\">\n <div className=\"absolute top-0 left-1/2 -translate-x-1/2\">\n <StatusIndicator statusColor={item.statusColor} />\n </div>\n {item.content}\n </div>\n ))}\n </div>\n </div>\n );\n }\n\n if (connectorVerticalPosition === \"left\") {\n return (\n <div className={cn(\"overflow-y-auto\", className)}>\n <div className=\"space-y-6 relative\">\n {items.map((item, index) => {\n return (\n <div key={index} className={cn(\"grid grid-cols-[auto_1fr]\")}>\n <StatusIndicator statusColor={item.statusColor} />\n <div className={cn(\"mb-6 ml-6\")}>{item.content}</div>\n </div>\n );\n })}\n <div\n className={cn(\n \"absolute left-1 top-0 bottom-0 w-px\",\n connectorColor\n )}\n />\n </div>\n </div>\n );\n }\n\n if (connectorVerticalPosition === \"right\") {\n return (\n <div className={cn(\"overflow-y-auto\", className)}>\n <div className=\"space-y-6 relative\">\n {items.map((item, index) => {\n return (\n <div key={index} className={cn(\"grid grid-cols-[1fr_auto]\")}>\n <div className={cn(\"mb-6 mr-6\")}>{item.content}</div>\n <StatusIndicator statusColor={item.statusColor} />\n </div>\n );\n })}\n <div\n className={cn(\n \"absolute right-1 top-0 bottom-0 w-px\",\n connectorColor\n )}\n />\n </div>\n </div>\n );\n }\n\n /**\n * connectorVerticalPosition === \"center\"\n * orientation === \"vertical\"\n */\n return (\n <div className={cn(\"overflow-y-auto\", className)}>\n <div className=\"space-y-6 relative\">\n {items.map((item, index) => {\n const isLeft = item.position === \"left\";\n\n return (\n <div key={index} className=\"grid grid-cols-[1fr_auto_1fr]\">\n {isLeft ? (\n <>\n <div className=\"mb-6 mr-6\">{item.content}</div>\n <StatusIndicator statusColor={item.statusColor} />\n <div></div>\n </>\n ) : (\n <>\n <div></div>\n <StatusIndicator statusColor={item.statusColor} />\n <div className=\"mb-6 ml-6\">{item.content}</div>\n </>\n )}\n </div>\n );\n })}\n <div\n className={cn(\n \"absolute left-1/2 top-0 bottom-0 w-px -translate-x-1/2\",\n connectorColor\n )}\n />\n </div>\n </div>\n );\n};\n\nexport { Timeline };\n",
|
|
@@ -1273,6 +1374,8 @@
|
|
|
1273
1374
|
},
|
|
1274
1375
|
{
|
|
1275
1376
|
"name": "Wave Text",
|
|
1377
|
+
"exportName": "WaveText",
|
|
1378
|
+
"packageName": "@rlx-components/wave-text",
|
|
1276
1379
|
"slug": "wave-text",
|
|
1277
1380
|
"category": "component",
|
|
1278
1381
|
"sourceCode": "export const WaveText = ({ children }: { children: string }) => {\n\tconst chars = children.split(\"\");\n\tconst waveSpeed = 0.15; // seconds between each letter starting the wave\n\tconst waveDuration = 0.6; // duration of each letter's wave motion\n\tconst pauseDuration = 1.5; // seconds pause after all letters finish\n\n\t// Count only non-space characters for timing calculations\n\tconst nonSpaceCount = chars.filter((char) => char !== \" \").length;\n\t// Total cycle: time for wave to pass through all letters + pause\n\tconst totalCycleDuration =\n\t\tnonSpaceCount * waveSpeed + waveDuration + pauseDuration;\n\n\t// Build individual keyframes for each letter (skip spaces)\n\tlet allKeyframes = \"\";\n\tlet nonSpaceIndex = 0; // Track which non-space character this is\n\n\tchars.forEach((char, index) => {\n\t\t// Skip creating keyframes for spaces\n\t\tif (char === \" \") return;\n\n\t\tconst animationName = `waveLetter${index}`;\n\t\t// Calculate when this letter's wave starts (staggered by waveSpeed)\n\t\tconst waveStart =\n\t\t\t((nonSpaceIndex * waveSpeed) / totalCycleDuration) * 100;\n\t\tconst wavePeak =\n\t\t\t((nonSpaceIndex * waveSpeed + waveDuration * 0.3) /\n\t\t\t\ttotalCycleDuration) *\n\t\t\t100;\n\t\tconst waveMid =\n\t\t\t((nonSpaceIndex * waveSpeed + waveDuration * 0.5) /\n\t\t\t\ttotalCycleDuration) *\n\t\t\t100;\n\t\tconst waveEnd =\n\t\t\t((nonSpaceIndex * waveSpeed + waveDuration) / totalCycleDuration) *\n\t\t\t100;\n\n\t\t// Create smooth arm wave motion - rise up and come back down\n\t\t// Alternate rotation for wave effect (left-right pattern)\n\t\tconst rotationAmount = nonSpaceIndex % 2 === 0 ? -12 : 12;\n\n\t\tallKeyframes += `@keyframes ${animationName} {\\n`;\n\t\tallKeyframes += ` 0% { transform: translateY(0) rotate(0deg); }\\n`;\n\t\tallKeyframes += ` ${waveStart.toFixed(\n\t\t\t2\n\t\t)}% { transform: translateY(0) rotate(0deg); }\\n`;\n\t\tallKeyframes += ` ${wavePeak.toFixed(\n\t\t\t2\n\t\t)}% { transform: translateY(-0.7em) rotate(${\n\t\t\trotationAmount * 0.7\n\t\t}deg); }\\n`;\n\t\tallKeyframes += ` ${waveMid.toFixed(\n\t\t\t2\n\t\t)}% { transform: translateY(-0.8em) rotate(${rotationAmount}deg); }\\n`;\n\t\tallKeyframes += ` ${waveEnd.toFixed(\n\t\t\t2\n\t\t)}% { transform: translateY(0) rotate(0deg); }\\n`;\n\t\tallKeyframes += ` 100% { transform: translateY(0) rotate(0deg); }\\n`;\n\t\tallKeyframes += `}\\n`;\n\n\t\tnonSpaceIndex++; // Increment for next non-space character\n\t});\n\n\treturn (\n\t\t<>\n\t\t\t<style>{allKeyframes}</style>\n\t\t\t<span className=\"inline-block\">\n\t\t\t\t{chars.map((char, index) => {\n\t\t\t\t\tconst isSpace = char === \" \";\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\tkey={index}\n\t\t\t\t\t\t\tclassName=\"inline-block\"\n\t\t\t\t\t\t\tstyle={\n\t\t\t\t\t\t\t\tisSpace\n\t\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\t\t\tanimation: `waveLetter${index} ${totalCycleDuration}s ease-in-out infinite`,\n\t\t\t\t\t\t\t\t\t }\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{isSpace ? \"\\u00A0\" : char}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</span>\n\t\t</>\n\t);\n};\n",
|
|
@@ -1287,8 +1390,11 @@
|
|
|
1287
1390
|
"animates": [
|
|
1288
1391
|
{
|
|
1289
1392
|
"name": "Circular Swing",
|
|
1393
|
+
"exportName": "--animate-rlx-circular-swing",
|
|
1394
|
+
"packageName": "@rlx-animates/circular-swing",
|
|
1290
1395
|
"slug": "circular-swing",
|
|
1291
1396
|
"category": "animate",
|
|
1397
|
+
"sourceCode": "@theme {\n --animate-rlx-circular-swing: circular-swing 2s ease-in-out infinite;\n @keyframes circular-swing {\n 0% {\n transform: rotate(0deg);\n }\n 50% {\n transform: rotate(22.5deg);\n }\n 100% {\n transform: rotate(0deg);\n }\n }\n}\n",
|
|
1292
1398
|
"demos": [
|
|
1293
1399
|
{
|
|
1294
1400
|
"name": "default",
|
|
@@ -1299,55 +1405,39 @@
|
|
|
1299
1405
|
],
|
|
1300
1406
|
"hooks": [
|
|
1301
1407
|
{
|
|
1302
|
-
"name": "
|
|
1303
|
-
"
|
|
1408
|
+
"name": "Use Copy To Clipboard",
|
|
1409
|
+
"exportName": "useCopyToClipboard",
|
|
1410
|
+
"packageName": "@rlx-hooks/use-copy-to-clipboard",
|
|
1411
|
+
"slug": "use-copy-to-clipboard",
|
|
1304
1412
|
"category": "hook",
|
|
1305
|
-
"
|
|
1306
|
-
{
|
|
1307
|
-
"name": "default",
|
|
1308
|
-
"code": "\"use client\";\n\nimport { useCopyToClipboard } from \"@rlx-hooks/use-copy-to-clipboard\";\nimport { Button } from \"@rlx-widgets/button\";\nimport { Check } from \"lucide-react\";\n\nexport const Preview = () => {\n const { isCopied, copyToClipboard } = useCopyToClipboard();\n\n return (\n <Button onClick={() => copyToClipboard(\"Hello World!\")} variant=\"outline\">\n {isCopied ? <Check className=\"w-4 h-4\" /> : \"Copy Text\"}\n </Button>\n );\n};\n"
|
|
1309
|
-
},
|
|
1310
|
-
{
|
|
1311
|
-
"name": "params",
|
|
1312
|
-
"code": "\"use client\";\n\nimport { useCopyToClipboard } from \"@rlx-hooks/use-copy-to-clipboard\";\nimport { Button } from \"@rlx-widgets/button\";\nimport { Check } from \"lucide-react\";\nimport { toast, Toaster } from \"sonner\";\nimport { useTheme } from \"@rlx-widgets/base\";\n\nexport const Preview = () => {\n const themeContext = useTheme();\n const theme = themeContext.theme;\n\n const handleCopy = () => {\n toast(\"Copied to clipboard\");\n };\n\n const { isCopied, copyToClipboard } = useCopyToClipboard({\n timeout: 2000,\n onCopy: handleCopy,\n });\n\n return (\n <div>\n <Toaster\n theme={theme}\n toastOptions={{\n style: {\n background: \"var(--color-muted)\",\n border: \"var(--color-border)\",\n },\n }}\n position=\"top-center\"\n />\n <Button onClick={() => copyToClipboard(\"Hello World!\")} variant=\"outline\">\n {isCopied ? <Check className=\"w-4 h-4\" /> : \"Copy Text\"}\n </Button>\n </div>\n );\n};\n"
|
|
1313
|
-
}
|
|
1314
|
-
]
|
|
1413
|
+
"sourceCode": "\"use client\";\n\nimport { useState } from \"react\";\n\nexport function useCopyToClipboard({\n timeout = 2000,\n onCopy,\n}: {\n timeout?: number;\n onCopy?: () => void;\n} = {}) {\n const [isCopied, setIsCopied] = useState(false);\n\n const copyToClipboard = (value: string) => {\n if (typeof window === \"undefined\" || !navigator.clipboard.writeText) {\n return;\n }\n\n if (!value) return;\n\n navigator.clipboard.writeText(value).then(() => {\n setIsCopied(true);\n\n if (onCopy) {\n onCopy();\n }\n\n if (timeout !== 0) {\n setTimeout(() => {\n setIsCopied(false);\n }, timeout);\n }\n }, console.error);\n };\n\n return { isCopied, copyToClipboard };\n}\n\nexport default useCopyToClipboard;"
|
|
1315
1414
|
},
|
|
1316
1415
|
{
|
|
1317
|
-
"name": "
|
|
1318
|
-
"
|
|
1416
|
+
"name": "Use Is Mobile",
|
|
1417
|
+
"exportName": "useIsMobile",
|
|
1418
|
+
"packageName": "@rlx-hooks/use-is-mobile",
|
|
1419
|
+
"slug": "use-is-mobile",
|
|
1319
1420
|
"category": "hook",
|
|
1320
|
-
"
|
|
1321
|
-
{
|
|
1322
|
-
"name": "default",
|
|
1323
|
-
"code": "\"use client\";\n\nimport { useState, useEffect } from \"react\";\nimport { useIsMobile } from \"@rlx-hooks/use-is-mobile\";\n\nexport const Preview = () => {\n const isMobile = useIsMobile();\n const [windowWidth, setWindowWidth] = useState(0);\n\n useEffect(() => {\n setWindowWidth(window.innerWidth);\n const handleResize = () => {\n setWindowWidth(window.innerWidth);\n };\n window.addEventListener(\"resize\", handleResize);\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n };\n }, []);\n\n return (\n <div>\n <div>Window width: {windowWidth}px</div>\n <div>Is mobile: {isMobile ? \"Yes\" : \"No\"}</div>\n </div>\n );\n};\n"
|
|
1324
|
-
}
|
|
1325
|
-
]
|
|
1421
|
+
"sourceCode": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nconst MOBILE_BREAKPOINT = 768;\n\nexport function useIsMobile() {\n const [isMobile, setIsMobile] = useState<boolean | undefined>(undefined);\n\n useEffect(() => {\n const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);\n const onChange = () => {\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\n };\n mql.addEventListener(\"change\", onChange);\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\n return () => mql.removeEventListener(\"change\", onChange);\n }, []);\n\n return !!isMobile;\n}\n\nexport default useIsMobile;"
|
|
1326
1422
|
},
|
|
1327
1423
|
{
|
|
1328
|
-
"name": "
|
|
1329
|
-
"
|
|
1424
|
+
"name": "Use Media Query",
|
|
1425
|
+
"exportName": "useMediaQuery",
|
|
1426
|
+
"packageName": "@rlx-hooks/use-media-query",
|
|
1427
|
+
"slug": "use-media-query",
|
|
1330
1428
|
"category": "hook",
|
|
1331
|
-
"
|
|
1332
|
-
{
|
|
1333
|
-
"name": "default",
|
|
1334
|
-
"code": "\"use client\";\n\nimport { useState } from \"react\";\nimport { Input } from \"@rlx-widgets/input\";\nimport { useMediaQuery } from \"@rlx-hooks/use-media-query\";\nimport { Badge } from \"@rlx-widgets/badge\";\n\nexport const Preview = () => {\n const [query, setQuery] = useState(\"(min-width: 768px)\");\n const isMatch = useMediaQuery(query);\n\n return (\n <div>\n <Input\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder=\"Enter media query\"\n />\n <div>\n Screen size matches:{\" \"}\n {isMatch ? (\n <Badge variant=\"default\">Yes</Badge>\n ) : (\n <Badge variant=\"destructive\">No</Badge>\n )}\n </div>\n </div>\n );\n};\n"
|
|
1335
|
-
}
|
|
1336
|
-
]
|
|
1429
|
+
"sourceCode": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nexport function useMediaQuery(query: string) {\n const [value, setValue] = useState(false);\n\n useEffect(() => {\n function onChange(event: MediaQueryListEvent) {\n setValue(event.matches);\n }\n\n const result = matchMedia(query);\n result.addEventListener(\"change\", onChange);\n setValue(result.matches);\n\n return () => result.removeEventListener(\"change\", onChange);\n }, [query]);\n\n return value;\n}\n\nexport default useMediaQuery;\n"
|
|
1337
1430
|
}
|
|
1338
1431
|
],
|
|
1339
1432
|
"utils": [
|
|
1340
1433
|
{
|
|
1341
|
-
"name": "
|
|
1342
|
-
"
|
|
1434
|
+
"name": "Is Valid Date",
|
|
1435
|
+
"exportName": "isValidDate",
|
|
1436
|
+
"packageName": "@rlx-utils/is-valid-date",
|
|
1437
|
+
"slug": "is-valid-date",
|
|
1343
1438
|
"category": "util",
|
|
1344
|
-
"
|
|
1345
|
-
{
|
|
1346
|
-
"name": "default",
|
|
1347
|
-
"code": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { Input } from \"@rlx-widgets/input\";\nimport { isValidDate } from \"@rlx-utils/is-valid-date\";\nimport { ShikiCodeBlock } from \"@rlx-components/shiki-code-block\";\nimport { InlineCode } from \"../../../../../../_components\";\nimport { ArrowRight } from \"lucide-react\";\n\nexport const Preview = () => {\n const [date, setDate] = useState<string>(\"2025-10-18\");\n const [isValid, setIsValid] = useState(false);\n\n useEffect(() => {\n setIsValid(isValidDate(new Date(date)));\n }, [date]);\n\n return (\n <div>\n <ShikiCodeBlock\n code={`isValidDate(new Date(\"${date}\"))`}\n lang=\"tsx\"\n className=\"h-fit\"\n />\n <Input\n type=\"text\"\n value={date}\n onChange={(e) => setDate(e.target.value)}\n className=\"mt-4\"\n />\n <p className=\"text-center mt-2\">\n {isValid ? \"Valid Date ✅\" : \"Invalid Date ❌\"}\n </p>\n {isValid && (\n <div className=\"flex items-center justify-center gap-2 mt-2\">\n <InlineCode>{`new Date(date).toLocaleDateString()`}</InlineCode>\n <ArrowRight className=\"w-4 h-4\" />\n <InlineCode>{new Date(date).toLocaleDateString()}</InlineCode>\n </div>\n )}\n </div>\n );\n};\n"
|
|
1348
|
-
}
|
|
1349
|
-
]
|
|
1439
|
+
"sourceCode": "export const isValidDate = (date: Date) => {\n return !Number.isNaN(date.getTime());\n};\n\nexport default isValidDate;\n"
|
|
1350
1440
|
}
|
|
1351
1441
|
],
|
|
1352
|
-
"extractedAt": "2025-11-
|
|
1442
|
+
"extractedAt": "2025-11-21T06:29:06.871Z"
|
|
1353
1443
|
}
|