Skip to content

Commit 2e86990

Browse files
authored
Merge pull request #239 from Student-Activity-Center-IIIT-NR/dev
News ui change
2 parents c7bdceb + 1d73633 commit 2e86990

File tree

10 files changed

+3045
-1420
lines changed

10 files changed

+3045
-1420
lines changed

components.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"$schema": "https://ui.shadcn.com/schema.json",
3+
"style": "new-york",
4+
"rsc": false,
5+
"tsx": true,
6+
"tailwind": {
7+
"config": "",
8+
"css": "styles/globals.css",
9+
"baseColor": "stone",
10+
"cssVariables": true,
11+
"prefix": ""
12+
},
13+
"iconLibrary": "lucide",
14+
"aliases": {
15+
"components": "@/components",
16+
"utils": "@/lib/utils",
17+
"ui": "@/components/ui",
18+
"lib": "@/lib",
19+
"hooks": "@/hooks"
20+
},
21+
"registries": {}
22+
}

components/ui/button.tsx

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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 buttonVariants = cva(
8+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-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",
9+
{
10+
variants: {
11+
variant: {
12+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
13+
destructive:
14+
"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
15+
outline:
16+
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
17+
secondary:
18+
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
19+
ghost:
20+
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
21+
link: "text-primary underline-offset-4 hover:underline",
22+
},
23+
size: {
24+
default: "h-9 px-4 py-2 has-[>svg]:px-3",
25+
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
26+
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
27+
icon: "size-9",
28+
},
29+
},
30+
defaultVariants: {
31+
variant: "default",
32+
size: "default",
33+
},
34+
}
35+
)
36+
37+
function Button({
38+
className,
39+
variant,
40+
size,
41+
asChild = false,
42+
...props
43+
}: React.ComponentProps<"button"> &
44+
VariantProps<typeof buttonVariants> & {
45+
asChild?: boolean
46+
}) {
47+
const Comp = asChild ? Slot : "button"
48+
49+
return (
50+
<Comp
51+
data-slot="button"
52+
className={cn(buttonVariants({ variant, size, className }))}
53+
{...props}
54+
/>
55+
)
56+
}
57+
58+
export { Button, buttonVariants }

components/ui/carousel.tsx

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
import * as React from "react"
2+
import useEmblaCarousel, {
3+
type UseEmblaCarouselType,
4+
} from "embla-carousel-react"
5+
import { ArrowLeft, ArrowRight } from "lucide-react"
6+
7+
import { cn } from "@/lib/utils"
8+
import { Button } from "@/components/ui/button"
9+
10+
type CarouselApi = UseEmblaCarouselType[1]
11+
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
12+
type CarouselOptions = UseCarouselParameters[0]
13+
type CarouselPlugin = UseCarouselParameters[1]
14+
15+
type CarouselProps = {
16+
opts?: CarouselOptions
17+
plugins?: CarouselPlugin
18+
orientation?: "horizontal" | "vertical"
19+
setApi?: (api: CarouselApi) => void
20+
}
21+
22+
type CarouselContextProps = {
23+
carouselRef: ReturnType<typeof useEmblaCarousel>[0]
24+
api: ReturnType<typeof useEmblaCarousel>[1]
25+
scrollPrev: () => void
26+
scrollNext: () => void
27+
canScrollPrev: boolean
28+
canScrollNext: boolean
29+
} & CarouselProps
30+
31+
const CarouselContext = React.createContext<CarouselContextProps | null>(null)
32+
33+
function useCarousel() {
34+
const context = React.useContext(CarouselContext)
35+
36+
if (!context) {
37+
throw new Error("useCarousel must be used within a <Carousel />")
38+
}
39+
40+
return context
41+
}
42+
43+
function Carousel({
44+
orientation = "horizontal",
45+
opts,
46+
setApi,
47+
plugins,
48+
className,
49+
children,
50+
...props
51+
}: React.ComponentProps<"div"> & CarouselProps) {
52+
const [carouselRef, api] = useEmblaCarousel(
53+
{
54+
...opts,
55+
axis: orientation === "horizontal" ? "x" : "y",
56+
},
57+
plugins
58+
)
59+
const [canScrollPrev, setCanScrollPrev] = React.useState(false)
60+
const [canScrollNext, setCanScrollNext] = React.useState(false)
61+
62+
const onSelect = React.useCallback((api: CarouselApi) => {
63+
if (!api) return
64+
setCanScrollPrev(api.canScrollPrev())
65+
setCanScrollNext(api.canScrollNext())
66+
}, [])
67+
68+
const scrollPrev = React.useCallback(() => {
69+
api?.scrollPrev()
70+
}, [api])
71+
72+
const scrollNext = React.useCallback(() => {
73+
api?.scrollNext()
74+
}, [api])
75+
76+
const handleKeyDown = React.useCallback(
77+
(event: React.KeyboardEvent<HTMLDivElement>) => {
78+
if (event.key === "ArrowLeft") {
79+
event.preventDefault()
80+
scrollPrev()
81+
} else if (event.key === "ArrowRight") {
82+
event.preventDefault()
83+
scrollNext()
84+
}
85+
},
86+
[scrollPrev, scrollNext]
87+
)
88+
89+
React.useEffect(() => {
90+
if (!api || !setApi) return
91+
setApi(api)
92+
}, [api, setApi])
93+
94+
React.useEffect(() => {
95+
if (!api) return
96+
onSelect(api)
97+
api.on("reInit", onSelect)
98+
api.on("select", onSelect)
99+
100+
return () => {
101+
api?.off("select", onSelect)
102+
}
103+
}, [api, onSelect])
104+
105+
return (
106+
<CarouselContext.Provider
107+
value={{
108+
carouselRef,
109+
api: api,
110+
opts,
111+
orientation:
112+
orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
113+
scrollPrev,
114+
scrollNext,
115+
canScrollPrev,
116+
canScrollNext,
117+
}}
118+
>
119+
<div
120+
onKeyDownCapture={handleKeyDown}
121+
className={cn("relative", className)}
122+
role="region"
123+
aria-roledescription="carousel"
124+
data-slot="carousel"
125+
{...props}
126+
>
127+
{children}
128+
</div>
129+
</CarouselContext.Provider>
130+
)
131+
}
132+
133+
function CarouselContent({ className, ...props }: React.ComponentProps<"div">) {
134+
const { carouselRef, orientation } = useCarousel()
135+
136+
return (
137+
<div
138+
ref={carouselRef}
139+
className="overflow-hidden"
140+
data-slot="carousel-content"
141+
>
142+
<div
143+
className={cn(
144+
"flex",
145+
orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
146+
className
147+
)}
148+
{...props}
149+
/>
150+
</div>
151+
)
152+
}
153+
154+
function CarouselItem({ className, ...props }: React.ComponentProps<"div">) {
155+
const { orientation } = useCarousel()
156+
157+
return (
158+
<div
159+
role="group"
160+
aria-roledescription="slide"
161+
data-slot="carousel-item"
162+
className={cn(
163+
"min-w-0 shrink-0 grow-0 basis-full",
164+
orientation === "horizontal" ? "pl-4" : "pt-4",
165+
className
166+
)}
167+
{...props}
168+
/>
169+
)
170+
}
171+
172+
function CarouselPrevious({
173+
className,
174+
variant = "outline",
175+
size = "icon",
176+
...props
177+
}: React.ComponentProps<typeof Button>) {
178+
const { orientation, scrollPrev, canScrollPrev } = useCarousel()
179+
180+
return (
181+
<Button
182+
data-slot="carousel-previous"
183+
variant={variant}
184+
size={size}
185+
className={cn(
186+
"absolute size-8 rounded-full",
187+
orientation === "horizontal"
188+
? "top-1/2 -left-12 -translate-y-1/2"
189+
: "-top-12 left-1/2 -translate-x-1/2 rotate-90",
190+
className
191+
)}
192+
disabled={!canScrollPrev}
193+
onClick={scrollPrev}
194+
{...props}
195+
>
196+
<ArrowLeft />
197+
<span className="sr-only">Previous slide</span>
198+
</Button>
199+
)
200+
}
201+
202+
function CarouselNext({
203+
className,
204+
variant = "outline",
205+
size = "icon",
206+
...props
207+
}: React.ComponentProps<typeof Button>) {
208+
const { orientation, scrollNext, canScrollNext } = useCarousel()
209+
210+
return (
211+
<Button
212+
data-slot="carousel-next"
213+
variant={variant}
214+
size={size}
215+
className={cn(
216+
"absolute size-8 rounded-full",
217+
orientation === "horizontal"
218+
? "top-1/2 -right-12 -translate-y-1/2"
219+
: "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
220+
className
221+
)}
222+
disabled={!canScrollNext}
223+
onClick={scrollNext}
224+
{...props}
225+
>
226+
<ArrowRight />
227+
<span className="sr-only">Next slide</span>
228+
</Button>
229+
)
230+
}
231+
232+
export {
233+
type CarouselApi,
234+
Carousel,
235+
CarouselContent,
236+
CarouselItem,
237+
CarouselPrevious,
238+
CarouselNext,
239+
}

0 commit comments

Comments
 (0)