Skip to content

Commit ab01706

Browse files
Merge pull request #17 from designbycode/feature/tweakcn-theme-creator-15665160290612550556
Enhance Theme Creator with TweakCN Layout and Metadata Support
2 parents 2966f79 + d79911a commit ab01706

18 files changed

Lines changed: 191 additions & 129 deletions

resources/js/components/app/newsletter-dialog.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { Form, Head } from '@inertiajs/react';
1+
import { Form } from '@inertiajs/react';
22
import { Mail } from 'lucide-react';
3+
import InputError from '@/components/input-error';
34
import { Button } from '@/components/ui/button';
45
import {
56
Dialog,
@@ -11,7 +12,6 @@ import {
1112
import { Input } from '@/components/ui/input';
1213
import { Label } from '@/components/ui/label';
1314
import { Spinner } from '@/components/ui/spinner';
14-
import InputError from '@/components/input-error';
1515
import { subscribe } from '@/routes/newsletter';
1616

1717
interface NewsletterDialogProps {

resources/js/components/delete-user.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Form } from '@inertiajs/react';
22
import { useRef } from 'react';
3-
import ProfileController from '@/actions/App/Http/Controllers/Settings/ProfileController';
43
import Heading from '@/components/heading';
54
import InputError from '@/components/input-error';
65
import PasswordInput from '@/components/password-input';
@@ -15,6 +14,7 @@ import {
1514
DialogTrigger,
1615
} from '@/components/ui/dialog';
1716
import { Label } from '@/components/ui/label';
17+
import ProfileController from '@/actions/App/Http/Controllers/Settings/ProfileController';
1818

1919
export default function DeleteUser() {
2020
const passwordInput = useRef<HTMLInputElement>(null);

resources/js/components/preview/cards-preview.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ChevronDown, Sparkles, Terminal } from 'lucide-react';
2-
import { useCallback, useState } from 'react';
2+
import { useState } from 'react';
33
import {
44
Bar,
55
BarChart,
@@ -91,7 +91,6 @@ const chartData = [
9191

9292
export default function CardsPreview({ ...props }) {
9393
const [date, setDate] = useState<Date | undefined>(new Date());
94-
const onTooltipOpenChange = useCallback(() => {}, []);
9594

9695
return (
9796
<div

resources/js/components/themes/color-controls.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
import { Sparkles } from 'lucide-react';
2+
import { memo } from 'react';
23
import { Button } from '@/components/ui/button';
34
import { Input } from '@/components/ui/input';
45
import { Label } from '@/components/ui/label';
56
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
6-
import { PALETTE_PRESETS } from './pallets-preset';
77
import {
88
derivePaletteFromPrimary,
99
hexToTokenValue,
1010
tokenValueToHex,
1111
} from '@/lib/theme/color';
1212
import { TOKEN_GROUPS } from '@/lib/theme/defaults';
1313
import { useThemeStore } from '@/lib/theme/store';
14-
import { memo } from 'react';
14+
import { PALETTE_PRESETS } from './pallets-preset';
1515

1616
export function ColorControls() {
1717
const { light, dark, setToken, setManyTokens } = useThemeStore();

resources/js/components/themes/controls-panel.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
1+
import { usePage } from '@inertiajs/react';
12
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
3+
import { useThemeStore } from '@/lib/theme/store';
24
import { ColorControls } from './color-controls';
35
import { RadiusControls } from './raduis-controles';
6+
import ThemeInfo from './theme-info';
47
import { TypographyControls } from './typography-controls';
58

69
export function ControlsPanel() {
10+
const { title, name, description, tags, setInfo } = useThemeStore();
11+
const { availableTags = [] } = usePage<{ availableTags: string[] }>().props;
12+
713
return (
814
<Tabs defaultValue="colors" className="flex h-full flex-col">
9-
<TabsList className="m-3 grid grid-cols-3">
15+
<TabsList className="m-3 grid grid-cols-4">
1016
<TabsTrigger value="colors">Colors</TabsTrigger>
1117
<TabsTrigger value="radius">Radius</TabsTrigger>
1218
<TabsTrigger value="type">Type</TabsTrigger>
19+
<TabsTrigger value="info">Info</TabsTrigger>
1320
</TabsList>
1421
<div className="flex-1 overflow-y-auto px-4 pb-6">
1522
<TabsContent value="colors" className="mt-0">
@@ -21,6 +28,13 @@ export function ControlsPanel() {
2128
<TabsContent value="type" className="mt-0">
2229
<TypographyControls />
2330
</TabsContent>
31+
<TabsContent value="info" className="mt-0">
32+
<ThemeInfo
33+
theme={{ title, name, description, tags }}
34+
availableTags={availableTags}
35+
onChange={setInfo}
36+
/>
37+
</TabsContent>
2438
</div>
2539
</Tabs>
2640
);

resources/js/components/themes/export-dialog.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
import { useThemeStore } from '@/lib/theme/store';
2-
import {
3-
generateIndexCss,
4-
generateTailwindSnippet,
5-
} from '@/lib/theme/css-export';
1+
import { Download, FileCode } from 'lucide-react';
2+
import { Button } from '@/components/ui/button';
63
import {
74
Dialog,
85
DialogContent,
@@ -11,9 +8,12 @@ import {
118
DialogTrigger,
129
} from '@/components/ui/dialog';
1310
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
14-
import { Button } from '@/components/ui/button';
15-
import { Download, FileCode } from 'lucide-react';
1611
import { MainCodeBlock } from '@/layouts/main/theme/main-code-block';
12+
import {
13+
generateIndexCss,
14+
generateTailwindSnippet,
15+
} from '@/lib/theme/css-export';
16+
import { useThemeStore } from '@/lib/theme/store';
1717

1818
export function ExportDialog() {
1919
const state = useThemeStore();

resources/js/components/themes/raduis-controles.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { useThemeStore } from '@/lib/theme/store';
21
import { Label } from '@/components/ui/label';
32
import { Slider } from '@/components/ui/slider';
3+
import { useThemeStore } from '@/lib/theme/store';
44

55
export function RadiusControls() {
66
const { radius, setRadius } = useThemeStore();
7+
78
return (
89
<div className="space-y-3">
910
<div className="flex items-center justify-between">

resources/js/components/themes/theme-preview.tsx

Lines changed: 27 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
import { useThemeStore } from '@/lib/theme/store';
2-
import { tokenValueToCss } from '@/lib/theme/color';
3-
import { Badge } from '@/components/ui/badge';
4-
import { Button } from '@/components/ui/button';
5-
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
6-
import { Input } from '@/components/ui/input';
7-
import { Label } from '@/components/ui/label';
81
import { Sun, Moon } from 'lucide-react';
92
import { useMemo, useState } from 'react';
3+
import CardsPreview from '@/components/preview/cards-preview';
4+
import { Button } from '@/components/ui/button';
5+
import { tokenValueToCss } from '@/lib/theme/color';
6+
import { useThemeStore } from '@/lib/theme/store';
107

118
const COLOR_TOKENS = [
129
'background', 'foreground',
@@ -30,6 +27,7 @@ function buildVars(
3027

3128
for (const token of COLOR_TOKENS) {
3229
const val = colors[token];
30+
3331
if (val) {
3432
const css = tokenValueToCss(val);
3533
vars[`--${token}`] = css;
@@ -68,93 +66,38 @@ export function ThemePreview() {
6866

6967
return (
7068
<div className="flex h-full flex-col">
71-
<div className="flex items-center justify-between border-b px-4 py-2" style={{ borderColor: 'var(--color-border)' }}>
72-
<span className="text-sm font-medium text-muted-foreground">Preview</span>
69+
<div
70+
className="flex items-center justify-between border-b px-4 py-2"
71+
style={{ borderColor: 'var(--color-border)' }}
72+
>
73+
<span className="text-sm font-medium text-muted-foreground">
74+
Preview
75+
</span>
7376
<Button variant="outline" size="sm" onClick={toggleMode}>
7477
{previewMode === 'light' ? (
75-
<><Moon className="mr-1 size-3.5" /> Dark</>
78+
<>
79+
<Moon className="mr-1 size-3.5" /> Dark
80+
</>
7681
) : (
77-
<><Sun className="mr-1 size-3.5" /> Light</>
82+
<>
83+
<Sun className="mr-1 size-3.5" /> Light
84+
</>
7885
)}
7986
</Button>
8087
</div>
8188

8289
<div
8390
className="flex-1 overflow-y-auto"
84-
style={{ background: bgCss, color: fgCss } as React.CSSProperties}
91+
style={
92+
{
93+
background: bgCss,
94+
color: fgCss,
95+
...cssVars,
96+
} as React.CSSProperties
97+
}
8598
>
86-
<div className="min-h-full p-6" style={cssVars as React.CSSProperties}>
87-
<p
88-
className="text-2xl font-bold"
89-
style={{ fontFamily: `"${fonts.serif}"` }}
90-
>
91-
Theme Preview
92-
</p>
93-
<p className="mt-1 mb-6 text-sm" style={{ color: 'var(--color-muted-foreground)' }}>
94-
Sample UI components using your current palette.
95-
</p>
96-
97-
<div className="flex flex-wrap gap-2">
98-
<Button>Primary</Button>
99-
<Button variant="secondary">Secondary</Button>
100-
<Button variant="outline">Outline</Button>
101-
<Button variant="ghost">Ghost</Button>
102-
<Button variant="destructive">Destructive</Button>
103-
</div>
104-
105-
<Card className="mt-6 max-w-sm">
106-
<CardHeader>
107-
<CardTitle>Example Card</CardTitle>
108-
</CardHeader>
109-
<CardContent>
110-
<p className="text-sm" style={{ color: 'var(--color-muted-foreground)' }}>
111-
This card demonstrates how your theme appears on standard
112-
shadcn/ui components.
113-
</p>
114-
</CardContent>
115-
<CardFooter className="flex justify-between">
116-
<Button variant="outline">Cancel</Button>
117-
<Button>Save</Button>
118-
</CardFooter>
119-
</Card>
120-
121-
<Card className="mt-4 max-w-sm">
122-
<CardHeader>
123-
<CardTitle>Form Example</CardTitle>
124-
</CardHeader>
125-
<CardContent className="space-y-3">
126-
<div className="space-y-1">
127-
<Label htmlFor="pv-email">Email</Label>
128-
<Input id="pv-email" placeholder="you@example.com" />
129-
</div>
130-
<div className="space-y-1">
131-
<Label htmlFor="pv-pw">Password</Label>
132-
<Input id="pv-pw" type="password" placeholder="••••••••" />
133-
</div>
134-
</CardContent>
135-
</Card>
136-
137-
<div className="mt-6 flex flex-wrap gap-2">
138-
<Badge>Default</Badge>
139-
<Badge variant="secondary">Secondary</Badge>
140-
<Badge variant="outline">Outline</Badge>
141-
<Badge variant="destructive">Destructive</Badge>
142-
</div>
143-
144-
<div
145-
className="mt-6 rounded-lg border p-4 space-y-1"
146-
style={{ borderColor: 'var(--color-border)' }}
147-
>
148-
<p className="font-mono text-xs" style={{ color: 'var(--color-muted-foreground)' }}>
149-
SYSTEM — font-mono ({fonts.mono})
150-
</p>
151-
<p style={{ fontFamily: `"${fonts.serif}"` }}>
152-
The quick brown fox jumps over the lazy dog — serif
153-
</p>
154-
<p style={{ fontFamily: `"${fonts.sans}"` }}>
155-
The quick brown fox jumps over the lazy dog — sans
156-
</p>
157-
</div>
99+
<div className="min-h-full p-6">
100+
<CardsPreview />
158101
</div>
159102
</div>
160103
</div>

resources/js/components/themes/typography-controls.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ import {
77
SelectTrigger,
88
SelectValue,
99
} from '@/components/ui/select';
10+
import { Slider } from '@/components/ui/slider';
11+
import { useThemeStore } from '@/lib/theme/store';
1012
import {
1113
loadGoogleFont,
1214
MONO_FONTS,
1315
SANS_FONTS,
1416
SERIF_FONTS,
1517
} from './font-list';
16-
import { Slider } from '@/components/ui/slider';
17-
import { useThemeStore } from '@/lib/theme/store';
1818

1919
const SCALES = [
2020
{ name: 'Minor Second', value: 1.067 },
@@ -129,13 +129,11 @@ export function TypographyControls() {
129129
}
130130

131131
function FontSelect({
132-
kind,
133132
label,
134133
options,
135134
value,
136135
onChange,
137136
}: {
138-
kind: string;
139137
label: string;
140138
options: string[];
141139
value: string;

resources/js/layouts/main/main-footer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { Link } from '@inertiajs/react';
22
import { GithubIcon } from 'lucide-react';
33

4+
import XIcon from '@/components/icons/x-icon';
45
import { Button } from '@/components/ui/button';
56
import { PlaceholderPattern } from '@/components/ui/placeholder-pattern';
67
import MainWrapper from '@/layouts/main/main-wrapper';
78
import { home } from '@/routes';
8-
import XIcon from '@/components/icons/x-icon';
99

1010
const navLinks = [
1111
{ href: '#', label: 'Features' },

0 commit comments

Comments
 (0)