idk, working on showcase XD
This commit is contained in:
		@@ -17,12 +17,15 @@
 | 
			
		||||
    "@astrojs/sitemap": "^3.1.1",
 | 
			
		||||
    "@astrojs/tailwind": "^5.1.0",
 | 
			
		||||
    "@radix-ui/react-dropdown-menu": "^2.0.6",
 | 
			
		||||
    "@radix-ui/react-slot": "^1.0.2",
 | 
			
		||||
    "@radix-ui/react-tabs": "^1.0.4",
 | 
			
		||||
    "@types/react": "^18.2.74",
 | 
			
		||||
    "@types/react-dom": "^18.2.24",
 | 
			
		||||
    "astro": "^4.5.6",
 | 
			
		||||
    "class-variance-authority": "^0.7.0",
 | 
			
		||||
    "clsx": "^2.1.0",
 | 
			
		||||
    "cmdk": "^1.0.0",
 | 
			
		||||
    "embla-carousel-react": "^8.0.2",
 | 
			
		||||
    "lucide-react": "^0.365.0",
 | 
			
		||||
    "react": "^18.2.0",
 | 
			
		||||
    "react-dom": "^18.2.0",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										97
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										97
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							@@ -23,18 +23,15 @@ dependencies:
 | 
			
		||||
  '@astrojs/tailwind':
 | 
			
		||||
    specifier: ^5.1.0
 | 
			
		||||
    version: 5.1.0(astro@4.5.6)(tailwindcss@3.4.1)
 | 
			
		||||
  '@radix-ui/react-dialog':
 | 
			
		||||
    specifier: ^1.0.5
 | 
			
		||||
    version: 1.0.5(@types/react-dom@18.2.24)(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0)
 | 
			
		||||
  '@radix-ui/react-dropdown-menu':
 | 
			
		||||
    specifier: ^2.0.6
 | 
			
		||||
    version: 2.0.6(@types/react-dom@18.2.24)(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0)
 | 
			
		||||
  '@radix-ui/react-popover':
 | 
			
		||||
    specifier: ^1.0.7
 | 
			
		||||
    version: 1.0.7(@types/react-dom@18.2.24)(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0)
 | 
			
		||||
  '@radix-ui/react-slot':
 | 
			
		||||
    specifier: ^1.0.2
 | 
			
		||||
    version: 1.0.2(@types/react@18.2.74)(react@18.2.0)
 | 
			
		||||
  '@radix-ui/react-tabs':
 | 
			
		||||
    specifier: ^1.0.4
 | 
			
		||||
    version: 1.0.4(@types/react-dom@18.2.24)(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0)
 | 
			
		||||
  '@types/react':
 | 
			
		||||
    specifier: ^18.2.74
 | 
			
		||||
    version: 18.2.74
 | 
			
		||||
@@ -53,6 +50,9 @@ dependencies:
 | 
			
		||||
  cmdk:
 | 
			
		||||
    specifier: ^1.0.0
 | 
			
		||||
    version: 1.0.0(@types/react-dom@18.2.24)(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0)
 | 
			
		||||
  embla-carousel-react:
 | 
			
		||||
    specifier: ^8.0.2
 | 
			
		||||
    version: 8.0.2(react@18.2.0)
 | 
			
		||||
  lucide-react:
 | 
			
		||||
    specifier: ^0.365.0
 | 
			
		||||
    version: 0.365.0(react@18.2.0)
 | 
			
		||||
@@ -1116,41 +1116,6 @@ packages:
 | 
			
		||||
      react-remove-scroll: 2.5.5(@types/react@18.2.74)(react@18.2.0)
 | 
			
		||||
    dev: false
 | 
			
		||||
 | 
			
		||||
  /@radix-ui/react-popover@1.0.7(@types/react-dom@18.2.24)(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0):
 | 
			
		||||
    resolution: {integrity: sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      '@types/react': '*'
 | 
			
		||||
      '@types/react-dom': '*'
 | 
			
		||||
      react: ^16.8 || ^17.0 || ^18.0
 | 
			
		||||
      react-dom: ^16.8 || ^17.0 || ^18.0
 | 
			
		||||
    peerDependenciesMeta:
 | 
			
		||||
      '@types/react':
 | 
			
		||||
        optional: true
 | 
			
		||||
      '@types/react-dom':
 | 
			
		||||
        optional: true
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@babel/runtime': 7.24.4
 | 
			
		||||
      '@radix-ui/primitive': 1.0.1
 | 
			
		||||
      '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.74)(react@18.2.0)
 | 
			
		||||
      '@radix-ui/react-context': 1.0.1(@types/react@18.2.74)(react@18.2.0)
 | 
			
		||||
      '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.24)(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0)
 | 
			
		||||
      '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.74)(react@18.2.0)
 | 
			
		||||
      '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.24)(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0)
 | 
			
		||||
      '@radix-ui/react-id': 1.0.1(@types/react@18.2.74)(react@18.2.0)
 | 
			
		||||
      '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.24)(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0)
 | 
			
		||||
      '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.24)(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0)
 | 
			
		||||
      '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.24)(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0)
 | 
			
		||||
      '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.24)(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0)
 | 
			
		||||
      '@radix-ui/react-slot': 1.0.2(@types/react@18.2.74)(react@18.2.0)
 | 
			
		||||
      '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.74)(react@18.2.0)
 | 
			
		||||
      '@types/react': 18.2.74
 | 
			
		||||
      '@types/react-dom': 18.2.24
 | 
			
		||||
      aria-hidden: 1.2.4
 | 
			
		||||
      react: 18.2.0
 | 
			
		||||
      react-dom: 18.2.0(react@18.2.0)
 | 
			
		||||
      react-remove-scroll: 2.5.5(@types/react@18.2.74)(react@18.2.0)
 | 
			
		||||
    dev: false
 | 
			
		||||
 | 
			
		||||
  /@radix-ui/react-popper@1.1.3(@types/react-dom@18.2.24)(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0):
 | 
			
		||||
    resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
@@ -1289,6 +1254,34 @@ packages:
 | 
			
		||||
      react: 18.2.0
 | 
			
		||||
    dev: false
 | 
			
		||||
 | 
			
		||||
  /@radix-ui/react-tabs@1.0.4(@types/react-dom@18.2.24)(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0):
 | 
			
		||||
    resolution: {integrity: sha512-egZfYY/+wRNCflXNHx+dePvnz9FbmssDTJBtgRfDY7e8SE5oIo3Py2eCB1ckAbh1Q7cQ/6yJZThJ++sgbxibog==}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      '@types/react': '*'
 | 
			
		||||
      '@types/react-dom': '*'
 | 
			
		||||
      react: ^16.8 || ^17.0 || ^18.0
 | 
			
		||||
      react-dom: ^16.8 || ^17.0 || ^18.0
 | 
			
		||||
    peerDependenciesMeta:
 | 
			
		||||
      '@types/react':
 | 
			
		||||
        optional: true
 | 
			
		||||
      '@types/react-dom':
 | 
			
		||||
        optional: true
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@babel/runtime': 7.24.4
 | 
			
		||||
      '@radix-ui/primitive': 1.0.1
 | 
			
		||||
      '@radix-ui/react-context': 1.0.1(@types/react@18.2.74)(react@18.2.0)
 | 
			
		||||
      '@radix-ui/react-direction': 1.0.1(@types/react@18.2.74)(react@18.2.0)
 | 
			
		||||
      '@radix-ui/react-id': 1.0.1(@types/react@18.2.74)(react@18.2.0)
 | 
			
		||||
      '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.24)(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0)
 | 
			
		||||
      '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.24)(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0)
 | 
			
		||||
      '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.24)(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0)
 | 
			
		||||
      '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.74)(react@18.2.0)
 | 
			
		||||
      '@types/react': 18.2.74
 | 
			
		||||
      '@types/react-dom': 18.2.24
 | 
			
		||||
      react: 18.2.0
 | 
			
		||||
      react-dom: 18.2.0(react@18.2.0)
 | 
			
		||||
    dev: false
 | 
			
		||||
 | 
			
		||||
  /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.74)(react@18.2.0):
 | 
			
		||||
    resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
@@ -2284,6 +2277,28 @@ packages:
 | 
			
		||||
    resolution: {integrity: sha512-w+9yAVHoHhysCa+gln7AzbO9CdjFcL/wN/5dd+XW/Msl2d/4+WisEaCF1nty0xbAKaxdaJfgLB2296U7zZB7BA==}
 | 
			
		||||
    dev: false
 | 
			
		||||
 | 
			
		||||
  /embla-carousel-react@8.0.2(react@18.2.0):
 | 
			
		||||
    resolution: {integrity: sha512-RHe1GKLulOW8EDN+cJgbFbVVfRXcaLT2/89dyVw3ONGgVpZjD19wB87I1LUZ1aCzOSrTccx0PFSQanK4OOfGPA==}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      react: ^16.8.0 || ^17.0.1 || ^18.0.0
 | 
			
		||||
    dependencies:
 | 
			
		||||
      embla-carousel: 8.0.2
 | 
			
		||||
      embla-carousel-reactive-utils: 8.0.2(embla-carousel@8.0.2)
 | 
			
		||||
      react: 18.2.0
 | 
			
		||||
    dev: false
 | 
			
		||||
 | 
			
		||||
  /embla-carousel-reactive-utils@8.0.2(embla-carousel@8.0.2):
 | 
			
		||||
    resolution: {integrity: sha512-nLZqDkQdO0hvOP49/dUwjkkepMnUXgIzhyRuDjwGqswpB4Ibnc5M+w7rSQQAM+uMj0cPaXnYOTlv8XD7I/zVNw==}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      embla-carousel: 8.0.2
 | 
			
		||||
    dependencies:
 | 
			
		||||
      embla-carousel: 8.0.2
 | 
			
		||||
    dev: false
 | 
			
		||||
 | 
			
		||||
  /embla-carousel@8.0.2:
 | 
			
		||||
    resolution: {integrity: sha512-bogsDO8xosuh/l3PxIvA5AMl3+BnRVAse9sDW/60amzj4MbGS5re4WH5eVEXiuH8G1/3G7QUAX2QNr3Yx8z5rA==}
 | 
			
		||||
    dev: false
 | 
			
		||||
 | 
			
		||||
  /emoji-regex@10.3.0:
 | 
			
		||||
    resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==}
 | 
			
		||||
    dev: false
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								src/components/Showcase.astro
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/components/Showcase.astro
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
---
 | 
			
		||||
import SinglePage from "../layouts/SinglePage.astro";
 | 
			
		||||
import { ShowcaseTabs } from "./ShowcaseTabs.jsx";
 | 
			
		||||
 | 
			
		||||
import { dictionary } from "../i18n/dictionary";
 | 
			
		||||
const { title, description } = dictionary[Astro.currentLocale];
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
<SinglePage>
 | 
			
		||||
    <ShowcaseTabs client:load/>
 | 
			
		||||
</SinglePage>
 | 
			
		||||
							
								
								
									
										93
									
								
								src/components/ShowcaseTabs.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								src/components/ShowcaseTabs.jsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,93 @@
 | 
			
		||||
import { Button } from "../components/ui/button"
 | 
			
		||||
import {
 | 
			
		||||
    Card,
 | 
			
		||||
    CardContent,
 | 
			
		||||
    CardDescription,
 | 
			
		||||
    CardFooter,
 | 
			
		||||
    CardHeader,
 | 
			
		||||
    CardTitle,
 | 
			
		||||
} from "../components/ui/card"
 | 
			
		||||
import {
 | 
			
		||||
    Tabs,
 | 
			
		||||
    TabsContent,
 | 
			
		||||
    TabsList,
 | 
			
		||||
    TabsTrigger,
 | 
			
		||||
} from "../components/ui/tabs"
 | 
			
		||||
import {
 | 
			
		||||
    Carousel,
 | 
			
		||||
    CarouselContent,
 | 
			
		||||
    CarouselItem,
 | 
			
		||||
    CarouselNext,
 | 
			
		||||
    CarouselPrevious,
 | 
			
		||||
} from "../components/ui/carousel"
 | 
			
		||||
 | 
			
		||||
const data = [{
 | 
			
		||||
    value: "thisPage",
 | 
			
		||||
    handle: "1",
 | 
			
		||||
    title: "This Page",
 | 
			
		||||
    description: "random text",
 | 
			
		||||
    images: [{ src: "temp.jpg", alt: "text" }, { src: "temp.jpg", alt: "text2" }]
 | 
			
		||||
}, {
 | 
			
		||||
    value: "thatPage",
 | 
			
		||||
    title: "That Page",
 | 
			
		||||
    handle: "2",
 | 
			
		||||
    description: "random text",
 | 
			
		||||
    images: [{ src: "temp.jpg", alt: "text" }, { src: "temp.jpg", alt: "text2" }]
 | 
			
		||||
}, {
 | 
			
		||||
    value: "otherPge",
 | 
			
		||||
    title: "Other Page",
 | 
			
		||||
    handle: "3",
 | 
			
		||||
    description: "random text",
 | 
			
		||||
    images: [{ src: "temp.jpg", alt: "text" }, { src: "temp.jpg", alt: "text2" }]
 | 
			
		||||
}];
 | 
			
		||||
 | 
			
		||||
export function ShowcaseTabs() {
 | 
			
		||||
    return (
 | 
			
		||||
        <Tabs defaultValue={data[0].value} className="h-full">
 | 
			
		||||
 | 
			
		||||
            {data.map((item) => (
 | 
			
		||||
                <TabsContent value={item.value} className="">
 | 
			
		||||
                    <Card className="h-full">
 | 
			
		||||
                        <CardHeader>
 | 
			
		||||
                            <CardTitle>{item.title}</CardTitle>
 | 
			
		||||
                            <CardDescription>
 | 
			
		||||
                                {item.description}
 | 
			
		||||
                            </CardDescription>
 | 
			
		||||
                        </CardHeader>
 | 
			
		||||
                        <CardContent>
 | 
			
		||||
                            <Carousel className="w-full h-full" opts={{ align: "start", loop: "true" }}>
 | 
			
		||||
                                <CarouselContent>
 | 
			
		||||
                                    {item.images.map((image, index) => (
 | 
			
		||||
                                        <CarouselItem key={index}>
 | 
			
		||||
                                            <Card>
 | 
			
		||||
                                                <CardContent className="flex aspect-square items-center justify-center p-6">
 | 
			
		||||
                                                    <img src={image.src} alt={image.alt} />
 | 
			
		||||
                                                </CardContent>
 | 
			
		||||
                                            </Card>
 | 
			
		||||
                                        </CarouselItem>
 | 
			
		||||
                                    ))}
 | 
			
		||||
                                </CarouselContent>
 | 
			
		||||
                                <div className="w-full pt-10 grid grid-cols-2 gap-4 ">
 | 
			
		||||
                                    <div className="col-start-1 flex text-center justify-center w-full h-full">
 | 
			
		||||
                                        <CarouselPrevious />
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                    <div className="col-start-2 flex justify-center">
 | 
			
		||||
                                        <CarouselNext />
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                </div>
 | 
			
		||||
                            </Carousel>
 | 
			
		||||
                        </CardContent>
 | 
			
		||||
                    </Card>
 | 
			
		||||
                </TabsContent>
 | 
			
		||||
            ))
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            <TabsList className={`grid w-full mt-4 grid-cols-${data.length}`}>
 | 
			
		||||
                {data.map((item) => (
 | 
			
		||||
                    <TabsTrigger value={item.value}>{item.handle}</TabsTrigger>
 | 
			
		||||
                ))}
 | 
			
		||||
            </TabsList>
 | 
			
		||||
 | 
			
		||||
        </Tabs>
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
@@ -5,7 +5,7 @@ import { cva } from "class-variance-authority";
 | 
			
		||||
import { cn } from "../../lib/utils"
 | 
			
		||||
 | 
			
		||||
const buttonVariants = cva(
 | 
			
		||||
  "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none  focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
 | 
			
		||||
  "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
 | 
			
		||||
  {
 | 
			
		||||
    variants: {
 | 
			
		||||
      variant: {
 | 
			
		||||
@@ -13,7 +13,7 @@ const buttonVariants = cva(
 | 
			
		||||
        destructive:
 | 
			
		||||
          "bg-destructive text-destructive-foreground hover:bg-destructive/90",
 | 
			
		||||
        outline:
 | 
			
		||||
          "border border-input bg-background hover:bg-primary hover:text-accent-foreground",
 | 
			
		||||
          "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
 | 
			
		||||
        secondary:
 | 
			
		||||
          "bg-secondary text-secondary-foreground hover:bg-secondary/80",
 | 
			
		||||
        ghost: "hover:bg-accent hover:text-accent-foreground",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										50
									
								
								src/components/ui/card.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/components/ui/card.jsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
import * as React from "react"
 | 
			
		||||
 | 
			
		||||
import { cn } from "../../lib/utils"
 | 
			
		||||
 | 
			
		||||
const Card = React.forwardRef(({ className, ...props }, ref) => (
 | 
			
		||||
  <div
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn("rounded-lg border bg-card text-card-foreground shadow-sm", className)}
 | 
			
		||||
    {...props} />
 | 
			
		||||
))
 | 
			
		||||
Card.displayName = "Card"
 | 
			
		||||
 | 
			
		||||
const CardHeader = React.forwardRef(({ className, ...props }, ref) => (
 | 
			
		||||
  <div
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn("flex flex-col space-y-1.5 p-6", className)}
 | 
			
		||||
    {...props} />
 | 
			
		||||
))
 | 
			
		||||
CardHeader.displayName = "CardHeader"
 | 
			
		||||
 | 
			
		||||
const CardTitle = React.forwardRef(({ className, ...props }, ref) => (
 | 
			
		||||
  <h3
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn("text-2xl font-semibold leading-none tracking-tight", className)}
 | 
			
		||||
    {...props} />
 | 
			
		||||
))
 | 
			
		||||
CardTitle.displayName = "CardTitle"
 | 
			
		||||
 | 
			
		||||
const CardDescription = React.forwardRef(({ className, ...props }, ref) => (
 | 
			
		||||
  <p
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn("text-sm text-muted-foreground", className)}
 | 
			
		||||
    {...props} />
 | 
			
		||||
))
 | 
			
		||||
CardDescription.displayName = "CardDescription"
 | 
			
		||||
 | 
			
		||||
const CardContent = React.forwardRef(({ className, ...props }, ref) => (
 | 
			
		||||
  <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
 | 
			
		||||
))
 | 
			
		||||
CardContent.displayName = "CardContent"
 | 
			
		||||
 | 
			
		||||
const CardFooter = React.forwardRef(({ className, ...props }, ref) => (
 | 
			
		||||
  <div
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn("flex items-center p-6 pt-0", className)}
 | 
			
		||||
    {...props} />
 | 
			
		||||
))
 | 
			
		||||
CardFooter.displayName = "CardFooter"
 | 
			
		||||
 | 
			
		||||
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
 | 
			
		||||
							
								
								
									
										189
									
								
								src/components/ui/carousel.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								src/components/ui/carousel.jsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,189 @@
 | 
			
		||||
import * as React from "react"
 | 
			
		||||
import useEmblaCarousel from "embla-carousel-react";
 | 
			
		||||
import { ArrowLeft, ArrowRight } from "lucide-react"
 | 
			
		||||
 | 
			
		||||
import { cn } from "../../lib/utils"
 | 
			
		||||
import { Button } from "../../components/ui/button"
 | 
			
		||||
 | 
			
		||||
const CarouselContext = React.createContext(null)
 | 
			
		||||
 | 
			
		||||
function useCarousel() {
 | 
			
		||||
  const context = React.useContext(CarouselContext)
 | 
			
		||||
 | 
			
		||||
  if (!context) {
 | 
			
		||||
    throw new Error("useCarousel must be used within a <Carousel />")
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return context
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Carousel = React.forwardRef((
 | 
			
		||||
  {
 | 
			
		||||
    orientation = "horizontal",
 | 
			
		||||
    opts,
 | 
			
		||||
    setApi,
 | 
			
		||||
    plugins,
 | 
			
		||||
    className,
 | 
			
		||||
    children,
 | 
			
		||||
    ...props
 | 
			
		||||
  },
 | 
			
		||||
  ref
 | 
			
		||||
) => {
 | 
			
		||||
  const [carouselRef, api] = useEmblaCarousel({
 | 
			
		||||
    ...opts,
 | 
			
		||||
    axis: orientation === "horizontal" ? "x" : "y",
 | 
			
		||||
  }, plugins)
 | 
			
		||||
  const [canScrollPrev, setCanScrollPrev] = React.useState(false)
 | 
			
		||||
  const [canScrollNext, setCanScrollNext] = React.useState(false)
 | 
			
		||||
 | 
			
		||||
  const onSelect = React.useCallback((api) => {
 | 
			
		||||
    if (!api) {
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setCanScrollPrev(api.canScrollPrev())
 | 
			
		||||
    setCanScrollNext(api.canScrollNext())
 | 
			
		||||
  }, [])
 | 
			
		||||
 | 
			
		||||
  const scrollPrev = React.useCallback(() => {
 | 
			
		||||
    api?.scrollPrev()
 | 
			
		||||
  }, [api])
 | 
			
		||||
 | 
			
		||||
  const scrollNext = React.useCallback(() => {
 | 
			
		||||
    api?.scrollNext()
 | 
			
		||||
  }, [api])
 | 
			
		||||
 | 
			
		||||
  const handleKeyDown = React.useCallback((event) => {
 | 
			
		||||
    if (event.key === "ArrowLeft") {
 | 
			
		||||
      event.preventDefault()
 | 
			
		||||
      scrollPrev()
 | 
			
		||||
    } else if (event.key === "ArrowRight") {
 | 
			
		||||
      event.preventDefault()
 | 
			
		||||
      scrollNext()
 | 
			
		||||
    }
 | 
			
		||||
  }, [scrollPrev, scrollNext])
 | 
			
		||||
 | 
			
		||||
  React.useEffect(() => {
 | 
			
		||||
    if (!api || !setApi) {
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setApi(api)
 | 
			
		||||
  }, [api, setApi])
 | 
			
		||||
 | 
			
		||||
  React.useEffect(() => {
 | 
			
		||||
    if (!api) {
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    onSelect(api)
 | 
			
		||||
    api.on("reInit", onSelect)
 | 
			
		||||
    api.on("select", onSelect)
 | 
			
		||||
 | 
			
		||||
    return () => {
 | 
			
		||||
      api?.off("select", onSelect)
 | 
			
		||||
    };
 | 
			
		||||
  }, [api, onSelect])
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    (<CarouselContext.Provider
 | 
			
		||||
      value={{
 | 
			
		||||
        carouselRef,
 | 
			
		||||
        api: api,
 | 
			
		||||
        opts,
 | 
			
		||||
        orientation:
 | 
			
		||||
          orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
 | 
			
		||||
        scrollPrev,
 | 
			
		||||
        scrollNext,
 | 
			
		||||
        canScrollPrev,
 | 
			
		||||
        canScrollNext,
 | 
			
		||||
      }}>
 | 
			
		||||
      <div
 | 
			
		||||
        ref={ref}
 | 
			
		||||
        onKeyDownCapture={handleKeyDown}
 | 
			
		||||
        className={cn("relative", className)}
 | 
			
		||||
        role="region"
 | 
			
		||||
        aria-roledescription="carousel"
 | 
			
		||||
        {...props}>
 | 
			
		||||
        {children}
 | 
			
		||||
      </div>
 | 
			
		||||
    </CarouselContext.Provider>)
 | 
			
		||||
  );
 | 
			
		||||
})
 | 
			
		||||
Carousel.displayName = "Carousel"
 | 
			
		||||
 | 
			
		||||
const CarouselContent = React.forwardRef(({ className, ...props }, ref) => {
 | 
			
		||||
  const { carouselRef, orientation } = useCarousel()
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    (<div ref={carouselRef} className="overflow-hidden">
 | 
			
		||||
      <div
 | 
			
		||||
        ref={ref}
 | 
			
		||||
        className={cn(
 | 
			
		||||
          "flex",
 | 
			
		||||
          orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
 | 
			
		||||
          className
 | 
			
		||||
        )}
 | 
			
		||||
        {...props} />
 | 
			
		||||
    </div>)
 | 
			
		||||
  );
 | 
			
		||||
})
 | 
			
		||||
CarouselContent.displayName = "CarouselContent"
 | 
			
		||||
 | 
			
		||||
const CarouselItem = React.forwardRef(({ className, ...props }, ref) => {
 | 
			
		||||
  const { orientation } = useCarousel()
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    (<div
 | 
			
		||||
      ref={ref}
 | 
			
		||||
      role="group"
 | 
			
		||||
      aria-roledescription="slide"
 | 
			
		||||
      className={cn(
 | 
			
		||||
        "min-w-0 shrink-0 grow-0 basis-full",
 | 
			
		||||
        orientation === "horizontal" ? "pl-4" : "pt-4",
 | 
			
		||||
        className
 | 
			
		||||
      )}
 | 
			
		||||
      {...props} />)
 | 
			
		||||
  );
 | 
			
		||||
})
 | 
			
		||||
CarouselItem.displayName = "CarouselItem"
 | 
			
		||||
 | 
			
		||||
const CarouselPrevious = React.forwardRef(({ className, variant = "outline", size = "icon", ...props }, ref) => {
 | 
			
		||||
  const { orientation, scrollPrev, canScrollPrev } = useCarousel()
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    (<Button
 | 
			
		||||
      ref={ref}
 | 
			
		||||
      variant={variant}
 | 
			
		||||
      size={size}
 | 
			
		||||
      className={cn(" h-8 w-8 rounded-full", className)}
 | 
			
		||||
      disabled={!canScrollPrev}
 | 
			
		||||
      onClick={scrollPrev}
 | 
			
		||||
      {...props}>
 | 
			
		||||
      <ArrowLeft className="h-4 w-4" />
 | 
			
		||||
      <span className="sr-only">Previous slide</span>
 | 
			
		||||
    </Button>)
 | 
			
		||||
  );
 | 
			
		||||
})
 | 
			
		||||
CarouselPrevious.displayName = "CarouselPrevious"
 | 
			
		||||
 | 
			
		||||
const CarouselNext = React.forwardRef(({ className, variant = "outline", size = "icon", ...props }, ref) => {
 | 
			
		||||
  const { orientation, scrollNext, canScrollNext } = useCarousel()
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    (<Button
 | 
			
		||||
      ref={ref}
 | 
			
		||||
      variant={variant}
 | 
			
		||||
      size={size}
 | 
			
		||||
      className={cn("h-8 w-8 rounded-full", className)}
 | 
			
		||||
      disabled={!canScrollNext}
 | 
			
		||||
      onClick={scrollNext}
 | 
			
		||||
      {...props}>
 | 
			
		||||
      <ArrowRight className="h-4 w-4" />
 | 
			
		||||
      <span className="sr-only">Next slide</span>
 | 
			
		||||
    </Button>)
 | 
			
		||||
  );
 | 
			
		||||
})
 | 
			
		||||
CarouselNext.displayName = "CarouselNext"
 | 
			
		||||
 | 
			
		||||
export { Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext };
 | 
			
		||||
							
								
								
									
										41
									
								
								src/components/ui/tabs.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/components/ui/tabs.jsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
import * as React from "react"
 | 
			
		||||
import * as TabsPrimitive from "@radix-ui/react-tabs"
 | 
			
		||||
 | 
			
		||||
import { cn } from "../../lib/utils"
 | 
			
		||||
 | 
			
		||||
const Tabs = TabsPrimitive.Root
 | 
			
		||||
 | 
			
		||||
const TabsList = React.forwardRef(({ className, ...props }, ref) => (
 | 
			
		||||
  <TabsPrimitive.List
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(
 | 
			
		||||
      "inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
 | 
			
		||||
      className
 | 
			
		||||
    )}
 | 
			
		||||
    {...props} />
 | 
			
		||||
))
 | 
			
		||||
TabsList.displayName = TabsPrimitive.List.displayName
 | 
			
		||||
 | 
			
		||||
const TabsTrigger = React.forwardRef(({ className, ...props }, ref) => (
 | 
			
		||||
  <TabsPrimitive.Trigger
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(
 | 
			
		||||
      "inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
 | 
			
		||||
      className
 | 
			
		||||
    )}
 | 
			
		||||
    {...props} />
 | 
			
		||||
))
 | 
			
		||||
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName
 | 
			
		||||
 | 
			
		||||
const TabsContent = React.forwardRef(({ className, ...props }, ref) => (
 | 
			
		||||
  <TabsPrimitive.Content
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(
 | 
			
		||||
      "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
 | 
			
		||||
      className
 | 
			
		||||
    )}
 | 
			
		||||
    {...props} />
 | 
			
		||||
))
 | 
			
		||||
TabsContent.displayName = TabsPrimitive.Content.displayName
 | 
			
		||||
 | 
			
		||||
export { Tabs, TabsList, TabsTrigger, TabsContent }
 | 
			
		||||
@@ -2,9 +2,11 @@
 | 
			
		||||
import MainLayout from "../../layouts/MainLayout.astro";
 | 
			
		||||
import Hero from "../../components/Hero.astro";
 | 
			
		||||
import About from "../../components/About.astro";
 | 
			
		||||
import Showcase from "../../components/Showcase.astro";
 | 
			
		||||
 | 
			
		||||
//@ts-ignore
 | 
			
		||||
import { dictionary } from "../../i18n/dictionary";
 | 
			
		||||
 | 
			
		||||
const { title, description } = dictionary[Astro.currentLocale];
 | 
			
		||||
 | 
			
		||||
export async function getStaticPaths() {
 | 
			
		||||
@@ -16,5 +18,5 @@ export async function getStaticPaths() {
 | 
			
		||||
<MainLayout title={title} description={description} lang={Astro.currentLocale} themeOverride="theme_auto">
 | 
			
		||||
  <Hero />
 | 
			
		||||
  <About />
 | 
			
		||||
  <Hero />
 | 
			
		||||
  <Showcase />
 | 
			
		||||
</MainLayout>
 | 
			
		||||
		Reference in New Issue
	
	Block a user