@srcroot/ui 0.0.54 → 0.0.56

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 +55 -1
  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 +152 -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 +147 -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 +131 -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,125 +1,125 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import { FiEye, FiEyeOff, FiSearch, FiX } from "react-icons/fi"
5
-
6
- import { cn } from "@/lib/utils"
7
-
8
- export interface InputProps
9
- extends React.InputHTMLAttributes<HTMLInputElement> {
10
- /**
11
- * Whether the input is in an error state
12
- */
13
- error?: boolean
14
- }
15
-
16
- /**
17
- * Input component with focus states and error styling
18
- *
19
- * Supports special handling for:
20
- * - type="password": Adds show/hide toggle
21
- * - type="search": Adds search icon and clear button
22
- *
23
- * @example
24
- * // Basic usage
25
- * <Input placeholder="Enter your email" />
26
- *
27
- * // Password with toggle
28
- * <Input type="password" placeholder="Password" />
29
- *
30
- * // Search with icon and clear
31
- * <Input type="search" placeholder="Search..." />
32
- */
33
- const Input = React.forwardRef<HTMLInputElement, InputProps>(
34
- ({ className, type, error, ...props }, ref) => {
35
- const [isVisible, setIsVisible] = React.useState(false)
36
- const [value, setValue] = React.useState(props.value || props.defaultValue || "")
37
- const isPassword = type === "password"
38
- const isSearch = type === "search"
39
-
40
- // Handle value changes for search clear functionality
41
- const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
42
- setValue(e.target.value)
43
- props.onChange?.(e)
44
- }
45
-
46
- const handleClear = () => {
47
- setValue("")
48
- // Create a synthetic event to notify parent
49
- const event = {
50
- target: { value: "" },
51
- currentTarget: { value: "" },
52
- } as React.ChangeEvent<HTMLInputElement>
53
- props.onChange?.(event)
54
- }
55
-
56
- // Base input styles
57
- const baseStyles = cn(
58
- "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
59
- error && "border-destructive focus-visible:ring-destructive",
60
- isSearch && "pl-9", // Add padding for search icon
61
- (isPassword || (isSearch && value)) && "pr-9", // Add padding for toggle/clear button
62
- "[&::-webkit-search-cancel-button]:appearance-none", // Hide native search cancel button
63
- className
64
- )
65
-
66
- // For regular inputs, render normally
67
- if (!isPassword && !isSearch) {
68
- return (
69
- <input
70
- type={type}
71
- className={baseStyles}
72
- ref={ref}
73
- aria-invalid={error ? "true" : undefined}
74
- {...props}
75
- />
76
- )
77
- }
78
-
79
- return (
80
- <div className="relative">
81
- {isSearch && (
82
- <FiSearch className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground pointer-events-none" />
83
- )}
84
- <input
85
- type={isPassword ? (isVisible ? "text" : "password") : type}
86
- className={baseStyles}
87
- ref={ref}
88
- aria-invalid={error ? "true" : undefined}
89
- {...props}
90
- onChange={handleChange}
91
- value={props.value !== undefined ? props.value : value}
92
- />
93
- {isPassword && (
94
- <button
95
- type="button"
96
- onClick={() => setIsVisible(!isVisible)}
97
- className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground focus:outline-none"
98
- >
99
- {isVisible ? (
100
- <FiEyeOff className="h-4 w-4" aria-hidden="true" />
101
- ) : (
102
- <FiEye className="h-4 w-4" aria-hidden="true" />
103
- )}
104
- <span className="sr-only">
105
- {isVisible ? "Hide password" : "Show password"}
106
- </span>
107
- </button>
108
- )}
109
- {isSearch && value && (
110
- <button
111
- type="button"
112
- onClick={handleClear}
113
- className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground focus:outline-none"
114
- >
115
- <FiX className="h-4 w-4" aria-hidden="true" />
116
- <span className="sr-only">Clear search</span>
117
- </button>
118
- )}
119
- </div>
120
- )
121
- }
122
- )
123
- Input.displayName = "Input"
124
-
125
- export { Input }
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { FiEye, FiEyeOff, FiSearch, FiX } from "react-icons/fi"
5
+
6
+ import { cn } from "@/lib/utils"
7
+
8
+ export interface InputProps
9
+ extends React.InputHTMLAttributes<HTMLInputElement> {
10
+ /**
11
+ * Whether the input is in an error state
12
+ */
13
+ error?: boolean
14
+ }
15
+
16
+ /**
17
+ * Input component with focus states and error styling
18
+ *
19
+ * Supports special handling for:
20
+ * - type="password": Adds show/hide toggle
21
+ * - type="search": Adds search icon and clear button
22
+ *
23
+ * @example
24
+ * // Basic usage
25
+ * <Input placeholder="Enter your email" />
26
+ *
27
+ * // Password with toggle
28
+ * <Input type="password" placeholder="Password" />
29
+ *
30
+ * // Search with icon and clear
31
+ * <Input type="search" placeholder="Search..." />
32
+ */
33
+ const Input = React.forwardRef<HTMLInputElement, InputProps>(
34
+ ({ className, type, error, ...props }, ref) => {
35
+ const [isVisible, setIsVisible] = React.useState(false)
36
+ const [value, setValue] = React.useState(props.value || props.defaultValue || "")
37
+ const isPassword = type === "password"
38
+ const isSearch = type === "search"
39
+
40
+ // Handle value changes for search clear functionality
41
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
42
+ setValue(e.target.value)
43
+ props.onChange?.(e)
44
+ }
45
+
46
+ const handleClear = () => {
47
+ setValue("")
48
+ // Create a synthetic event to notify parent
49
+ const event = {
50
+ target: { value: "" },
51
+ currentTarget: { value: "" },
52
+ } as React.ChangeEvent<HTMLInputElement>
53
+ props.onChange?.(event)
54
+ }
55
+
56
+ // Base input styles
57
+ const baseStyles = cn(
58
+ "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
59
+ error && "border-destructive focus-visible:ring-destructive",
60
+ isSearch && "pl-9", // Add padding for search icon
61
+ (isPassword || (isSearch && value)) && "pr-9", // Add padding for toggle/clear button
62
+ "[&::-webkit-search-cancel-button]:appearance-none", // Hide native search cancel button
63
+ className
64
+ )
65
+
66
+ // For regular inputs, render normally
67
+ if (!isPassword && !isSearch) {
68
+ return (
69
+ <input
70
+ type={type}
71
+ className={baseStyles}
72
+ ref={ref}
73
+ aria-invalid={error ? "true" : undefined}
74
+ {...props}
75
+ />
76
+ )
77
+ }
78
+
79
+ return (
80
+ <div className="relative">
81
+ {isSearch && (
82
+ <FiSearch className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground pointer-events-none" />
83
+ )}
84
+ <input
85
+ type={isPassword ? (isVisible ? "text" : "password") : type}
86
+ className={baseStyles}
87
+ ref={ref}
88
+ aria-invalid={error ? "true" : undefined}
89
+ {...props}
90
+ onChange={handleChange}
91
+ value={props.value !== undefined ? props.value : value}
92
+ />
93
+ {isPassword && (
94
+ <button
95
+ type="button"
96
+ onClick={() => setIsVisible(!isVisible)}
97
+ className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground focus:outline-none"
98
+ >
99
+ {isVisible ? (
100
+ <FiEyeOff className="h-4 w-4" aria-hidden="true" />
101
+ ) : (
102
+ <FiEye className="h-4 w-4" aria-hidden="true" />
103
+ )}
104
+ <span className="sr-only">
105
+ {isVisible ? "Hide password" : "Show password"}
106
+ </span>
107
+ </button>
108
+ )}
109
+ {isSearch && value && (
110
+ <button
111
+ type="button"
112
+ onClick={handleClear}
113
+ className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground focus:outline-none"
114
+ >
115
+ <FiX className="h-4 w-4" aria-hidden="true" />
116
+ <span className="sr-only">Clear search</span>
117
+ </button>
118
+ )}
119
+ </div>
120
+ )
121
+ }
122
+ )
123
+ Input.displayName = "Input"
124
+
125
+ export { Input }
@@ -1,63 +1,60 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import { cn } from "@/lib/utils"
5
-
6
- interface KbdProps extends React.HTMLAttributes<HTMLElement> {
7
- /** Array of keys to display (e.g., ["Ctrl", "K"]) */
8
- keys?: string[]
9
- }
10
-
11
- /**
12
- * Kbd - Keyboard key display component
13
- *
14
- * Usage:
15
- * <Kbd>⌘</Kbd>
16
- * <Kbd keys={["Ctrl", "Shift", "P"]} />
17
- */
18
- const Kbd = React.forwardRef<HTMLElement, KbdProps>(
19
- ({ className, children, keys, ...props }, ref) => {
20
- // If keys array is provided, render each key
21
- if (keys && keys.length > 0) {
22
- return (
23
- <span className="inline-flex items-center gap-1">
24
- {keys.map((key, index) => (
25
- <React.Fragment key={index}>
26
- <kbd
27
- ref={index === 0 ? ref : undefined}
28
- className={cn(
29
- "pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground",
30
- className
31
- )}
32
- {...props}
33
- >
34
- {key}
35
- </kbd>
36
- {index < keys.length - 1 && (
37
- <span className="text-muted-foreground text-xs">+</span>
38
- )}
39
- </React.Fragment>
40
- ))}
41
- </span>
42
- )
43
- }
44
-
45
- // Single key rendering
46
- return (
47
- <kbd
48
- ref={ref}
49
- className={cn(
50
- "pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground",
51
- className
52
- )}
53
- {...props}
54
- >
55
- {children}
56
- </kbd>
57
- )
58
- }
59
- )
60
- Kbd.displayName = "Kbd"
61
-
62
- export { Kbd }
63
-
1
+ import * as React from "react"
2
+ import { cn } from "@/lib/utils"
3
+
4
+ interface KbdProps extends React.HTMLAttributes<HTMLElement> {
5
+ /** Array of keys to display (e.g., ["Ctrl", "K"]) */
6
+ keys?: string[]
7
+ }
8
+
9
+ /**
10
+ * Kbd - Keyboard key display component
11
+ *
12
+ * Usage:
13
+ * <Kbd>⌘</Kbd>
14
+ * <Kbd keys={["Ctrl", "Shift", "P"]} />
15
+ */
16
+ const Kbd = React.forwardRef<HTMLElement, KbdProps>(
17
+ ({ className, children, keys, ...props }, ref) => {
18
+ // If keys array is provided, render each key
19
+ if (keys && keys.length > 0) {
20
+ return (
21
+ <span className="inline-flex items-center gap-1">
22
+ {keys.map((key, index) => (
23
+ <React.Fragment key={index}>
24
+ <kbd
25
+ ref={index === 0 ? ref : undefined}
26
+ className={cn(
27
+ "pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground",
28
+ className
29
+ )}
30
+ {...props}
31
+ >
32
+ {key}
33
+ </kbd>
34
+ {index < keys.length - 1 && (
35
+ <span className="text-muted-foreground text-xs">+</span>
36
+ )}
37
+ </React.Fragment>
38
+ ))}
39
+ </span>
40
+ )
41
+ }
42
+
43
+ // Single key rendering
44
+ return (
45
+ <kbd
46
+ ref={ref}
47
+ className={cn(
48
+ "pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground",
49
+ className
50
+ )}
51
+ {...props}
52
+ >
53
+ {children}
54
+ </kbd>
55
+ )
56
+ }
57
+ )
58
+ Kbd.displayName = "Kbd"
59
+
60
+ export { Kbd }
@@ -1,37 +1,36 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import { cn } from "@/lib/utils"
5
-
6
- /**
7
- * Label component for form inputs
8
- *
9
- * @example
10
- * <Label htmlFor="email">Email</Label>
11
- * <Input id="email" type="email" />
12
- */
13
- const Label = React.forwardRef<
14
- HTMLLabelElement,
15
- React.LabelHTMLAttributes<HTMLLabelElement> & {
16
- /**
17
- * Whether the associated input is required
18
- */
19
- required?: boolean
20
- }
21
- >(({ className, required, children, ...props }, ref) => (
22
- <label
23
- ref={ref}
24
- className={cn(
25
- "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
26
- className
27
- )}
28
- {...props}
29
- >
30
- {children}
31
- {required && <span className="text-destructive ml-1">*</span>}
32
- </label>
33
- ))
34
- Label.displayName = "Label"
35
-
36
- export { Label }
37
-
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { cn } from "@/lib/utils"
5
+
6
+ /**
7
+ * Label component for form inputs
8
+ *
9
+ * @example
10
+ * <Label htmlFor="email">Email</Label>
11
+ * <Input id="email" type="email" />
12
+ */
13
+ const Label = React.forwardRef<
14
+ HTMLLabelElement,
15
+ React.LabelHTMLAttributes<HTMLLabelElement> & {
16
+ /**
17
+ * Whether the associated input is required
18
+ */
19
+ required?: boolean
20
+ }
21
+ >(({ className, required, children, ...props }, ref) => (
22
+ <label
23
+ ref={ref}
24
+ className={cn(
25
+ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
26
+ className
27
+ )}
28
+ {...props}
29
+ >
30
+ {children}
31
+ {required && <span className="text-destructive ml-1">*</span>}
32
+ </label>
33
+ ))
34
+ Label.displayName = "Label"
35
+
36
+ export { Label }