From 865b359baa26c49c074e48b574cfa6aa9c84efe6 Mon Sep 17 00:00:00 2001 From: Sahaj Jain Date: Thu, 17 Apr 2025 15:11:57 +0530 Subject: [PATCH] fix: build errors --- app/editor/theme/page.tsx | 95 ++----------------- app/layout.tsx | 41 +++++--- components/editor/code-panel.tsx | 28 ++++-- components/editor/color-picker.tsx | 8 +- components/editor/css-import-dialog.tsx | 6 +- components/editor/editor.tsx | 20 +++- components/editor/header.tsx | 75 +++++++++++++++ components/editor/shadow-control.tsx | 3 +- components/editor/theme-control-panel.tsx | 30 ++++-- components/editor/theme-font-select.tsx | 2 +- components/editor/theme-preview-panel.tsx | 18 +++- .../dashboard/components/data-table.tsx | 60 ++++++++---- components/home/roadmap.tsx | 6 +- components/ui/calendar.tsx | 8 +- config/button.ts | 33 ------- config/editors/theme.ts | 3 - config/theme.ts | 1 + eslint.config.mjs | 19 ++++ package.json | 3 +- pnpm-lock.yaml | 14 ++- scripts/generate-theme-registry.ts | 9 +- store/editor-store.ts | 9 +- types/editor.ts | 11 --- types/theme.ts | 26 ++--- utils/debounce.ts | 3 +- utils/parse-css-input.ts | 9 +- utils/shadows.ts | 8 +- utils/theme-fonts.ts | 4 +- 28 files changed, 309 insertions(+), 243 deletions(-) create mode 100644 components/editor/header.tsx delete mode 100644 config/button.ts diff --git a/app/editor/theme/page.tsx b/app/editor/theme/page.tsx index 68874196..48721c70 100644 --- a/app/editor/theme/page.tsx +++ b/app/editor/theme/page.tsx @@ -1,42 +1,16 @@ -"use client"; - import { getEditorConfig } from "@/config/editors"; -import Link from "next/link"; -import { Moon, Sun, Heart } from "lucide-react"; -import GitHubIcon from "@/assets/github.svg"; -import TwitterIcon from "@/assets/twitter.svg"; -import DiscordIcon from "@/assets/discord.svg"; import { cn } from "@/lib/utils"; -import { useTheme } from "@/components/theme-provider"; -import Logo from "@/assets/logo.svg"; -import { useGithubStars } from "@/hooks/use-github-stars"; -import { SocialLink } from "@/components/social-link"; -import { Separator } from "@/components/ui/separator"; -import * as SwitchPrimitives from "@radix-ui/react-switch"; -import { Suspense } from "react"; -import { Loading } from "@/components/loading"; import Editor from "@/components/editor/editor"; +import { Metadata } from "next"; +import { Header } from "../../../components/editor/header"; -export function meta() { - return [ - { title: "tweakcn — Theme Generator for shadcn/ui" }, - { - name: "description", - content: - "Easily customize and preview your shadcn/ui theme with tweakcn. Modify colors, fonts, and styles in real-time.", - }, - ]; -} +export const metadata: Metadata = { + title: "tweakcn — Theme Generator for shadcn/ui", + description: + "Easily customize and preview your shadcn/ui theme with tweakcn. Modify colors, fonts, and styles in real-time.", +}; export default function Component() { - const { theme, toggleTheme } = useTheme(); - const { stargazersCount } = useGithubStars("jnsahaj", "tweakcn"); - - const handleThemeToggle = (event: React.MouseEvent) => { - const { clientX: x, clientY: y } = event; - toggleTheme({ x, y }); - }; - return ( <>
-
-
-
- - - tweakcn - -
-
- - - {stargazersCount > 0 && stargazersCount.toLocaleString()} - - -
- - - Support - - - - -
- - - - - - - {theme === "dark" ? ( - - ) : ( - - )} - - -
-
-
- +
- }> - - +
diff --git a/app/layout.tsx b/app/layout.tsx index f7540169..bb4603c7 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -6,6 +6,7 @@ import { TooltipProvider } from "@/components/ui/tooltip"; import { ThemeScript } from "@/components/theme-script"; import "./globals.css"; import { PostHogInit } from "@/components/posthog-init"; +import { Suspense } from "react"; export const metadata: Metadata = { title: "Beautiful themes for shadcn/ui — tweakcn | Theme Editor & Generator", @@ -15,7 +16,8 @@ export const metadata: Metadata = { "theme editor, theme generator, shadcn, ui, components, react, tailwind, button, editor, visual editor, component editor, web development, frontend, design system, UI components, React components, Tailwind CSS, shadcn/ui themes", authors: [{ name: "Sahaj Jain" }], openGraph: { - title: "Beautiful themes for shadcn/ui — tweakcn | Theme Editor & Generator", + title: + "Beautiful themes for shadcn/ui — tweakcn | Theme Editor & Generator", description: "Customize theme for shadcn/ui with tweakcn's interactive editor. Supports Tailwind CSS v4, Shadcn UI, and custom styles. Modify properties, preview changes, and get the code in real time.", url: "https://tweakcn.com/", @@ -32,7 +34,8 @@ export const metadata: Metadata = { }, twitter: { card: "summary_large_image", - title: "Beautiful themes for shadcn/ui — tweakcn | Theme Editor & Generator", + title: + "Beautiful themes for shadcn/ui — tweakcn | Theme Editor & Generator", description: "Customize theme for shadcn/ui with tweakcn's interactive editor. Supports Tailwind CSS v4, Shadcn UI, and custom styles. Modify properties, preview changes, and get the code in real time.", images: ["https://tweakcn.com/og-image.png"], @@ -41,15 +44,29 @@ export const metadata: Metadata = { viewport: "width=device-width, initial-scale=1.0", }; -export default function RootLayout({ children }: { children: React.ReactNode }) { +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { return ( - - + + - - - - {children} - - + + + + + {children} + + + diff --git a/components/editor/code-panel.tsx b/components/editor/code-panel.tsx index 9e04d8b0..63fc5850 100644 --- a/components/editor/code-panel.tsx +++ b/components/editor/code-panel.tsx @@ -1,7 +1,7 @@ import React, { useState } from "react"; import { Button } from "@/components/ui/button"; import { Copy, Check, PanelRight } from "lucide-react"; -import { EditorConfig, ThemeEditorState } from "@/types/editor"; +import { ThemeEditorState } from "@/types/editor"; import { ScrollArea, ScrollBar } from "../ui/scroll-area"; import { ColorFormat } from "../../types"; import { @@ -14,32 +14,38 @@ import { import { usePostHog } from "posthog-js/react"; import { useEditorStore } from "@/store/editor-store"; import { usePreferencesStore } from "@/store/preferences-store"; -import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; - +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/components/ui/tooltip"; +import { generateThemeCode } from "@/utils/theme-style-generator"; interface CodePanelProps { - config: EditorConfig; themeEditorState: ThemeEditorState; onCodePanelToggle: () => void; } const CodePanel: React.FC = ({ - config, themeEditorState, onCodePanelToggle, }) => { const [registryCopied, setRegistryCopied] = useState(false); const [copied, setCopied] = useState(false); const posthog = usePostHog(); - + const preset = useEditorStore((state) => state.themeState.preset); const colorFormat = usePreferencesStore((state) => state.colorFormat); const tailwindVersion = usePreferencesStore((state) => state.tailwindVersion); const packageManager = usePreferencesStore((state) => state.packageManager); const setColorFormat = usePreferencesStore((state) => state.setColorFormat); - const setTailwindVersion = usePreferencesStore((state) => state.setTailwindVersion); - const setPackageManager = usePreferencesStore((state) => state.setPackageManager); + const setTailwindVersion = usePreferencesStore( + (state) => state.setTailwindVersion + ); + const setPackageManager = usePreferencesStore( + (state) => state.setPackageManager + ); - const code = config.codeGenerator.generateComponentCode( + const code = generateThemeCode( themeEditorState, colorFormat, tailwindVersion @@ -61,7 +67,9 @@ const CodePanel: React.FC = ({ const copyRegistryCommand = async () => { try { - await navigator.clipboard.writeText(getRegistryCommand(preset)); + await navigator.clipboard.writeText( + getRegistryCommand(preset ?? "default") + ); setRegistryCopied(true); setTimeout(() => setRegistryCopied(false), 2000); captureCopyEvent("COPY_REGISTRY_COMMAND"); diff --git a/components/editor/color-picker.tsx b/components/editor/color-picker.tsx index 8f247a8c..c721c25f 100644 --- a/components/editor/color-picker.tsx +++ b/components/editor/color-picker.tsx @@ -14,9 +14,11 @@ const ColorPicker = ({ color, onChange, label }: ColorPickerProps) => { // Create debounced onChange handler with useCallback to maintain reference const debouncedOnChange = useCallback( - debounce((value) => { - onChange(value); - }, 10), + (value: string) => { + debounce(() => { + onChange(value); + }, 10)(); + }, [onChange] ); diff --git a/components/editor/css-import-dialog.tsx b/components/editor/css-import-dialog.tsx index d6b0f255..83dcaaf6 100644 --- a/components/editor/css-import-dialog.tsx +++ b/components/editor/css-import-dialog.tsx @@ -47,7 +47,7 @@ const CssImportDialog: React.FC = ({ setCssText(""); setError(null); onOpenChange(false); - } catch (err) { + } catch { setError("Failed to parse CSS. Please check your syntax."); } }; @@ -62,7 +62,9 @@ const CssImportDialog: React.FC = ({ - Import Custom CSS + + Import Custom CSS + Paste your CSS file below to customize the theme colors. Make sure to include variables like --primary, --background, etc. diff --git a/components/editor/editor.tsx b/components/editor/editor.tsx index 62948467..a014af82 100644 --- a/components/editor/editor.tsx +++ b/components/editor/editor.tsx @@ -1,3 +1,5 @@ +"use client"; + import React, { useState } from "react"; import { ResizablePanelGroup, @@ -5,7 +7,11 @@ import { ResizableHandle, } from "@/components/ui/resizable"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; -import { EditorConfig, BaseEditorState, ThemeEditorState } from "@/types/editor"; +import { + EditorConfig, + BaseEditorState, + ThemeEditorState, +} from "@/types/editor"; import { ThemeStyles } from "@/types/theme"; import CodePanel from "./code-panel"; import { Sliders } from "lucide-react"; @@ -16,8 +22,14 @@ interface EditorProps { initialState?: BaseEditorState; } -const isThemeStyles = (styles: any): styles is ThemeStyles => { - return !!styles && "light" in styles && "dark" in styles; +const isThemeStyles = (styles: unknown): styles is ThemeStyles => { + return ( + !!styles && + typeof styles === "object" && + styles !== null && + "light" in styles && + "dark" in styles + ); }; const Editor: React.FC = ({ config }) => { @@ -67,7 +79,6 @@ const Editor: React.FC = ({ config }) => { setIsCodePanelOpen(!isCodePanelOpen)} /> @@ -113,7 +124,6 @@ const Editor: React.FC = ({ config }) => { setIsCodePanelOpen(!isCodePanelOpen)} /> diff --git a/components/editor/header.tsx b/components/editor/header.tsx new file mode 100644 index 00000000..ee365ead --- /dev/null +++ b/components/editor/header.tsx @@ -0,0 +1,75 @@ +"use client"; + +import Link from "next/link"; +import { Moon, Sun, Heart } from "lucide-react"; +import GitHubIcon from "@/assets/github.svg"; +import TwitterIcon from "@/assets/twitter.svg"; +import DiscordIcon from "@/assets/discord.svg"; +import { useTheme } from "@/components/theme-provider"; +import Logo from "@/assets/logo.svg"; +import { useGithubStars } from "@/hooks/use-github-stars"; +import { SocialLink } from "@/components/social-link"; +import { Separator } from "@/components/ui/separator"; +import * as SwitchPrimitives from "@radix-ui/react-switch"; + +export function Header() { + const { theme, toggleTheme } = useTheme(); + const { stargazersCount } = useGithubStars("jnsahaj", "tweakcn"); + + const handleThemeToggle = (event: React.MouseEvent) => { + const { clientX: x, clientY: y } = event; + toggleTheme({ x, y }); + }; + + return ( +
+
+
+ + + tweakcn + +
+
+ + + {stargazersCount > 0 && stargazersCount.toLocaleString()} + + +
+ + + Support + + + + +
+ + + + + + + {theme === "dark" ? ( + + ) : ( + + )} + + +
+
+
+ ); +} diff --git a/components/editor/shadow-control.tsx b/components/editor/shadow-control.tsx index 3cce6cf1..bfcac8f1 100644 --- a/components/editor/shadow-control.tsx +++ b/components/editor/shadow-control.tsx @@ -1,5 +1,4 @@ import React from "react"; -import { Label } from "../ui/label"; import { SliderWithInput } from "./slider-with-input"; import ColorPicker from "./color-picker"; import ControlSection from "./control-section"; @@ -11,7 +10,7 @@ interface ShadowControlProps { shadowSpread: number; shadowOffsetX: number; shadowOffsetY: number; - onChange: (key: string, value: any) => void; + onChange: (key: string, value: string | number) => void; } const ShadowControl: React.FC = ({ diff --git a/components/editor/theme-control-panel.tsx b/components/editor/theme-control-panel.tsx index cda295e9..3340f558 100644 --- a/components/editor/theme-control-panel.tsx +++ b/components/editor/theme-control-panel.tsx @@ -1,3 +1,5 @@ +"use client"; + import React, { useState } from "react"; import { ThemeEditorControlsProps, ThemeStyleProps } from "@/types/theme"; import ControlSection from "./control-section"; @@ -46,11 +48,13 @@ const ThemeControlPanel = ({ } = useEditorStore(); const [cssImportOpen, setCssImportOpen] = useState(false); - const currentStyles = { - ...defaultThemeState.styles.light, - ...defaultThemeState.styles[currentMode], - ...styles?.[currentMode], - }; + const currentStyles = React.useMemo( + () => ({ + ...defaultThemeState.styles[currentMode], + ...styles?.[currentMode], + }), + [currentMode, styles] + ); const updateStyle = React.useCallback( ( @@ -119,7 +123,7 @@ const ThemeControlPanel = ({
@@ -232,7 +236,9 @@ const ThemeControlPanel = ({ /> updateStyle("destructive-foreground", color)} + onChange={(color) => + updateStyle("destructive-foreground", color) + } label="Destructive Foreground" /> @@ -313,7 +319,9 @@ const ThemeControlPanel = ({ /> updateStyle("sidebar-accent-foreground", color)} + onChange={(color) => + updateStyle("sidebar-accent-foreground", color) + } label="Sidebar Accent Foreground" /> updateStyle("letter-spacing", `${value}em`)} + onChange={(value) => + updateStyle("letter-spacing", `${value}em`) + } min={-0.5} max={0.5} step={0.025} @@ -446,7 +456,7 @@ const ThemeControlPanel = ({ )} onChange={(key, value) => { if (key === "shadow-color") { - updateStyle(key, value); + updateStyle(key, value as string); } else if (key === "shadow-opacity") { updateStyle(key, value.toString()); } else { diff --git a/components/editor/theme-font-select.tsx b/components/editor/theme-font-select.tsx index 02968060..71258129 100644 --- a/components/editor/theme-font-select.tsx +++ b/components/editor/theme-font-select.tsx @@ -22,7 +22,7 @@ const ThemeFontSelect: React.FC = ({ onFontChange, }) => { const fontNames = useMemo(() => ["System", ...Object.keys(fonts)], [fonts]); - const value = fonts[currentFont] ?? defaultValue; + const value = currentFont ? fonts[currentFont] ?? defaultValue : defaultValue; return ( - + Eddie Lake - Jamik Tashpulatov + + Jamik Tashpulatov + @@ -316,10 +318,11 @@ export function DataTable({ }) { const [data, setData] = React.useState(() => initialData); const [rowSelection, setRowSelection] = React.useState({}); - const [columnVisibility, setColumnVisibility] = React.useState( - {} + const [columnVisibility, setColumnVisibility] = + React.useState({}); + const [columnFilters, setColumnFilters] = React.useState( + [] ); - const [columnFilters, setColumnFilters] = React.useState([]); const [sorting, setSorting] = React.useState([]); const [pagination, setPagination] = React.useState({ pageIndex: 0, @@ -383,7 +386,10 @@ export function DataTable({ View