@srcroot/ui 0.0.55 → 0.0.58

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.
Files changed (107) hide show
  1. package/README.md +151 -151
  2. package/dist/index.d.ts +0 -0
  3. package/dist/index.js +120 -93
  4. package/package.json +7 -2
  5. package/src/registry/analytics/google-analytics.tsx +36 -39
  6. package/src/registry/analytics/google-tag-manager.tsx +62 -65
  7. package/src/registry/analytics/meta-pixel.tsx +44 -47
  8. package/src/registry/analytics/microsoft-clarity.tsx +31 -34
  9. package/src/registry/analytics/tiktok-pixel.tsx +34 -37
  10. package/src/registry/lib/utils.ts +0 -0
  11. package/src/registry/themes/v3/blue.css +157 -157
  12. package/src/registry/themes/v3/glass.css +153 -153
  13. package/src/registry/themes/v3/gray.css +157 -157
  14. package/src/registry/themes/v3/green.css +157 -157
  15. package/src/registry/themes/v3/neutral.css +157 -157
  16. package/src/registry/themes/v3/orange.css +157 -157
  17. package/src/registry/themes/v3/rose.css +157 -157
  18. package/src/registry/themes/v3/slate.css +157 -157
  19. package/src/registry/themes/v3/stone.css +157 -157
  20. package/src/registry/themes/v3/violet.css +186 -186
  21. package/src/registry/themes/v3/zinc.css +157 -157
  22. package/src/registry/themes/v4/blue.css +184 -184
  23. package/src/registry/themes/v4/glass.css +180 -180
  24. package/src/registry/themes/v4/gray.css +184 -184
  25. package/src/registry/themes/v4/green.css +184 -184
  26. package/src/registry/themes/v4/neutral.css +184 -184
  27. package/src/registry/themes/v4/orange.css +184 -184
  28. package/src/registry/themes/v4/rose.css +184 -184
  29. package/src/registry/themes/v4/slate.css +184 -184
  30. package/src/registry/themes/v4/stone.css +184 -184
  31. package/src/registry/themes/v4/violet.css +184 -184
  32. package/src/registry/themes/v4/zinc.css +184 -184
  33. package/src/registry/ui/accordion.tsx +164 -165
  34. package/src/registry/ui/alert-dialog.tsx +213 -214
  35. package/src/registry/ui/alert.tsx +73 -76
  36. package/src/registry/ui/aspect-ratio.tsx +44 -47
  37. package/src/registry/ui/avatar.tsx +96 -97
  38. package/src/registry/ui/badge.tsx +52 -55
  39. package/src/registry/ui/breadcrumb.tsx +147 -150
  40. package/src/registry/ui/button-group.tsx +64 -67
  41. package/src/registry/ui/button.tsx +71 -72
  42. package/src/registry/ui/calendar.tsx +514 -515
  43. package/src/registry/ui/card.tsx +88 -91
  44. package/src/registry/ui/carousel.tsx +214 -214
  45. package/src/registry/ui/chart.tsx +373 -373
  46. package/src/registry/ui/chatbot.tsx +86 -13
  47. package/src/registry/ui/checkbox.tsx +93 -94
  48. package/src/registry/ui/collapsible.tsx +107 -108
  49. package/src/registry/ui/combobox.tsx +171 -171
  50. package/src/registry/ui/command.tsx +300 -300
  51. package/src/registry/ui/container.tsx +44 -47
  52. package/src/registry/ui/context-menu.tsx +221 -221
  53. package/src/registry/ui/date-picker.tsx +228 -228
  54. package/src/registry/ui/dialog.tsx +269 -270
  55. package/src/registry/ui/drawer.tsx +10 -4
  56. package/src/registry/ui/dropdown-menu.tsx +529 -530
  57. package/src/registry/ui/empty-state.tsx +0 -2
  58. package/src/registry/ui/file-upload.tsx +0 -0
  59. package/src/registry/ui/floating-dock.tsx +0 -0
  60. package/src/registry/ui/form-field.tsx +91 -94
  61. package/src/registry/ui/google-analytics.tsx +38 -0
  62. package/src/registry/ui/google-tag-manager.tsx +64 -0
  63. package/src/registry/ui/hover-card.tsx +223 -223
  64. package/src/registry/ui/image.tsx +144 -147
  65. package/src/registry/ui/input-group.tsx +82 -85
  66. package/src/registry/ui/input.tsx +125 -125
  67. package/src/registry/ui/kbd.tsx +60 -63
  68. package/src/registry/ui/label.tsx +36 -37
  69. package/src/registry/ui/loading-spinner.tsx +108 -111
  70. package/src/registry/ui/map.tsx +0 -0
  71. package/src/registry/ui/marquee.tsx +2 -0
  72. package/src/registry/ui/menubar.tsx +246 -246
  73. package/src/registry/ui/meta-pixel.tsx +46 -0
  74. package/src/registry/ui/microsoft-clarity.tsx +33 -0
  75. package/src/registry/ui/native-select.tsx +49 -52
  76. package/src/registry/ui/otp-input.tsx +163 -155
  77. package/src/registry/ui/pagination.tsx +149 -152
  78. package/src/registry/ui/patterns.tsx +28 -0
  79. package/src/registry/ui/popover.tsx +226 -227
  80. package/src/registry/ui/progress.tsx +51 -52
  81. package/src/registry/ui/radio.tsx +99 -102
  82. package/src/registry/ui/resizable.tsx +314 -314
  83. package/src/registry/ui/scroll-animation.tsx +45 -0
  84. package/src/registry/ui/scroll-area.tsx +121 -122
  85. package/src/registry/ui/scroll-to-top.tsx +0 -0
  86. package/src/registry/ui/search.tsx +162 -150
  87. package/src/registry/ui/select.tsx +292 -293
  88. package/src/registry/ui/separator.tsx +46 -47
  89. package/src/registry/ui/sheet.tsx +6 -3
  90. package/src/registry/ui/sidebar.tsx +628 -628
  91. package/src/registry/ui/skeleton.tsx +26 -29
  92. package/src/registry/ui/slider.tsx +196 -197
  93. package/src/registry/ui/slot.tsx +69 -72
  94. package/src/registry/ui/star-rating.tsx +146 -134
  95. package/src/registry/ui/switch.tsx +72 -73
  96. package/src/registry/ui/table-of-contents.tsx +96 -96
  97. package/src/registry/ui/table.tsx +138 -139
  98. package/src/registry/ui/tabs.tsx +124 -125
  99. package/src/registry/ui/text.tsx +61 -64
  100. package/src/registry/ui/textarea.tsx +41 -42
  101. package/src/registry/ui/theme-switcher.tsx +66 -66
  102. package/src/registry/ui/tiktok-pixel.tsx +36 -0
  103. package/src/registry/ui/toast.tsx +97 -98
  104. package/src/registry/ui/toggle-group.tsx +129 -129
  105. package/src/registry/ui/toggle.tsx +72 -72
  106. package/src/registry/ui/tooltip.tsx +143 -144
  107. package/src/registry/ui/whatsapp.tsx +0 -0
@@ -1,42 +1,41 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import { cn } from "@/lib/utils"
5
-
6
- export interface TextareaProps
7
- extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
8
- /**
9
- * Whether the textarea is in an error state
10
- */
11
- error?: boolean
12
- }
13
-
14
- /**
15
- * Textarea component for multi-line text input
16
- *
17
- * @example
18
- * <Textarea placeholder="Enter your message" />
19
- *
20
- * @example
21
- * <Textarea error placeholder="Required field" />
22
- */
23
- const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
24
- ({ className, error, ...props }, ref) => {
25
- return (
26
- <textarea
27
- className={cn(
28
- "flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
29
- error && "border-destructive focus-visible:ring-destructive",
30
- className
31
- )}
32
- ref={ref}
33
- aria-invalid={error ? "true" : undefined}
34
- {...props}
35
- />
36
- )
37
- }
38
- )
39
- Textarea.displayName = "Textarea"
40
-
41
- export { Textarea }
42
-
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { cn } from "@/lib/utils"
5
+
6
+ export interface TextareaProps
7
+ extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
8
+ /**
9
+ * Whether the textarea is in an error state
10
+ */
11
+ error?: boolean
12
+ }
13
+
14
+ /**
15
+ * Textarea component for multi-line text input
16
+ *
17
+ * @example
18
+ * <Textarea placeholder="Enter your message" />
19
+ *
20
+ * @example
21
+ * <Textarea error placeholder="Required field" />
22
+ */
23
+ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
24
+ ({ className, error, ...props }, ref) => {
25
+ return (
26
+ <textarea
27
+ className={cn(
28
+ "flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
29
+ error && "border-destructive focus-visible:ring-destructive",
30
+ className
31
+ )}
32
+ ref={ref}
33
+ aria-invalid={error ? "true" : undefined}
34
+ {...props}
35
+ />
36
+ )
37
+ }
38
+ )
39
+ Textarea.displayName = "Textarea"
40
+
41
+ export { Textarea }
@@ -1,66 +1,66 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import { useTheme } from "next-themes"
5
- import { FiSun, FiMoon, FiMonitor } from "react-icons/fi"
6
-
7
- import { DropdownMenuItem } from "@/components/ui/dropdown-menu"
8
-
9
- /**
10
- * ThemeSwitcher component for use within a DropdownMenu
11
- * Toggles between light, dark, and system themes
12
- *
13
- * @example
14
- * <DropdownMenu>
15
- * <DropdownMenuContent>
16
- * <ThemeSwitcher />
17
- * </DropdownMenuContent>
18
- * </DropdownMenu>
19
- */
20
- export function ThemeSwitcher() {
21
- const { setTheme, theme, resolvedTheme } = useTheme()
22
- const [mounted, setMounted] = React.useState(false)
23
-
24
- // Avoid hydration mismatch
25
- React.useEffect(() => {
26
- setMounted(true)
27
- }, [])
28
-
29
- const toggleTheme = () => {
30
- // Cycle: light -> dark -> system -> light
31
- if (theme === "light") {
32
- setTheme("dark")
33
- } else if (theme === "dark") {
34
- setTheme("system")
35
- } else {
36
- setTheme("light")
37
- }
38
- }
39
-
40
- const getIcon = () => {
41
- if (!mounted) {
42
- return <FiSun className="mr-2 h-4 w-4" />
43
- }
44
- if (theme === "system") {
45
- return <FiMonitor className="mr-2 h-4 w-4" />
46
- }
47
- if (resolvedTheme === "dark") {
48
- return <FiMoon className="mr-2 h-4 w-4" />
49
- }
50
- return <FiSun className="mr-2 h-4 w-4" />
51
- }
52
-
53
- const getLabel = () => {
54
- if (!mounted) return "Theme"
55
- if (theme === "system") return "System"
56
- if (theme === "dark") return "Dark"
57
- return "Light"
58
- }
59
-
60
- return (
61
- <DropdownMenuItem onClick={toggleTheme} closeOnSelect={false}>
62
- {getIcon()}
63
- <span>Theme: {getLabel()}</span>
64
- </DropdownMenuItem>
65
- )
66
- }
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { useTheme } from "next-themes"
5
+ import { FiSun, FiMoon, FiMonitor } from "react-icons/fi"
6
+
7
+ import { DropdownMenuItem } from "@/components/ui/dropdown-menu"
8
+
9
+ /**
10
+ * ThemeSwitcher component for use within a DropdownMenu
11
+ * Toggles between light, dark, and system themes
12
+ *
13
+ * @example
14
+ * <DropdownMenu>
15
+ * <DropdownMenuContent>
16
+ * <ThemeSwitcher />
17
+ * </DropdownMenuContent>
18
+ * </DropdownMenu>
19
+ */
20
+ export function ThemeSwitcher() {
21
+ const { setTheme, theme, resolvedTheme } = useTheme()
22
+ const [mounted, setMounted] = React.useState(false)
23
+
24
+ // Avoid hydration mismatch
25
+ React.useEffect(() => {
26
+ setMounted(true)
27
+ }, [])
28
+
29
+ const toggleTheme = () => {
30
+ // Cycle: light -> dark -> system -> light
31
+ if (theme === "light") {
32
+ setTheme("dark")
33
+ } else if (theme === "dark") {
34
+ setTheme("system")
35
+ } else {
36
+ setTheme("light")
37
+ }
38
+ }
39
+
40
+ const getIcon = () => {
41
+ if (!mounted) {
42
+ return <FiSun className="mr-2 h-4 w-4" />
43
+ }
44
+ if (theme === "system") {
45
+ return <FiMonitor className="mr-2 h-4 w-4" />
46
+ }
47
+ if (resolvedTheme === "dark") {
48
+ return <FiMoon className="mr-2 h-4 w-4" />
49
+ }
50
+ return <FiSun className="mr-2 h-4 w-4" />
51
+ }
52
+
53
+ const getLabel = () => {
54
+ if (!mounted) return "Theme"
55
+ if (theme === "system") return "System"
56
+ if (theme === "dark") return "Dark"
57
+ return "Light"
58
+ }
59
+
60
+ return (
61
+ <DropdownMenuItem onClick={toggleTheme} closeOnSelect={false}>
62
+ {getIcon()}
63
+ <span>Theme: {getLabel()}</span>
64
+ </DropdownMenuItem>
65
+ )
66
+ }
@@ -0,0 +1,36 @@
1
+ "use client"
2
+
3
+ import Script from 'next/script';
4
+ import type { FC } from 'react';
5
+
6
+ interface TikTokPixelProps {
7
+ pixelIds: string[]; // ← array
8
+ }
9
+
10
+ const TikTokPixel: FC<TikTokPixelProps> = ({ pixelIds }) => {
11
+ return (
12
+ <Script
13
+ id="tiktok-script-multi"
14
+ strategy="afterInteractive"
15
+ dangerouslySetInnerHTML={{
16
+ __html: `
17
+ !function (w, d, t) {
18
+ w.TiktokAnalyticsObject=t;var ttq=w[t]=w[t]||[];
19
+ ttq.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie","holdConsent","revokeConsent","grantConsent"],
20
+ ttq.setAndDefer=function(t,e){t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}};
21
+ for(var i=0;i<ttq.methods.length;i++)ttq.setAndDefer(ttq,ttq.methods[i]);
22
+ ttq.instance=function(t){for(var e=ttq._i[t]||[],n=0;n<ttq.methods.length;n++)ttq.setAndDefer(e,ttq.methods[n]);return e},
23
+ ttq.load=function(e,n){var r="https://analytics.tiktok.com/i18n/pixel/events.js";
24
+ ttq._i=ttq._i||{},ttq._i[e]=[],ttq._i[e]._u=r,ttq._t=ttq._t||{},ttq._t[e]=+new Date,ttq._o=ttq._o||{},ttq._o[e]=n||{};
25
+ var s=document.createElement("script");s.type="text/javascript",s.async=!0,s.src=r+"?sdkid="+e+"&lib="+t;
26
+ var p=document.getElementsByTagName("script")[0];p.parentNode.insertBefore(s,p)};
27
+ ${pixelIds.map(id => `ttq.load('${id}');`).join('\n')}
28
+ ttq.page();
29
+ }(window, document, 'ttq');
30
+ `,
31
+ }}
32
+ />
33
+ );
34
+ };
35
+
36
+ export default TikTokPixel;
@@ -1,98 +1,97 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import { cva, type VariantProps } from "class-variance-authority"
5
- import { cn } from "@/lib/utils"
6
-
7
- const toastVariants = cva(
8
- "group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all",
9
- {
10
- variants: {
11
- variant: {
12
- default: "border bg-background text-foreground",
13
- destructive:
14
- "destructive group border-destructive bg-destructive text-destructive-foreground",
15
- },
16
- },
17
- defaultVariants: {
18
- variant: "default",
19
- },
20
- }
21
- )
22
-
23
- interface ToastProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof toastVariants> {
24
- onClose?: () => void
25
- }
26
-
27
- /**
28
- * Toast notification component
29
- *
30
- * For a complete toast system, use with a ToastProvider context.
31
- * This is the individual toast component.
32
- *
33
- * @example
34
- * <Toast variant="default">
35
- * <ToastTitle>Success</ToastTitle>
36
- * <ToastDescription>Your action was completed.</ToastDescription>
37
- * </Toast>
38
- */
39
- const Toast = React.forwardRef<HTMLDivElement, ToastProps>(
40
- ({ className, variant, onClose, children, ...props }, ref) => {
41
- return (
42
- <div
43
- ref={ref}
44
- role={variant === "destructive" ? "alert" : "status"}
45
- aria-live={variant === "destructive" ? "assertive" : "polite"}
46
- className={cn(toastVariants({ variant }), className)}
47
- {...props}
48
- >
49
- <div className="grid gap-1">{children}</div>
50
- {onClose && (
51
- <button
52
- className="absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-1 group-hover:opacity-100"
53
- onClick={onClose}
54
- >
55
- <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
56
- <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
57
- </svg>
58
- </button>
59
- )}
60
- </div>
61
- )
62
- }
63
- )
64
- Toast.displayName = "Toast"
65
-
66
- const ToastTitle = React.forwardRef<
67
- HTMLDivElement,
68
- React.HTMLAttributes<HTMLDivElement>
69
- >(({ className, ...props }, ref) => (
70
- <div ref={ref} className={cn("text-sm font-semibold [&+div]:text-xs", className)} {...props} />
71
- ))
72
- ToastTitle.displayName = "ToastTitle"
73
-
74
- const ToastDescription = React.forwardRef<
75
- HTMLDivElement,
76
- React.HTMLAttributes<HTMLDivElement>
77
- >(({ className, ...props }, ref) => (
78
- <div ref={ref} className={cn("text-sm opacity-90", className)} {...props} />
79
- ))
80
- ToastDescription.displayName = "ToastDescription"
81
-
82
- const ToastAction = React.forwardRef<
83
- HTMLButtonElement,
84
- React.ButtonHTMLAttributes<HTMLButtonElement>
85
- >(({ className, ...props }, ref) => (
86
- <button
87
- ref={ref}
88
- className={cn(
89
- "inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium transition-colors hover:bg-secondary focus:outline-none focus:ring-1 focus:ring-ring disabled:pointer-events-none disabled:opacity-50",
90
- className
91
- )}
92
- {...props}
93
- />
94
- ))
95
- ToastAction.displayName = "ToastAction"
96
-
97
- export { Toast, ToastTitle, ToastDescription, ToastAction, toastVariants }
98
-
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { cva, type VariantProps } from "class-variance-authority"
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const toastVariants = cva(
8
+ "group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default: "border bg-background text-foreground",
13
+ destructive:
14
+ "destructive group border-destructive bg-destructive text-destructive-foreground",
15
+ },
16
+ },
17
+ defaultVariants: {
18
+ variant: "default",
19
+ },
20
+ }
21
+ )
22
+
23
+ interface ToastProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof toastVariants> {
24
+ onClose?: () => void
25
+ }
26
+
27
+ /**
28
+ * Toast notification component
29
+ *
30
+ * For a complete toast system, use with a ToastProvider context.
31
+ * This is the individual toast component.
32
+ *
33
+ * @example
34
+ * <Toast variant="default">
35
+ * <ToastTitle>Success</ToastTitle>
36
+ * <ToastDescription>Your action was completed.</ToastDescription>
37
+ * </Toast>
38
+ */
39
+ const Toast = React.forwardRef<HTMLDivElement, ToastProps>(
40
+ ({ className, variant, onClose, children, ...props }, ref) => {
41
+ return (
42
+ <div
43
+ ref={ref}
44
+ role={variant === "destructive" ? "alert" : "status"}
45
+ aria-live={variant === "destructive" ? "assertive" : "polite"}
46
+ className={cn(toastVariants({ variant }), className)}
47
+ {...props}
48
+ >
49
+ <div className="grid gap-1">{children}</div>
50
+ {onClose && (
51
+ <button
52
+ className="absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-1 group-hover:opacity-100"
53
+ onClick={onClose}
54
+ >
55
+ <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
56
+ <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
57
+ </svg>
58
+ </button>
59
+ )}
60
+ </div>
61
+ )
62
+ }
63
+ )
64
+ Toast.displayName = "Toast"
65
+
66
+ const ToastTitle = React.forwardRef<
67
+ HTMLDivElement,
68
+ React.HTMLAttributes<HTMLDivElement>
69
+ >(({ className, ...props }, ref) => (
70
+ <div ref={ref} className={cn("text-sm font-semibold [&+div]:text-xs", className)} {...props} />
71
+ ))
72
+ ToastTitle.displayName = "ToastTitle"
73
+
74
+ const ToastDescription = React.forwardRef<
75
+ HTMLDivElement,
76
+ React.HTMLAttributes<HTMLDivElement>
77
+ >(({ className, ...props }, ref) => (
78
+ <div ref={ref} className={cn("text-sm opacity-90", className)} {...props} />
79
+ ))
80
+ ToastDescription.displayName = "ToastDescription"
81
+
82
+ const ToastAction = React.forwardRef<
83
+ HTMLButtonElement,
84
+ React.ButtonHTMLAttributes<HTMLButtonElement>
85
+ >(({ className, ...props }, ref) => (
86
+ <button
87
+ ref={ref}
88
+ className={cn(
89
+ "inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium transition-colors hover:bg-secondary focus:outline-none focus:ring-1 focus:ring-ring disabled:pointer-events-none disabled:opacity-50",
90
+ className
91
+ )}
92
+ {...props}
93
+ />
94
+ ))
95
+ ToastAction.displayName = "ToastAction"
96
+
97
+ export { Toast, ToastTitle, ToastDescription, ToastAction, toastVariants }