Skip to content

Commit 550bf14

Browse files
Merge pull request #15 from codersforcauses/Kerry-Components
Shadcn components added
2 parents e59e19d + 62d7c7e commit 550bf14

11 files changed

Lines changed: 1780 additions & 0 deletions

File tree

client/src/components/ui/alert.tsx

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import * as React from "react"
2+
import { cva, type VariantProps } from "class-variance-authority"
3+
4+
import { cn } from "@/lib/utils"
5+
6+
const alertVariants = cva(
7+
"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",
8+
{
9+
variants: {
10+
variant: {
11+
default: "bg-card text-card-foreground",
12+
destructive:
13+
"text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90",
14+
},
15+
},
16+
defaultVariants: {
17+
variant: "default",
18+
},
19+
}
20+
)
21+
22+
function Alert({
23+
className,
24+
variant,
25+
...props
26+
}: React.ComponentProps<"div"> & VariantProps<typeof alertVariants>) {
27+
return (
28+
<div
29+
data-slot="alert"
30+
role="alert"
31+
className={cn(alertVariants({ variant }), className)}
32+
{...props}
33+
/>
34+
)
35+
}
36+
37+
function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
38+
return (
39+
<div
40+
data-slot="alert-title"
41+
className={cn(
42+
"col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight",
43+
className
44+
)}
45+
{...props}
46+
/>
47+
)
48+
}
49+
50+
function AlertDescription({
51+
className,
52+
...props
53+
}: React.ComponentProps<"div">) {
54+
return (
55+
<div
56+
data-slot="alert-description"
57+
className={cn(
58+
"text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed",
59+
className
60+
)}
61+
{...props}
62+
/>
63+
)
64+
}
65+
66+
export { Alert, AlertTitle, AlertDescription }
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
"use client"
2+
3+
import * as React from "react"
4+
import * as AvatarPrimitive from "@radix-ui/react-avatar"
5+
6+
import { cn } from "@/lib/utils"
7+
8+
function Avatar({
9+
className,
10+
...props
11+
}: React.ComponentProps<typeof AvatarPrimitive.Root>) {
12+
return (
13+
<AvatarPrimitive.Root
14+
data-slot="avatar"
15+
className={cn(
16+
"relative flex size-8 shrink-0 overflow-hidden rounded-full",
17+
className
18+
)}
19+
{...props}
20+
/>
21+
)
22+
}
23+
24+
function AvatarImage({
25+
className,
26+
...props
27+
}: React.ComponentProps<typeof AvatarPrimitive.Image>) {
28+
return (
29+
<AvatarPrimitive.Image
30+
data-slot="avatar-image"
31+
className={cn("aspect-square size-full", className)}
32+
{...props}
33+
/>
34+
)
35+
}
36+
37+
function AvatarFallback({
38+
className,
39+
...props
40+
}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
41+
return (
42+
<AvatarPrimitive.Fallback
43+
data-slot="avatar-fallback"
44+
className={cn(
45+
"bg-muted flex size-full items-center justify-center rounded-full",
46+
className
47+
)}
48+
{...props}
49+
/>
50+
)
51+
}
52+
53+
export { Avatar, AvatarImage, AvatarFallback }

client/src/components/ui/badge.tsx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import * as React from "react"
2+
import { Slot } from "@radix-ui/react-slot"
3+
import { cva, type VariantProps } from "class-variance-authority"
4+
5+
import { cn } from "@/lib/utils"
6+
7+
const badgeVariants = cva(
8+
"inline-flex items-center justify-center rounded-full 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",
9+
{
10+
variants: {
11+
variant: {
12+
default:
13+
"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
14+
secondary:
15+
"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
16+
destructive:
17+
"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",
18+
outline:
19+
"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
20+
},
21+
},
22+
defaultVariants: {
23+
variant: "default",
24+
},
25+
}
26+
)
27+
28+
function Badge({
29+
className,
30+
variant,
31+
asChild = false,
32+
...props
33+
}: React.ComponentProps<"span"> &
34+
VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
35+
const Comp = asChild ? Slot : "span"
36+
37+
return (
38+
<Comp
39+
data-slot="badge"
40+
className={cn(badgeVariants({ variant }), className)}
41+
{...props}
42+
/>
43+
)
44+
}
45+
46+
export { Badge, badgeVariants }
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
"use client"
2+
3+
import * as React from "react"
4+
import {
5+
ChevronDownIcon,
6+
ChevronLeftIcon,
7+
ChevronRightIcon,
8+
} from "lucide-react"
9+
import {
10+
DayPicker,
11+
getDefaultClassNames,
12+
type DayButton,
13+
} from "react-day-picker"
14+
15+
import { cn } from "@/lib/utils"
16+
import { Button, buttonVariants } from "@/components/ui/button"
17+
18+
function Calendar({
19+
className,
20+
classNames,
21+
showOutsideDays = true,
22+
captionLayout = "label",
23+
buttonVariant = "ghost",
24+
formatters,
25+
components,
26+
...props
27+
}: React.ComponentProps<typeof DayPicker> & {
28+
buttonVariant?: React.ComponentProps<typeof Button>["variant"]
29+
}) {
30+
const defaultClassNames = getDefaultClassNames()
31+
32+
return (
33+
<DayPicker
34+
showOutsideDays={showOutsideDays}
35+
className={cn(
36+
"bg-background group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
37+
String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
38+
String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
39+
className
40+
)}
41+
captionLayout={captionLayout}
42+
formatters={{
43+
formatMonthDropdown: (date) =>
44+
date.toLocaleString("default", { month: "short" }),
45+
...formatters,
46+
}}
47+
classNames={{
48+
root: cn("w-fit", defaultClassNames.root),
49+
months: cn(
50+
"flex gap-4 flex-col md:flex-row relative",
51+
defaultClassNames.months
52+
),
53+
month: cn("flex flex-col w-full gap-4", defaultClassNames.month),
54+
nav: cn(
55+
"flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between",
56+
defaultClassNames.nav
57+
),
58+
button_previous: cn(
59+
buttonVariants({ variant: buttonVariant }),
60+
"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
61+
defaultClassNames.button_previous
62+
),
63+
button_next: cn(
64+
buttonVariants({ variant: buttonVariant }),
65+
"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
66+
defaultClassNames.button_next
67+
),
68+
month_caption: cn(
69+
"flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)",
70+
defaultClassNames.month_caption
71+
),
72+
dropdowns: cn(
73+
"w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5",
74+
defaultClassNames.dropdowns
75+
),
76+
dropdown_root: cn(
77+
"relative has-focus:border-ring border border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] rounded-md",
78+
defaultClassNames.dropdown_root
79+
),
80+
dropdown: cn(
81+
"absolute bg-popover inset-0 opacity-0",
82+
defaultClassNames.dropdown
83+
),
84+
caption_label: cn(
85+
"select-none font-medium",
86+
captionLayout === "label"
87+
? "text-sm"
88+
: "rounded-md pl-2 pr-1 flex items-center gap-1 text-sm h-8 [&>svg]:text-muted-foreground [&>svg]:size-3.5",
89+
defaultClassNames.caption_label
90+
),
91+
table: "w-full border-collapse",
92+
weekdays: cn("flex", defaultClassNames.weekdays),
93+
weekday: cn(
94+
"text-muted-foreground rounded-md flex-1 font-normal text-[0.8rem] select-none",
95+
defaultClassNames.weekday
96+
),
97+
week: cn("flex w-full mt-2", defaultClassNames.week),
98+
week_number_header: cn(
99+
"select-none w-(--cell-size)",
100+
defaultClassNames.week_number_header
101+
),
102+
week_number: cn(
103+
"text-[0.8rem] select-none text-muted-foreground",
104+
defaultClassNames.week_number
105+
),
106+
day: cn(
107+
"relative w-full h-full p-0 text-center [&:last-child[data-selected=true]_button]:rounded-r-md group/day aspect-square select-none",
108+
props.showWeekNumber
109+
? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-md"
110+
: "[&:first-child[data-selected=true]_button]:rounded-l-md",
111+
defaultClassNames.day
112+
),
113+
range_start: cn(
114+
"rounded-l-md bg-accent",
115+
defaultClassNames.range_start
116+
),
117+
range_middle: cn("rounded-none", defaultClassNames.range_middle),
118+
range_end: cn("rounded-r-md bg-accent", defaultClassNames.range_end),
119+
today: cn(
120+
"bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none",
121+
defaultClassNames.today
122+
),
123+
outside: cn(
124+
"text-muted-foreground aria-selected:text-muted-foreground",
125+
defaultClassNames.outside
126+
),
127+
disabled: cn(
128+
"text-muted-foreground opacity-50",
129+
defaultClassNames.disabled
130+
),
131+
hidden: cn("invisible", defaultClassNames.hidden),
132+
...classNames,
133+
}}
134+
components={{
135+
Root: ({ className, rootRef, ...props }) => {
136+
return (
137+
<div
138+
data-slot="calendar"
139+
ref={rootRef}
140+
className={cn(className)}
141+
{...props}
142+
/>
143+
)
144+
},
145+
Chevron: ({ className, orientation, ...props }) => {
146+
if (orientation === "left") {
147+
return (
148+
<ChevronLeftIcon className={cn("size-4", className)} {...props} />
149+
)
150+
}
151+
152+
if (orientation === "right") {
153+
return (
154+
<ChevronRightIcon
155+
className={cn("size-4", className)}
156+
{...props}
157+
/>
158+
)
159+
}
160+
161+
return (
162+
<ChevronDownIcon className={cn("size-4", className)} {...props} />
163+
)
164+
},
165+
DayButton: CalendarDayButton,
166+
WeekNumber: ({ children, ...props }) => {
167+
return (
168+
<td {...props}>
169+
<div className="flex size-(--cell-size) items-center justify-center text-center">
170+
{children}
171+
</div>
172+
</td>
173+
)
174+
},
175+
...components,
176+
}}
177+
{...props}
178+
/>
179+
)
180+
}
181+
182+
function CalendarDayButton({
183+
className,
184+
day,
185+
modifiers,
186+
...props
187+
}: React.ComponentProps<typeof DayButton>) {
188+
const defaultClassNames = getDefaultClassNames()
189+
190+
const ref = React.useRef<HTMLButtonElement>(null)
191+
React.useEffect(() => {
192+
if (modifiers.focused) ref.current?.focus()
193+
}, [modifiers.focused])
194+
195+
return (
196+
<Button
197+
ref={ref}
198+
variant="ghost"
199+
size="icon"
200+
data-day={day.date.toLocaleDateString()}
201+
data-selected-single={
202+
modifiers.selected &&
203+
!modifiers.range_start &&
204+
!modifiers.range_end &&
205+
!modifiers.range_middle
206+
}
207+
data-range-start={modifiers.range_start}
208+
data-range-end={modifiers.range_end}
209+
data-range-middle={modifiers.range_middle}
210+
className={cn(
211+
"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",
212+
defaultClassNames.day,
213+
className
214+
)}
215+
{...props}
216+
/>
217+
)
218+
}
219+
220+
export { Calendar, CalendarDayButton }

0 commit comments

Comments
 (0)