trix-ui 0.2.1 → 0.2.3

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 (69) hide show
  1. package/README.md +306 -215
  2. package/dist/commands/add/__tests__/add.test.js +16 -4
  3. package/dist/commands/add/__tests__/add.test.js.map +1 -1
  4. package/dist/commands/add/analysis.js +6 -1
  5. package/dist/commands/add/analysis.js.map +1 -1
  6. package/dist/commands/add/command.js +6 -0
  7. package/dist/commands/add/command.js.map +1 -1
  8. package/dist/commands/add/types.d.ts +1 -0
  9. package/dist/commands/add/ui.js +4 -0
  10. package/dist/commands/add/ui.js.map +1 -1
  11. package/dist/commands/add-composite.d.ts +2 -0
  12. package/dist/commands/add-composite.js +202 -0
  13. package/dist/commands/add-composite.js.map +1 -0
  14. package/dist/commands/add-section.js +6 -0
  15. package/dist/commands/add-section.js.map +1 -1
  16. package/dist/commands/add-wrapper.js +6 -0
  17. package/dist/commands/add-wrapper.js.map +1 -1
  18. package/dist/commands/build.js +104 -104
  19. package/dist/commands/doctor.js +7 -2
  20. package/dist/commands/doctor.js.map +1 -1
  21. package/dist/commands/init/config.js +1 -0
  22. package/dist/commands/init/config.js.map +1 -1
  23. package/dist/commands/list.js +12 -4
  24. package/dist/commands/list.js.map +1 -1
  25. package/dist/commands/remove.js +24 -10
  26. package/dist/commands/remove.js.map +1 -1
  27. package/dist/commands/shared/add-collection.d.ts +2 -1
  28. package/dist/commands/shared/add-collection.js +8 -2
  29. package/dist/commands/shared/add-collection.js.map +1 -1
  30. package/dist/index.js +2 -0
  31. package/dist/index.js.map +1 -1
  32. package/dist/lib/config.d.ts +1 -0
  33. package/dist/lib/config.js +1 -0
  34. package/dist/lib/config.js.map +1 -1
  35. package/dist/lib/lockfile.d.ts +6 -5
  36. package/dist/lib/lockfile.js +3 -0
  37. package/dist/lib/lockfile.js.map +1 -1
  38. package/dist/lib/paths.d.ts +1 -0
  39. package/dist/lib/paths.js +1 -0
  40. package/dist/lib/paths.js.map +1 -1
  41. package/dist/lib/registry.d.ts +2 -0
  42. package/dist/lib/registry.js +11 -0
  43. package/dist/lib/registry.js.map +1 -1
  44. package/package.json +4 -3
  45. package/registry/index.json +204 -242
  46. package/templates/components/ui/avatar.tsx +109 -0
  47. package/templates/components/ui/badge.tsx +182 -182
  48. package/templates/components/ui/button.tsx +48 -44
  49. package/templates/components/ui/label.tsx +24 -0
  50. package/templates/composites/feature-collection-card.tsx +113 -0
  51. package/templates/composites/music-player-card.tsx +571 -0
  52. package/templates/composites/user-profile-card.tsx +145 -0
  53. package/templates/sections/signature-hero.tsx +92 -0
  54. package/templates/wrappers/Interative-wrapper.tsx +555 -0
  55. package/templates/wrappers/progress-wrapper.tsx +248 -0
  56. package/templates/wrappers/reveal-wrap.tsx +136 -0
  57. package/LICENSE.md +0 -21
  58. package/templates/components/ui/checkbox.tsx +0 -33
  59. package/templates/components/ui/dialog.tsx +0 -92
  60. package/templates/components/ui/dropdown.tsx +0 -75
  61. package/templates/components/ui/select.tsx +0 -24
  62. package/templates/components/ui/switch.tsx +0 -27
  63. package/templates/components/ui/toast.tsx +0 -100
  64. package/templates/sections/cta.tsx +0 -22
  65. package/templates/sections/feature-grid.tsx +0 -62
  66. package/templates/sections/hero.tsx +0 -63
  67. package/templates/wrappers/border-wrapper.tsx +0 -34
  68. package/templates/wrappers/glow-wrapper.tsx +0 -31
  69. package/templates/wrappers/lift-wrapper.tsx +0 -27
@@ -0,0 +1,248 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { cn } from "../../lib/utils";
5
+
6
+ type Axis = "y" | "x";
7
+
8
+ export type ScrollProgressState = {
9
+ /** 0..1 (clamped if clamp=true) */
10
+ progress: number;
11
+ /** Raw (can go <0 or >1 when clamp=false) */
12
+ rawProgress: number;
13
+ /** True if any part of the element intersects the viewport */
14
+ inView: boolean;
15
+ /** Element rect in viewport coordinates */
16
+ rect: DOMRect | null;
17
+ };
18
+
19
+ export interface ScrollProgressWrapProps
20
+ extends Omit<React.HTMLAttributes<HTMLDivElement>, "children" | "onProgress"> {
21
+ /** Render-prop child gets scroll progress state */
22
+ children: (state: ScrollProgressState) => React.ReactNode;
23
+
24
+ /** Scroll axis (default "y") */
25
+ axis?: Axis;
26
+
27
+ /**
28
+ * When progress should start/end.
29
+ * - "cover": progress=0 when element just enters, progress=1 when it just leaves (default)
30
+ * - "contain": progress=0 when element top hits viewport top, progress=1 when bottom hits viewport bottom
31
+ */
32
+ mode?: "cover" | "contain";
33
+
34
+ /** Clamp progress to 0..1 (default true) */
35
+ clamp?: boolean;
36
+
37
+ /**
38
+ * Call on every progress change (rAF throttled)
39
+ * Receives clamped progress.
40
+ */
41
+ onProgress?: (progress: number, state: ScrollProgressState) => void;
42
+
43
+ /**
44
+ * Additional offset (px) applied to viewport size.
45
+ * Useful to trigger earlier/later without rootMargin complexity.
46
+ * Default 0.
47
+ */
48
+ viewportOffset?: number;
49
+
50
+ /**
51
+ * Update frequency control. If true (default), uses requestAnimationFrame while scrolling/resizing.
52
+ * If false, uses scroll+resize events directly (still throttled by rAF internally).
53
+ */
54
+ raf?: boolean;
55
+
56
+ /**
57
+ * Debug overlay (default false)
58
+ * Shows progress and a small bar.
59
+ */
60
+ debug?: boolean;
61
+ }
62
+
63
+ function clamp01(n: number) {
64
+ if (n < 0) return 0;
65
+ if (n > 1) return 1;
66
+ return n;
67
+ }
68
+
69
+ function usePrefersReducedMotion(): boolean {
70
+ const [reduced, setReduced] = React.useState(false);
71
+
72
+ React.useEffect(() => {
73
+ if (typeof window === "undefined") return;
74
+ const media = window.matchMedia("(prefers-reduced-motion: reduce)");
75
+ const onChange = () => setReduced(media.matches);
76
+ onChange();
77
+ media.addEventListener?.("change", onChange);
78
+ return () => media.removeEventListener?.("change", onChange);
79
+ }, []);
80
+
81
+ return reduced;
82
+ }
83
+
84
+ /**
85
+ * ScrollProgressWrap
86
+ * Exposes element-local scroll progress (0..1) for timelines, progress bars, parallax, etc.
87
+ */
88
+ export function ScrollProgressWrap({
89
+ axis = "y",
90
+ mode = "cover",
91
+ clamp = true,
92
+ onProgress,
93
+ viewportOffset = 0,
94
+ raf = true,
95
+ debug = false,
96
+ className,
97
+ style,
98
+ children,
99
+ ...props
100
+ }: ScrollProgressWrapProps): React.JSX.Element {
101
+ const ref = React.useRef<HTMLDivElement | null>(null);
102
+ const reducedMotion = usePrefersReducedMotion();
103
+
104
+ const [state, setState] = React.useState<ScrollProgressState>({
105
+ progress: 0,
106
+ rawProgress: 0,
107
+ inView: false,
108
+ rect: null,
109
+ });
110
+
111
+ const last = React.useRef({
112
+ progress: Number.NaN,
113
+ rawProgress: Number.NaN,
114
+ inView: false,
115
+ });
116
+
117
+ const compute = React.useCallback(() => {
118
+ const el = ref.current;
119
+ if (!el) return;
120
+
121
+ const rect = el.getBoundingClientRect();
122
+
123
+ // viewport size with optional offset
124
+ const vw = window.innerWidth + viewportOffset * 2;
125
+ const vh = window.innerHeight + viewportOffset * 2;
126
+
127
+ // shift coordinates if viewportOffset is used (simulate bigger viewport)
128
+ const top = rect.top - viewportOffset;
129
+ const left = rect.left - viewportOffset;
130
+
131
+ const size = axis === "y" ? rect.height : rect.width;
132
+ const viewportSize = axis === "y" ? vh : vw;
133
+ const start = axis === "y" ? top : left;
134
+ const end = start + size;
135
+
136
+ const inView = end > 0 && start < viewportSize;
137
+
138
+ let rawProgress: number;
139
+
140
+ if (mode === "cover") {
141
+ // progress from "just entering" (end=0) to "just leaving" (start=viewport)
142
+ // When element end touches 0 => progress 0
143
+ // When element start touches viewport => progress 1
144
+ const denom = size + viewportSize || 1;
145
+ rawProgress = (viewportSize - start) / denom;
146
+ } else {
147
+ // "contain": from top hits viewport top to bottom hits viewport bottom
148
+ // top=0 => 0, bottom=viewport => 1
149
+ const denom = Math.max(1, viewportSize - size);
150
+ rawProgress = (-start) / denom;
151
+ }
152
+
153
+ const progress = clamp ? clamp01(rawProgress) : rawProgress;
154
+
155
+ // avoid excessive re-renders
156
+ const changed =
157
+ progress !== last.current.progress ||
158
+ rawProgress !== last.current.rawProgress ||
159
+ inView !== last.current.inView;
160
+
161
+ if (!changed) return;
162
+
163
+ last.current = { progress, rawProgress, inView };
164
+
165
+ const next: ScrollProgressState = {
166
+ progress,
167
+ rawProgress,
168
+ inView,
169
+ rect,
170
+ };
171
+
172
+ setState(next);
173
+ onProgress?.(progress, next);
174
+ }, [axis, mode, clamp, onProgress, viewportOffset]);
175
+
176
+ React.useEffect(() => {
177
+ if (typeof window === "undefined") return;
178
+
179
+ // Reduced motion doesn't mean "no updates", but we can still compute normally.
180
+ // Keeping this here in case you want to short-circuit later:
181
+ // if (reducedMotion) return;
182
+
183
+ let ticking = false;
184
+
185
+ const schedule = () => {
186
+ if (ticking) return;
187
+ ticking = true;
188
+ requestAnimationFrame(() => {
189
+ ticking = false;
190
+ compute();
191
+ });
192
+ };
193
+
194
+ // initial
195
+ schedule();
196
+
197
+ const onScroll = () => schedule();
198
+ const onResize = () => schedule();
199
+
200
+ window.addEventListener("scroll", onScroll, { passive: true });
201
+ window.addEventListener("resize", onResize);
202
+
203
+ // If raf=true, we also keep things smooth during momentum scrolling on some devices
204
+ // by scheduling repeatedly while the page is scrolling.
205
+ // We still only update when events fire, but rAF ensures we render at the right time.
206
+ // (If you want "always-on" tracking, we can add an optional loop mode later.)
207
+ return () => {
208
+ window.removeEventListener("scroll", onScroll);
209
+ window.removeEventListener("resize", onResize);
210
+ };
211
+ }, [compute, reducedMotion, raf]);
212
+
213
+ return (
214
+ <div
215
+ ref={ref}
216
+ {...props}
217
+ className={cn("relative", className)}
218
+ style={style}
219
+ >
220
+ {children(state)}
221
+
222
+ {debug ? (
223
+ <div className="pointer-events-none absolute right-3 top-3 z-10 w-36 rounded-xl border border-border/60 bg-background/80 p-3 text-[11px] text-muted-foreground shadow-sm backdrop-blur">
224
+ <div className="flex items-center justify-between">
225
+ <span>progress</span>
226
+ <span className="font-medium text-foreground">
227
+ {Math.round(state.progress * 100)}%
228
+ </span>
229
+ </div>
230
+ <div className="mt-2 h-2 w-full overflow-hidden rounded-full bg-muted">
231
+ <div
232
+ className="h-full bg-foreground"
233
+ style={{ width: `${clamp01(state.progress) * 100}%` }}
234
+ />
235
+ </div>
236
+ <div className="mt-2 flex items-center justify-between">
237
+ <span>inView</span>
238
+ <span className="font-medium text-foreground">
239
+ {state.inView ? "true" : "false"}
240
+ </span>
241
+ </div>
242
+ </div>
243
+ ) : null}
244
+ </div>
245
+ );
246
+ }
247
+
248
+ ScrollProgressWrap.displayName = "ScrollProgressWrap";
@@ -0,0 +1,136 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { cn } from "@/lib/utils"
5
+
6
+ type RevealDirection = "up" | "down" | "left" | "right" | "none"
7
+
8
+ export interface RevealWrapProps
9
+ extends React.HTMLAttributes<HTMLDivElement> {
10
+ /** Reveal only once (default true) */
11
+ once?: boolean
12
+
13
+ /** IntersectionObserver threshold (default 0.2) */
14
+ threshold?: number
15
+
16
+ /** IntersectionObserver rootMargin (default "0px 0px -10% 0px") */
17
+ rootMargin?: string
18
+
19
+ /** Transition delay in ms (default 0) */
20
+ delay?: number
21
+
22
+ /** Transition duration in ms (default 600) */
23
+ duration?: number
24
+
25
+ /** Direction to reveal from (default "up") */
26
+ direction?: RevealDirection
27
+
28
+ /** Offset distance in px (default 18) */
29
+ distance?: number
30
+ }
31
+
32
+ function usePrefersReducedMotion(): boolean {
33
+ const [reduced, setReduced] = React.useState(false)
34
+
35
+ React.useEffect(() => {
36
+ if (typeof window === "undefined") return
37
+ const media = window.matchMedia("(prefers-reduced-motion: reduce)")
38
+ const onChange = () => setReduced(media.matches)
39
+ onChange()
40
+ media.addEventListener?.("change", onChange)
41
+ return () => media.removeEventListener?.("change", onChange)
42
+ }, [])
43
+
44
+ return reduced
45
+ }
46
+
47
+ export function RevealWrap({
48
+ once = true,
49
+ threshold = 0.2,
50
+ rootMargin = "0px 0px -10% 0px",
51
+ delay = 0,
52
+ duration = 600,
53
+ direction = "up",
54
+ distance = 18,
55
+ className,
56
+ style,
57
+ children,
58
+ ...props
59
+ }: RevealWrapProps): React.JSX.Element {
60
+ const ref = React.useRef<HTMLDivElement | null>(null)
61
+ const [visible, setVisible] = React.useState(false)
62
+ const reducedMotion = usePrefersReducedMotion()
63
+
64
+ React.useEffect(() => {
65
+ if (reducedMotion) {
66
+ setVisible(true)
67
+ return
68
+ }
69
+
70
+ const el = ref.current
71
+ if (!el) return
72
+
73
+ if (typeof IntersectionObserver === "undefined") {
74
+ setVisible(true)
75
+ return
76
+ }
77
+
78
+ const observer = new IntersectionObserver(
79
+ (entries) => {
80
+ const entry = entries[0]
81
+ if (!entry) return
82
+
83
+ if (entry.isIntersecting) {
84
+ setVisible(true)
85
+ if (once) observer.unobserve(entry.target)
86
+ } else if (!once) {
87
+ setVisible(false)
88
+ }
89
+ },
90
+ { threshold, rootMargin }
91
+ )
92
+
93
+ observer.observe(el)
94
+ return () => observer.disconnect()
95
+ }, [once, threshold, rootMargin, reducedMotion])
96
+
97
+ const clampedDistance = Math.max(0, distance)
98
+ const clampedDuration = Math.max(0, duration)
99
+ const clampedDelay = Math.max(0, delay)
100
+
101
+ const offsetClass =
102
+ direction === "up"
103
+ ? "translate-y-[var(--reveal-distance)]"
104
+ : direction === "down"
105
+ ? "-translate-y-[var(--reveal-distance)]"
106
+ : direction === "left"
107
+ ? "translate-x-[var(--reveal-distance)]"
108
+ : direction === "right"
109
+ ? "-translate-x-[var(--reveal-distance)]"
110
+ : ""
111
+
112
+ return (
113
+ <div
114
+ ref={ref}
115
+ {...props}
116
+ className={cn(
117
+ "transition-[opacity,transform] ease-out will-change-[opacity,transform]",
118
+ "motion-reduce:transition-none motion-reduce:transform-none",
119
+ visible
120
+ ? "opacity-100 translate-x-0 translate-y-0"
121
+ : cn("opacity-0", offsetClass),
122
+ className
123
+ )}
124
+ style={{
125
+ "--reveal-distance": `${clampedDistance}px`,
126
+ transitionDuration: `${clampedDuration}ms`,
127
+ transitionDelay: `${clampedDelay}ms`,
128
+ ...style,
129
+ } as React.CSSProperties}
130
+ >
131
+ {children}
132
+ </div>
133
+ )
134
+ }
135
+
136
+ RevealWrap.displayName = "RevealWrap"
package/LICENSE.md DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2023 shadcn
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
@@ -1,33 +0,0 @@
1
- import * as React from "react"
2
- import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
3
-
4
- import { cn } from "@/lib/utils"
5
-
6
- function CheckIcon(props: React.SVGProps<SVGSVGElement>) {
7
- return (
8
- <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" {...props}>
9
- <polyline points="3.5 8.5 6.5 11.5 12.5 4.5" />
10
- </svg>
11
- )
12
- }
13
-
14
- const Checkbox = React.forwardRef<
15
- React.ElementRef<typeof CheckboxPrimitive.Root>,
16
- React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
17
- >(({ className, ...props }, ref) => (
18
- <CheckboxPrimitive.Root
19
- ref={ref}
20
- className={cn(
21
- "peer h-4 w-4 shrink-0 rounded-sm border border-input bg-background shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
22
- className
23
- )}
24
- {...props}
25
- >
26
- <CheckboxPrimitive.Indicator className="flex items-center justify-center text-current">
27
- <CheckIcon className="h-3.5 w-3.5 stroke-[2.5]" />
28
- </CheckboxPrimitive.Indicator>
29
- </CheckboxPrimitive.Root>
30
- ))
31
- Checkbox.displayName = "Checkbox"
32
-
33
- export { Checkbox }
@@ -1,92 +0,0 @@
1
- import * as React from "react"
2
- import * as DialogPrimitive from "@radix-ui/react-dialog"
3
-
4
- import { cn } from "@/lib/utils"
5
-
6
- const Dialog = DialogPrimitive.Root
7
- const DialogTrigger = DialogPrimitive.Trigger
8
- const DialogClose = DialogPrimitive.Close
9
-
10
- const DialogOverlay = React.forwardRef<
11
- React.ElementRef<typeof DialogPrimitive.Overlay>,
12
- React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
13
- >(({ className, ...props }, ref) => (
14
- <DialogPrimitive.Overlay
15
- ref={ref}
16
- className={cn("fixed inset-0 z-50 bg-black/50", className)}
17
- {...props}
18
- />
19
- ))
20
- DialogOverlay.displayName = "DialogOverlay"
21
-
22
- const DialogContent = React.forwardRef<
23
- React.ElementRef<typeof DialogPrimitive.Content>,
24
- React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
25
- >(({ className, ...props }, ref) => (
26
- <DialogPrimitive.Portal>
27
- <DialogOverlay />
28
- <DialogPrimitive.Content
29
- ref={ref}
30
- className={cn(
31
- "fixed left-1/2 top-1/2 z-50 w-full max-w-lg -translate-x-1/2 -translate-y-1/2 rounded-lg border border-border bg-background p-6 shadow-lg focus-visible:outline-none",
32
- className
33
- )}
34
- {...props}
35
- />
36
- </DialogPrimitive.Portal>
37
- ))
38
- DialogContent.displayName = "DialogContent"
39
-
40
- const DialogHeader = ({
41
- className,
42
- ...props
43
- }: React.HTMLAttributes<HTMLDivElement>) => (
44
- <div className={cn("flex flex-col space-y-2 text-left", className)} {...props} />
45
- )
46
- DialogHeader.displayName = "DialogHeader"
47
-
48
- const DialogFooter = ({
49
- className,
50
- ...props
51
- }: React.HTMLAttributes<HTMLDivElement>) => (
52
- <div
53
- className={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)}
54
- {...props}
55
- />
56
- )
57
- DialogFooter.displayName = "DialogFooter"
58
-
59
- const DialogTitle = React.forwardRef<
60
- React.ElementRef<typeof DialogPrimitive.Title>,
61
- React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
62
- >(({ className, ...props }, ref) => (
63
- <DialogPrimitive.Title
64
- ref={ref}
65
- className={cn("text-lg font-semibold", className)}
66
- {...props}
67
- />
68
- ))
69
- DialogTitle.displayName = "DialogTitle"
70
-
71
- const DialogDescription = React.forwardRef<
72
- React.ElementRef<typeof DialogPrimitive.Description>,
73
- React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
74
- >(({ className, ...props }, ref) => (
75
- <DialogPrimitive.Description
76
- ref={ref}
77
- className={cn("text-sm text-muted-foreground", className)}
78
- {...props}
79
- />
80
- ))
81
- DialogDescription.displayName = "DialogDescription"
82
-
83
- export {
84
- Dialog,
85
- DialogTrigger,
86
- DialogClose,
87
- DialogContent,
88
- DialogHeader,
89
- DialogFooter,
90
- DialogTitle,
91
- DialogDescription
92
- }
@@ -1,75 +0,0 @@
1
- import * as React from "react"
2
- import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
3
-
4
- import { cn } from "@/lib/utils"
5
-
6
- const DropdownMenu = DropdownMenuPrimitive.Root
7
- const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
8
- const DropdownMenuGroup = DropdownMenuPrimitive.Group
9
-
10
- const DropdownMenuContent = React.forwardRef<
11
- React.ElementRef<typeof DropdownMenuPrimitive.Content>,
12
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
13
- >(({ className, sideOffset = 4, ...props }, ref) => (
14
- <DropdownMenuPrimitive.Portal>
15
- <DropdownMenuPrimitive.Content
16
- ref={ref}
17
- sideOffset={sideOffset}
18
- className={cn(
19
- "z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md",
20
- className
21
- )}
22
- {...props}
23
- />
24
- </DropdownMenuPrimitive.Portal>
25
- ))
26
- DropdownMenuContent.displayName = "DropdownMenuContent"
27
-
28
- const DropdownMenuItem = React.forwardRef<
29
- React.ElementRef<typeof DropdownMenuPrimitive.Item>,
30
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item>
31
- >(({ className, ...props }, ref) => (
32
- <DropdownMenuPrimitive.Item
33
- ref={ref}
34
- className={cn(
35
- "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
36
- className
37
- )}
38
- {...props}
39
- />
40
- ))
41
- DropdownMenuItem.displayName = "DropdownMenuItem"
42
-
43
- const DropdownMenuLabel = React.forwardRef<
44
- React.ElementRef<typeof DropdownMenuPrimitive.Label>,
45
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label>
46
- >(({ className, ...props }, ref) => (
47
- <DropdownMenuPrimitive.Label
48
- ref={ref}
49
- className={cn("px-2 py-1.5 text-xs font-semibold", className)}
50
- {...props}
51
- />
52
- ))
53
- DropdownMenuLabel.displayName = "DropdownMenuLabel"
54
-
55
- const DropdownMenuSeparator = React.forwardRef<
56
- React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
57
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
58
- >(({ className, ...props }, ref) => (
59
- <DropdownMenuPrimitive.Separator
60
- ref={ref}
61
- className={cn("-mx-1 my-1 h-px bg-border", className)}
62
- {...props}
63
- />
64
- ))
65
- DropdownMenuSeparator.displayName = "DropdownMenuSeparator"
66
-
67
- export {
68
- DropdownMenu,
69
- DropdownMenuTrigger,
70
- DropdownMenuContent,
71
- DropdownMenuItem,
72
- DropdownMenuLabel,
73
- DropdownMenuSeparator,
74
- DropdownMenuGroup
75
- }
@@ -1,24 +0,0 @@
1
- import * as React from "react"
2
-
3
- import { cn } from "@/lib/utils"
4
-
5
- export interface SelectProps
6
- extends React.SelectHTMLAttributes<HTMLSelectElement> {}
7
-
8
- const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
9
- ({ className, children, ...props }, ref) => (
10
- <select
11
- ref={ref}
12
- className={cn(
13
- "flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background disabled:cursor-not-allowed disabled:opacity-50",
14
- className
15
- )}
16
- {...props}
17
- >
18
- {children}
19
- </select>
20
- )
21
- )
22
- Select.displayName = "Select"
23
-
24
- export { Select }
@@ -1,27 +0,0 @@
1
- import * as React from "react"
2
- import * as SwitchPrimitive from "@radix-ui/react-switch"
3
-
4
- import { cn } from "@/lib/utils"
5
-
6
- const Switch = React.forwardRef<
7
- React.ElementRef<typeof SwitchPrimitive.Root>,
8
- React.ComponentPropsWithoutRef<typeof SwitchPrimitive.Root>
9
- >(({ className, ...props }, ref) => (
10
- <SwitchPrimitive.Root
11
- ref={ref}
12
- className={cn(
13
- "inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border border-input bg-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background data-[state=checked]:bg-primary",
14
- className
15
- )}
16
- {...props}
17
- >
18
- <SwitchPrimitive.Thumb
19
- className={
20
- "pointer-events-none block h-4 w-4 rounded-full bg-background shadow transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
21
- }
22
- />
23
- </SwitchPrimitive.Root>
24
- ))
25
- Switch.displayName = "Switch"
26
-
27
- export { Switch }