mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-10-09 19:19:50 +08:00
style: enhance UI with modern glassmorphism, animations and refined spacing
This commit is contained in:
+20
-9
@@ -208,11 +208,11 @@
|
||||
}
|
||||
|
||||
.animate-fade-in {
|
||||
animation: fadeIn 0.3s ease-out forwards;
|
||||
animation: fadeIn 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||
}
|
||||
|
||||
.animate-slide-in-right {
|
||||
animation: slideInRight 0.3s ease-out forwards;
|
||||
animation: slideInRight 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||
}
|
||||
|
||||
/* Message bubble animations */
|
||||
@@ -228,22 +228,33 @@
|
||||
}
|
||||
|
||||
.animate-message-in {
|
||||
animation: messageIn 0.25s ease-out forwards;
|
||||
animation: messageIn 0.35s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||
}
|
||||
|
||||
/* Subtle floating shadow for cards */
|
||||
.shadow-soft {
|
||||
box-shadow:
|
||||
0 1px 2px oklch(0.23 0.02 260 / 0.04),
|
||||
0 4px 12px oklch(0.23 0.02 260 / 0.06),
|
||||
0 8px 24px oklch(0.23 0.02 260 / 0.04);
|
||||
0 2px 4px oklch(0.23 0.02 260 / 0.02),
|
||||
0 6px 12px oklch(0.23 0.02 260 / 0.03),
|
||||
0 12px 24px oklch(0.23 0.02 260 / 0.03);
|
||||
}
|
||||
|
||||
.shadow-soft-lg {
|
||||
box-shadow:
|
||||
0 2px 4px oklch(0.23 0.02 260 / 0.04),
|
||||
0 8px 20px oklch(0.23 0.02 260 / 0.08),
|
||||
0 16px 40px oklch(0.23 0.02 260 / 0.06);
|
||||
0 4px 8px oklch(0.23 0.02 260 / 0.03),
|
||||
0 12px 24px oklch(0.23 0.02 260 / 0.05),
|
||||
0 24px 48px oklch(0.23 0.02 260 / 0.04);
|
||||
}
|
||||
|
||||
/* Gradient borders */
|
||||
.border-gradient-primary {
|
||||
position: relative;
|
||||
background:
|
||||
linear-gradient(var(--background), var(--background)) padding-box,
|
||||
linear-gradient(135deg, oklch(0.55 0.18 265), oklch(0.6 0.2 290))
|
||||
border-box;
|
||||
border: 2px solid transparent;
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
|
||||
/* Gradient text utility */
|
||||
|
||||
+19
-11
@@ -294,6 +294,7 @@ export function ChatInput({
|
||||
const { validFiles, errors } = validateFiles(
|
||||
supportedFiles,
|
||||
files.length,
|
||||
imageSupported,
|
||||
)
|
||||
showValidationErrors(errors)
|
||||
if (validFiles.length > 0) {
|
||||
@@ -344,7 +345,7 @@ export function ChatInput({
|
||||
/>
|
||||
|
||||
{/* Action bar */}
|
||||
<div className="flex items-center justify-between px-3 py-2 border-t border-border/50">
|
||||
<div className="flex items-center justify-between px-3 py-2 border-t border-border/50 bg-muted/20 rounded-b-2xl">
|
||||
{/* Left actions */}
|
||||
<div className="flex items-center gap-1">
|
||||
<ButtonWithTooltip
|
||||
@@ -371,18 +372,18 @@ export function ChatInput({
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<div className="flex items-center gap-1.5 px-2 py-1 rounded-md hover:bg-muted/50 transition-colors">
|
||||
<Switch
|
||||
id="minimal-style"
|
||||
checked={minimalStyle}
|
||||
onCheckedChange={onMinimalStyleChange}
|
||||
className="scale-75"
|
||||
className="scale-75 data-[state=checked]:bg-primary"
|
||||
/>
|
||||
<label
|
||||
htmlFor="minimal-style"
|
||||
className={`text-xs cursor-pointer select-none ${
|
||||
className={`text-xs cursor-pointer select-none font-medium ${
|
||||
minimalStyle
|
||||
? "text-primary font-medium"
|
||||
? "text-primary"
|
||||
: "text-muted-foreground"
|
||||
}`}
|
||||
>
|
||||
@@ -390,7 +391,7 @@ export function ChatInput({
|
||||
</label>
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="top">
|
||||
<TooltipContent side="top" className="text-xs">
|
||||
Use minimal for faster generation (no colors)
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
@@ -405,7 +406,7 @@ export function ChatInput({
|
||||
onClick={() => onToggleHistory(true)}
|
||||
disabled={isDisabled || diagramHistory.length === 0}
|
||||
tooltipContent="Diagram history"
|
||||
className="h-8 w-8 p-0 text-muted-foreground hover:text-foreground"
|
||||
className="h-8 w-8 p-0 text-muted-foreground hover:text-foreground transition-colors"
|
||||
>
|
||||
<History className="h-4 w-4" />
|
||||
</ButtonWithTooltip>
|
||||
@@ -417,7 +418,7 @@ export function ChatInput({
|
||||
onClick={() => setShowSaveDialog(true)}
|
||||
disabled={isDisabled}
|
||||
tooltipContent="Save diagram"
|
||||
className="h-8 w-8 p-0 text-muted-foreground hover:text-foreground"
|
||||
className="h-8 w-8 p-0 text-muted-foreground hover:text-foreground transition-colors"
|
||||
>
|
||||
<Download className="h-4 w-4" />
|
||||
</ButtonWithTooltip>
|
||||
@@ -444,7 +445,7 @@ export function ChatInput({
|
||||
? "Upload file (image, PDF, text)"
|
||||
: "Upload file (PDF, text)"
|
||||
}
|
||||
className="h-8 w-8 p-0 text-muted-foreground hover:text-foreground"
|
||||
className="h-8 w-8 p-0 text-muted-foreground hover:text-foreground transition-colors"
|
||||
>
|
||||
<ImageIcon className="h-4 w-4" />
|
||||
</ButtonWithTooltip>
|
||||
@@ -463,9 +464,16 @@ export function ChatInput({
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
disabled={isDisabled || !input.trim()}
|
||||
disabled={
|
||||
isDisabled ||
|
||||
(!input.trim() && files.length === 0)
|
||||
}
|
||||
size="sm"
|
||||
className="h-8 px-4 rounded-xl font-medium shadow-sm"
|
||||
className={`h-8 px-4 rounded-xl font-medium shadow-sm transition-all duration-300 ${
|
||||
input.trim() || files.length > 0
|
||||
? "bg-primary text-primary-foreground hover:bg-primary/90 hover:scale-105"
|
||||
: "bg-muted text-muted-foreground opacity-70"
|
||||
}`}
|
||||
aria-label={
|
||||
isDisabled ? "Sending..." : "Send message"
|
||||
}
|
||||
|
||||
@@ -1006,15 +1006,15 @@ export function ChatMessageDisplay({
|
||||
return (
|
||||
<div
|
||||
key={`${message.id}-content-${group.startIndex}`}
|
||||
className={`px-4 py-3 text-sm leading-relaxed ${
|
||||
className={`px-5 py-3.5 text-sm leading-7 shadow-sm transition-all duration-300 ${
|
||||
message.role ===
|
||||
"user"
|
||||
? "bg-primary text-primary-foreground rounded-2xl rounded-br-md shadow-sm"
|
||||
? "bg-primary text-primary-foreground rounded-[20px] rounded-br-md ml-12"
|
||||
: message.role ===
|
||||
"system"
|
||||
? "bg-destructive/10 text-destructive border border-destructive/20 rounded-2xl rounded-bl-md"
|
||||
: "bg-muted/60 text-foreground rounded-2xl rounded-bl-md"
|
||||
} ${message.role === "user" && isLastUserMessage && onEditMessage ? "cursor-pointer hover:opacity-90 transition-opacity" : ""} ${groupIndex > 0 ? "mt-3" : ""}`}
|
||||
? "bg-destructive/5 text-destructive border border-destructive/10 rounded-xl rounded-bl-md mr-12"
|
||||
: "bg-background border border-border/50 text-foreground rounded-[20px] rounded-bl-md mr-12 shadow-soft"
|
||||
} ${message.role === "user" && isLastUserMessage && onEditMessage ? "cursor-pointer hover:brightness-110" : ""} ${groupIndex > 0 ? "mt-2" : ""}`}
|
||||
role={
|
||||
message.role ===
|
||||
"user" &&
|
||||
|
||||
@@ -1266,18 +1266,18 @@ Continue from EXACTLY where you stopped.`,
|
||||
// Collapsed view (desktop only)
|
||||
if (!isVisible && !isMobile) {
|
||||
return (
|
||||
<div className="h-full flex flex-col items-center pt-4 bg-card border border-border/30 rounded-xl">
|
||||
<div className="h-full flex flex-col items-center pt-4 bg-card border border-border/30 rounded-xl shadow-sm transition-all duration-300 ease-in-out">
|
||||
<ButtonWithTooltip
|
||||
tooltipContent="Show chat panel (Ctrl+B)"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={onToggleVisibility}
|
||||
className="hover:bg-accent transition-colors"
|
||||
className="hover:bg-accent transition-colors rounded-xl"
|
||||
>
|
||||
<PanelRightOpen className="h-5 w-5 text-muted-foreground" />
|
||||
</ButtonWithTooltip>
|
||||
<div
|
||||
className="text-sm font-medium text-muted-foreground mt-8 tracking-wide"
|
||||
className="text-sm font-medium text-muted-foreground mt-8 tracking-wide opacity-80"
|
||||
style={{
|
||||
writingMode: "vertical-rl",
|
||||
transform: "rotate(180deg)",
|
||||
@@ -1291,7 +1291,8 @@ Continue from EXACTLY where you stopped.`,
|
||||
|
||||
// Full view
|
||||
return (
|
||||
<div className="h-full flex flex-col bg-card shadow-soft animate-slide-in-right rounded-xl border border-border/30 relative">
|
||||
<div className="h-full flex flex-col bg-card/80 backdrop-blur-sm shadow-soft animate-slide-in-right rounded-xl border border-border/40 relative overflow-hidden transition-all duration-300">
|
||||
<div className="absolute inset-0 bg-gradient-to-b from-background/50 to-transparent pointer-events-none" />
|
||||
<Toaster
|
||||
position="bottom-center"
|
||||
richColors
|
||||
|
||||
Reference in New Issue
Block a user