@srcroot/ui 0.0.1
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/README.md +151 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +640 -0
- package/package.json +43 -0
- package/registry/accordion.tsx +158 -0
- package/registry/alert-dialog.tsx +206 -0
- package/registry/alert.tsx +73 -0
- package/registry/aspect-ratio.tsx +44 -0
- package/registry/avatar.tsx +94 -0
- package/registry/badge.tsx +68 -0
- package/registry/breadcrumb.tsx +151 -0
- package/registry/button-group.tsx +84 -0
- package/registry/button.tsx +102 -0
- package/registry/calendar.tsx +238 -0
- package/registry/card.tsx +114 -0
- package/registry/carousel.tsx +169 -0
- package/registry/checkbox.tsx +79 -0
- package/registry/collapsible.tsx +110 -0
- package/registry/container.tsx +60 -0
- package/registry/dialog.tsx +264 -0
- package/registry/dropdown-menu.tsx +387 -0
- package/registry/image.tsx +144 -0
- package/registry/input.tsx +44 -0
- package/registry/label.tsx +34 -0
- package/registry/loading-spinner.tsx +108 -0
- package/registry/otp-input.tsx +152 -0
- package/registry/pagination.tsx +146 -0
- package/registry/popover.tsx +135 -0
- package/registry/progress.tsx +49 -0
- package/registry/radio.tsx +99 -0
- package/registry/search.tsx +146 -0
- package/registry/select.tsx +190 -0
- package/registry/separator.tsx +44 -0
- package/registry/sheet.tsx +180 -0
- package/registry/skeleton.tsx +26 -0
- package/registry/slider.tsx +115 -0
- package/registry/star-rating.tsx +131 -0
- package/registry/switch.tsx +70 -0
- package/registry/table.tsx +136 -0
- package/registry/tabs.tsx +122 -0
- package/registry/text.tsx +70 -0
- package/registry/textarea.tsx +39 -0
- package/registry/toast.tsx +95 -0
- package/registry/tooltip.tsx +122 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
3
|
+
import { cn } from "@/lib/utils"
|
|
4
|
+
|
|
5
|
+
const toastVariants = cva(
|
|
6
|
+
"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",
|
|
7
|
+
{
|
|
8
|
+
variants: {
|
|
9
|
+
variant: {
|
|
10
|
+
default: "border bg-background text-foreground",
|
|
11
|
+
destructive:
|
|
12
|
+
"destructive group border-destructive bg-destructive text-destructive-foreground",
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
defaultVariants: {
|
|
16
|
+
variant: "default",
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
interface ToastProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof toastVariants> {
|
|
22
|
+
onClose?: () => void
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Toast notification component
|
|
27
|
+
*
|
|
28
|
+
* For a complete toast system, use with a ToastProvider context.
|
|
29
|
+
* This is the individual toast component.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* <Toast variant="default">
|
|
33
|
+
* <ToastTitle>Success</ToastTitle>
|
|
34
|
+
* <ToastDescription>Your action was completed.</ToastDescription>
|
|
35
|
+
* </Toast>
|
|
36
|
+
*/
|
|
37
|
+
const Toast = React.forwardRef<HTMLDivElement, ToastProps>(
|
|
38
|
+
({ className, variant, onClose, children, ...props }, ref) => {
|
|
39
|
+
return (
|
|
40
|
+
<div
|
|
41
|
+
ref={ref}
|
|
42
|
+
role={variant === "destructive" ? "alert" : "status"}
|
|
43
|
+
aria-live={variant === "destructive" ? "assertive" : "polite"}
|
|
44
|
+
className={cn(toastVariants({ variant }), className)}
|
|
45
|
+
{...props}
|
|
46
|
+
>
|
|
47
|
+
<div className="grid gap-1">{children}</div>
|
|
48
|
+
{onClose && (
|
|
49
|
+
<button
|
|
50
|
+
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"
|
|
51
|
+
onClick={onClose}
|
|
52
|
+
>
|
|
53
|
+
<svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
|
54
|
+
<path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
|
|
55
|
+
</svg>
|
|
56
|
+
</button>
|
|
57
|
+
)}
|
|
58
|
+
</div>
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
Toast.displayName = "Toast"
|
|
63
|
+
|
|
64
|
+
const ToastTitle = React.forwardRef<
|
|
65
|
+
HTMLDivElement,
|
|
66
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
67
|
+
>(({ className, ...props }, ref) => (
|
|
68
|
+
<div ref={ref} className={cn("text-sm font-semibold [&+div]:text-xs", className)} {...props} />
|
|
69
|
+
))
|
|
70
|
+
ToastTitle.displayName = "ToastTitle"
|
|
71
|
+
|
|
72
|
+
const ToastDescription = React.forwardRef<
|
|
73
|
+
HTMLDivElement,
|
|
74
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
75
|
+
>(({ className, ...props }, ref) => (
|
|
76
|
+
<div ref={ref} className={cn("text-sm opacity-90", className)} {...props} />
|
|
77
|
+
))
|
|
78
|
+
ToastDescription.displayName = "ToastDescription"
|
|
79
|
+
|
|
80
|
+
const ToastAction = React.forwardRef<
|
|
81
|
+
HTMLButtonElement,
|
|
82
|
+
React.ButtonHTMLAttributes<HTMLButtonElement>
|
|
83
|
+
>(({ className, ...props }, ref) => (
|
|
84
|
+
<button
|
|
85
|
+
ref={ref}
|
|
86
|
+
className={cn(
|
|
87
|
+
"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",
|
|
88
|
+
className
|
|
89
|
+
)}
|
|
90
|
+
{...props}
|
|
91
|
+
/>
|
|
92
|
+
))
|
|
93
|
+
ToastAction.displayName = "ToastAction"
|
|
94
|
+
|
|
95
|
+
export { Toast, ToastTitle, ToastDescription, ToastAction, toastVariants }
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { cn } from "@/lib/utils"
|
|
3
|
+
|
|
4
|
+
interface TooltipContextValue {
|
|
5
|
+
open: boolean
|
|
6
|
+
setOpen: (open: boolean) => void
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const TooltipContext = React.createContext<TooltipContextValue | null>(null)
|
|
10
|
+
|
|
11
|
+
interface TooltipProviderProps {
|
|
12
|
+
children: React.ReactNode
|
|
13
|
+
delayDuration?: number
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* TooltipProvider wraps your app to enable tooltips
|
|
18
|
+
*/
|
|
19
|
+
function TooltipProvider({ children }: TooltipProviderProps) {
|
|
20
|
+
return <>{children}</>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface TooltipProps {
|
|
24
|
+
children: React.ReactNode
|
|
25
|
+
open?: boolean
|
|
26
|
+
onOpenChange?: (open: boolean) => void
|
|
27
|
+
defaultOpen?: boolean
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Tooltip component for hover hints
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* <TooltipProvider>
|
|
35
|
+
* <Tooltip>
|
|
36
|
+
* <TooltipTrigger>Hover me</TooltipTrigger>
|
|
37
|
+
* <TooltipContent>Tooltip text</TooltipContent>
|
|
38
|
+
* </Tooltip>
|
|
39
|
+
* </TooltipProvider>
|
|
40
|
+
*/
|
|
41
|
+
function Tooltip({ children, open: controlledOpen, onOpenChange, defaultOpen = false }: TooltipProps) {
|
|
42
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen)
|
|
43
|
+
|
|
44
|
+
const open = controlledOpen !== undefined ? controlledOpen : uncontrolledOpen
|
|
45
|
+
const setOpen = onOpenChange || setUncontrolledOpen
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<TooltipContext.Provider value={{ open, setOpen }}>
|
|
49
|
+
<span className="relative inline-block">
|
|
50
|
+
{children}
|
|
51
|
+
</span>
|
|
52
|
+
</TooltipContext.Provider>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface TooltipTriggerProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
57
|
+
asChild?: boolean
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const TooltipTrigger = React.forwardRef<HTMLSpanElement, TooltipTriggerProps>(
|
|
61
|
+
({ children, asChild, ...props }, ref) => {
|
|
62
|
+
const context = React.useContext(TooltipContext)
|
|
63
|
+
if (!context) throw new Error("TooltipTrigger must be used within Tooltip")
|
|
64
|
+
|
|
65
|
+
const handleMouseEnter = () => context.setOpen(true)
|
|
66
|
+
const handleMouseLeave = () => context.setOpen(false)
|
|
67
|
+
const handleFocus = () => context.setOpen(true)
|
|
68
|
+
const handleBlur = () => context.setOpen(false)
|
|
69
|
+
|
|
70
|
+
if (asChild && React.isValidElement(children)) {
|
|
71
|
+
return React.cloneElement(children as React.ReactElement<any>, {
|
|
72
|
+
onMouseEnter: handleMouseEnter,
|
|
73
|
+
onMouseLeave: handleMouseLeave,
|
|
74
|
+
onFocus: handleFocus,
|
|
75
|
+
onBlur: handleBlur,
|
|
76
|
+
ref,
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<span
|
|
82
|
+
ref={ref}
|
|
83
|
+
onMouseEnter={handleMouseEnter}
|
|
84
|
+
onMouseLeave={handleMouseLeave}
|
|
85
|
+
onFocus={handleFocus}
|
|
86
|
+
onBlur={handleBlur}
|
|
87
|
+
tabIndex={0}
|
|
88
|
+
{...props}
|
|
89
|
+
>
|
|
90
|
+
{children}
|
|
91
|
+
</span>
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
)
|
|
95
|
+
TooltipTrigger.displayName = "TooltipTrigger"
|
|
96
|
+
|
|
97
|
+
const TooltipContent = React.forwardRef<
|
|
98
|
+
HTMLDivElement,
|
|
99
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
100
|
+
>(({ className, children, ...props }, ref) => {
|
|
101
|
+
const context = React.useContext(TooltipContext)
|
|
102
|
+
if (!context) throw new Error("TooltipContent must be used within Tooltip")
|
|
103
|
+
|
|
104
|
+
if (!context.open) return null
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<div
|
|
108
|
+
ref={ref}
|
|
109
|
+
role="tooltip"
|
|
110
|
+
className={cn(
|
|
111
|
+
"absolute left-1/2 bottom-full z-50 mb-2 -translate-x-1/2 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95",
|
|
112
|
+
className
|
|
113
|
+
)}
|
|
114
|
+
{...props}
|
|
115
|
+
>
|
|
116
|
+
{children}
|
|
117
|
+
</div>
|
|
118
|
+
)
|
|
119
|
+
})
|
|
120
|
+
TooltipContent.displayName = "TooltipContent"
|
|
121
|
+
|
|
122
|
+
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
|