Skip to content

Commit 61763b6

Browse files
committed
theme builder
1 parent 4737313 commit 61763b6

4 files changed

Lines changed: 109 additions & 18 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import Heading from '@/components/heading';
2+
import { useCSSVars } from '@/hooks/use-css-vars';
3+
import type { Registry } from '@/types';
4+
5+
function ThemeList({ theme }: { theme: Registry }) {
6+
const { cssVars } = useCSSVars(theme);
7+
8+
return (
9+
<div
10+
style={cssVars}
11+
className={`flex justify-between rounded-md border border-border bg-background p-4`}
12+
>
13+
<div>
14+
<Heading
15+
as={`h4`}
16+
variant={`small`}
17+
title={theme?.title || 'Theme'}
18+
description={theme?.name}
19+
/>
20+
</div>
21+
<div className="flex shrink items-center gap-1.5 rounded-md border border-border p-1.5">
22+
<div className="size-6 rounded-sm border border-border bg-primary"></div>
23+
<div className="size-6 rounded-sm border border-border bg-secondary"></div>
24+
<div className="bg-accents size-6 rounded-sm border border-border"></div>
25+
<div className="size-6 rounded-sm border border-border bg-muted"></div>
26+
</div>
27+
</div>
28+
);
29+
}
30+
31+
ThemeList.displayName = 'ThemeList';
32+
33+
export default ThemeList;

resources/js/components/theme/theme-switcher.tsx

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,61 @@
11
import { Palette } from 'lucide-react';
22
import { Button } from '@/components/ui/button';
3+
import { Input } from '@/components/ui/input';
4+
import { Label } from '@/components/ui/label';
5+
import {
6+
Sheet,
7+
SheetClose,
8+
SheetContent,
9+
SheetDescription,
10+
SheetFooter,
11+
SheetHeader,
12+
SheetTitle,
13+
SheetTrigger,
14+
} from '@/components/ui/sheet';
315

416
function ThemeSwitcher() {
517
return (
618
<div>
7-
<Button variant="ghost" size="icon">
8-
<Palette className="size-4" />
9-
</Button>
19+
<Sheet>
20+
<SheetTrigger asChild>
21+
<Button variant="ghost" size="icon">
22+
<Palette className="size-4" />
23+
</Button>
24+
</SheetTrigger>
25+
<SheetContent>
26+
<SheetHeader>
27+
<SheetTitle>Edit profile</SheetTitle>
28+
<SheetDescription>
29+
Make changes to your profile here. Click save when
30+
you&apos;re done.
31+
</SheetDescription>
32+
</SheetHeader>
33+
<div className="grid flex-1 auto-rows-min gap-6 px-4">
34+
<div className="grid gap-3">
35+
<Label htmlFor="sheet-demo-name">Name</Label>
36+
<Input
37+
id="sheet-demo-name"
38+
defaultValue="Pedro Duarte"
39+
/>
40+
</div>
41+
<div className="grid gap-3">
42+
<Label htmlFor="sheet-demo-username">
43+
Username
44+
</Label>
45+
<Input
46+
id="sheet-demo-username"
47+
defaultValue="@peduarte"
48+
/>
49+
</div>
50+
</div>
51+
<SheetFooter>
52+
<Button type="submit">Save changes</Button>
53+
<SheetClose asChild>
54+
<Button variant="outline">Close</Button>
55+
</SheetClose>
56+
</SheetFooter>
57+
</SheetContent>
58+
</Sheet>
1059
</div>
1160
);
1261
}

resources/js/components/ui/sheet.tsx

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import * as SheetPrimitive from "@radix-ui/react-dialog"
2-
import { XIcon } from "lucide-react"
31
import * as React from "react"
2+
import { XIcon } from "lucide-react"
3+
import { Dialog as SheetPrimitive } from "radix-ui"
44

55
import { cn } from "@/lib/utils"
66

@@ -34,7 +34,7 @@ function SheetOverlay({
3434
<SheetPrimitive.Overlay
3535
data-slot="sheet-overlay"
3636
className={cn(
37-
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80",
37+
"fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
3838
className
3939
)}
4040
{...props}
@@ -46,34 +46,38 @@ function SheetContent({
4646
className,
4747
children,
4848
side = "right",
49+
showCloseButton = true,
4950
...props
5051
}: React.ComponentProps<typeof SheetPrimitive.Content> & {
5152
side?: "top" | "right" | "bottom" | "left"
53+
showCloseButton?: boolean
5254
}) {
5355
return (
5456
<SheetPortal>
5557
<SheetOverlay />
5658
<SheetPrimitive.Content
5759
data-slot="sheet-content"
5860
className={cn(
59-
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
61+
"fixed z-50 flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:animate-in data-[state=open]:duration-500",
6062
side === "right" &&
61-
"data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
63+
"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
6264
side === "left" &&
63-
"data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
65+
"inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
6466
side === "top" &&
65-
"data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b",
67+
"inset-x-0 top-0 h-auto border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
6668
side === "bottom" &&
67-
"data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t",
69+
"inset-x-0 bottom-0 h-auto border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
6870
className
6971
)}
7072
{...props}
7173
>
7274
{children}
73-
<SheetPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none">
74-
<XIcon className="size-4" />
75-
<span className="sr-only">Close</span>
76-
</SheetPrimitive.Close>
75+
{showCloseButton && (
76+
<SheetPrimitive.Close className="absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-secondary">
77+
<XIcon className="size-4" />
78+
<span className="sr-only">Close</span>
79+
</SheetPrimitive.Close>
80+
)}
7781
</SheetPrimitive.Content>
7882
</SheetPortal>
7983
)
@@ -106,7 +110,7 @@ function SheetTitle({
106110
return (
107111
<SheetPrimitive.Title
108112
data-slot="sheet-title"
109-
className={cn("text-foreground font-semibold", className)}
113+
className={cn("font-semibold text-foreground", className)}
110114
{...props}
111115
/>
112116
)
@@ -119,7 +123,7 @@ function SheetDescription({
119123
return (
120124
<SheetPrimitive.Description
121125
data-slot="sheet-description"
122-
className={cn("text-muted-foreground text-sm", className)}
126+
className={cn("text-sm text-muted-foreground", className)}
123127
{...props}
124128
/>
125129
)

resources/js/pages/themes/index.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { useState } from 'react';
33
import Heading from '@/components/heading';
44
import { CardsPreview } from '@/components/preview/CardsPreview';
55
import ThemeCard from '@/components/theme/theme-card';
6+
import ThemeList from '@/components/theme/theme-list';
67
import { ThemeSearch } from '@/components/theme/theme-search';
78
import { Button } from '@/components/ui/button';
89
import { Pagination } from '@/components/ui/pagination';
@@ -40,7 +41,11 @@ function ThemesIndex({
4041
filters={filters}
4142
availableCategories={availableCategories}
4243
/>
43-
44+
<div className="mb-4 grid grid-cols-1 gap-4 md:grid-cols-4">
45+
{themes.data.map((theme: Registry, _index) => (
46+
<ThemeList theme={theme} key={_index} />
47+
))}
48+
</div>
4449
<div className="mb-4 grid grid-cols-1 gap-4 md:grid-cols-4">
4550
{themes.data.map((theme: Registry, _index) => (
4651
<ThemeCard

0 commit comments

Comments
 (0)