mirror of
https://github.com/jnsahaj/tweakcn.git
synced 2026-09-17 16:43:47 +08:00
* chore: update shadcn/ui components to v3.8.5 and migrate to unified radix-ui - Update shadcn CLI from 2.5.0 to 3.8.5 - Update 45 standard UI components to latest versions - Migrate from 28 individual @radix-ui/react-* packages to unified radix-ui - Update react-resizable-panels from v2 to v4 (direction→orientation, onLayout→onLayoutChanged, ref→panelRef, numeric sizes→percentage strings) - Fix revola.tsx runtime error by sharing shouldUseDialog via React context instead of independent useMediaQuery calls in each sub-component - Preserve custom components: sidebar.tsx, base-ui-tabs.tsx, revola.tsx - Re-apply button accent variant after component update - Fix direct Radix imports in theme-toggle, user-profile-dropdown, data-table-view-options - Fix registryItemSchema import (shadcn/registry→shadcn/schema) - Fix ScrollArea viewPortClassName removal (use data-slot CSS selector) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: resolve CSS specificity regressions from shadcn v3.8.5 update - button: remove has-[>svg]:px-* variants that override custom padding, restore lg px-8 - dialog: revert sm:max-w-lg to max-w-lg so consumer max-w overrides work - separator: use JS conditionals instead of data-attribute variants for orientation - tabs: restore old TabsTrigger styles to prevent dark mode border overrides - select consumers: use size="sm" prop instead of className h-8 override Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
115 lines
3.7 KiB
TypeScript
115 lines
3.7 KiB
TypeScript
import { Alert, AlertDescription } from "@/components/ui/alert";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
ResponsiveDialog,
|
|
ResponsiveDialogContent,
|
|
ResponsiveDialogDescription,
|
|
ResponsiveDialogFooter,
|
|
ResponsiveDialogHeader,
|
|
ResponsiveDialogTitle,
|
|
} from "@/components/ui/revola";
|
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
|
import { Textarea } from "@/components/ui/textarea";
|
|
import { AlertCircle } from "lucide-react";
|
|
import React, { useState } from "react";
|
|
|
|
interface CssImportDialogProps {
|
|
open: boolean;
|
|
onOpenChange: (open: boolean) => void;
|
|
onImport: (css: string) => void;
|
|
}
|
|
|
|
const CssImportDialog: React.FC<CssImportDialogProps> = ({ open, onOpenChange, onImport }) => {
|
|
const [cssText, setCssText] = useState("");
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const handleImport = () => {
|
|
// Basic validation - check if the CSS contains some expected variables
|
|
if (!cssText.trim()) {
|
|
setError("Please enter CSS content");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// Here you would add more sophisticated CSS parsing validation
|
|
// For now we'll just do a simple check
|
|
if (!cssText.includes("--") || !cssText.includes(":")) {
|
|
setError(
|
|
"Invalid CSS format. CSS should contain variable definitions like --primary: #color"
|
|
);
|
|
return;
|
|
}
|
|
|
|
onImport(cssText);
|
|
setCssText("");
|
|
setError(null);
|
|
onOpenChange(false);
|
|
} catch {
|
|
setError("Failed to parse CSS. Please check your syntax.");
|
|
}
|
|
};
|
|
|
|
const handleClose = () => {
|
|
setCssText("");
|
|
setError(null);
|
|
onOpenChange(false);
|
|
};
|
|
|
|
return (
|
|
<ResponsiveDialog open={open} onOpenChange={onOpenChange}>
|
|
<ResponsiveDialogContent className="flex max-h-[90dvh] flex-col overflow-hidden shadow-lg sm:max-h-[min(640px,80dvh)] sm:max-w-[550px] sm:pt-6">
|
|
<ScrollArea className="flex h-full flex-col [&>[data-slot=scroll-area-viewport]]:pb-2 [&>[data-slot=scroll-area-viewport]>div]:space-y-6">
|
|
<ResponsiveDialogHeader className="px-6">
|
|
<ResponsiveDialogTitle>Import Custom CSS</ResponsiveDialogTitle>
|
|
<ResponsiveDialogDescription>
|
|
Paste your CSS file below to customize the theme colors. Make sure to include
|
|
variables like --primary, --background, etc.
|
|
</ResponsiveDialogDescription>
|
|
</ResponsiveDialogHeader>
|
|
|
|
<div className="space-y-4 px-6">
|
|
{error && (
|
|
<Alert variant="destructive">
|
|
<AlertCircle className="mr-2 size-4" />
|
|
<AlertDescription>{error}</AlertDescription>
|
|
</Alert>
|
|
)}
|
|
<Textarea
|
|
placeholder={`:root {
|
|
--background: 0 0% 100%;
|
|
--foreground: oklch(0.52 0.13 144.17);
|
|
--primary: #3e2723;
|
|
/* And more */
|
|
}
|
|
.dark {
|
|
--background: 222.2 84% 4.9%;
|
|
--foreground: hsl(37.50 36.36% 95.69%);
|
|
--primary: rgb(46, 125, 50);
|
|
/* And more */
|
|
}
|
|
`}
|
|
className="text-foreground min-h-[300px] font-mono text-sm"
|
|
value={cssText}
|
|
onChange={(e) => {
|
|
setCssText(e.target.value);
|
|
if (error) setError(null);
|
|
}}
|
|
/>
|
|
</div>
|
|
</ScrollArea>
|
|
|
|
<ResponsiveDialogFooter className="bg-muted/30 mt-4 border-t px-6 py-4 sm:mt-0">
|
|
<Button variant="ghost" onClick={handleClose} size="sm" className="max-sm:w-full">
|
|
Cancel
|
|
</Button>
|
|
<Button onClick={handleImport} size="sm" className="max-sm:w-full">
|
|
Import
|
|
</Button>
|
|
</ResponsiveDialogFooter>
|
|
</ResponsiveDialogContent>
|
|
</ResponsiveDialog>
|
|
);
|
|
};
|
|
|
|
export default CssImportDialog;
|