From e6c1f7eb5a3daecb5801dc1e4c97c1b8789b616a Mon Sep 17 00:00:00 2001 From: Marco Beretta <81851188+berry-13@users.noreply.github.com> Date: Thu, 25 Sep 2025 23:19:47 +0200 Subject: [PATCH] refactor: improve styling and animations in Artifacts, ArtifactsSubMenu, and MCPSubMenu components; update border-radius in style.css --- .../src/components/Chat/Input/Artifacts.tsx | 40 ++++----- .../Chat/Input/ArtifactsSubMenu.tsx | 30 +++---- client/src/components/Chat/Input/ChatForm.tsx | 1 + .../src/components/Chat/Input/MCPSubMenu.tsx | 2 +- .../components/Chat/Input/ToolsDropdown.tsx | 2 +- client/src/components/Nav/AccountSettings.tsx | 7 +- client/src/style.css | 88 ++++++++++++++++++- 7 files changed, 123 insertions(+), 47 deletions(-) diff --git a/client/src/components/Chat/Input/Artifacts.tsx b/client/src/components/Chat/Input/Artifacts.tsx index 493f126e3c..e8f4f22004 100644 --- a/client/src/components/Chat/Input/Artifacts.tsx +++ b/client/src/components/Chat/Input/Artifacts.tsx @@ -79,19 +79,17 @@ function Artifacts() { )} onClick={(e) => e.stopPropagation()} > - +
@@ -106,18 +104,16 @@ function Artifacts() { event.stopPropagation(); handleShadcnToggle(); }} - disabled={isCustomEnabled} className={cn( - 'mb-1 flex items-center justify-between rounded-lg px-2 py-2', - 'cursor-pointer outline-none transition-colors', - 'hover:bg-black/[0.075] dark:hover:bg-white/10', - 'data-[active-item]:bg-black/[0.075] dark:data-[active-item]:bg-white/10', - isCustomEnabled && 'cursor-not-allowed opacity-50', + 'mb-1 flex items-center justify-between gap-2 rounded-lg px-2 py-2', + 'cursor-pointer bg-surface-secondary text-text-primary outline-none transition-colors', + 'hover:bg-surface-hover data-[active-item]:bg-surface-hover', + isShadcnEnabled && 'bg-surface-active', )} > -
+ {localize('com_ui_include_shadcnui' as any)} +
- {localize('com_ui_include_shadcnui' as any)}
@@ -130,15 +126,15 @@ function Artifacts() { handleCustomToggle(); }} className={cn( - 'flex items-center justify-between rounded-lg px-2 py-2', - 'cursor-pointer outline-none transition-colors', - 'hover:bg-black/[0.075] dark:hover:bg-white/10', - 'data-[active-item]:bg-black/[0.075] dark:data-[active-item]:bg-white/10', + 'mb-1 flex items-center justify-between gap-2 rounded-lg px-2 py-2', + 'cursor-pointer bg-surface-secondary text-text-primary outline-none transition-colors', + 'hover:bg-surface-hover data-[active-item]:bg-surface-hover', + isCustomEnabled && 'bg-surface-active', )} > -
+ {localize('com_ui_custom_prompt_mode' as any)} +
- {localize('com_ui_custom_prompt_mode' as any)}
diff --git a/client/src/components/Chat/Input/ArtifactsSubMenu.tsx b/client/src/components/Chat/Input/ArtifactsSubMenu.tsx index e27fa43c0e..099a476bfa 100644 --- a/client/src/components/Chat/Input/ArtifactsSubMenu.tsx +++ b/client/src/components/Chat/Input/ArtifactsSubMenu.tsx @@ -90,8 +90,8 @@ const ArtifactsSubMenu = React.forwardRef portal={true} unmountOnHide={true} className={cn( - 'animate-popover-left z-50 ml-3 flex min-w-[250px] flex-col rounded-xl', - 'border border-border-light bg-surface-secondary px-1.5 py-1 shadow-lg', + 'animate-popover-left z-50 ml-3 mt-6 flex min-w-[250px] flex-col rounded-xl', + 'border border-border-light bg-surface-secondary shadow-lg', )} >
@@ -107,18 +107,16 @@ const ArtifactsSubMenu = React.forwardRef event.stopPropagation(); handleShadcnToggle(); }} - disabled={isCustomEnabled} className={cn( - 'mb-1 flex items-center justify-between rounded-lg px-2 py-2', - 'cursor-pointer text-text-primary outline-none transition-colors', - 'hover:bg-black/[0.075] dark:hover:bg-white/10', - 'data-[active-item]:bg-black/[0.075] dark:data-[active-item]:bg-white/10', - isCustomEnabled && 'cursor-not-allowed opacity-50', + 'mb-1 flex items-center justify-between gap-2 rounded-lg px-2 py-2', + 'cursor-pointer bg-surface-secondary text-text-primary outline-none transition-colors', + 'hover:bg-surface-hover data-[active-item]:bg-surface-hover', + isShadcnEnabled && 'bg-surface-active', )} > -
+ {localize('com_ui_include_shadcnui' as any)} +
- {localize('com_ui_include_shadcnui' as any)}
@@ -131,15 +129,15 @@ const ArtifactsSubMenu = React.forwardRef handleCustomToggle(); }} className={cn( - 'flex items-center justify-between rounded-lg px-2 py-2', - 'cursor-pointer text-text-primary outline-none transition-colors', - 'hover:bg-black/[0.075] dark:hover:bg-white/10', - 'data-[active-item]:bg-black/[0.075] dark:data-[active-item]:bg-white/10', + 'mb-1 flex items-center justify-between gap-2 rounded-lg px-2 py-2', + 'cursor-pointer bg-surface-secondary text-text-primary outline-none transition-colors', + 'hover:bg-surface-hover data-[active-item]:bg-surface-hover', + isCustomEnabled && 'bg-surface-active', )} > -
+ {localize('com_ui_custom_prompt_mode' as any)} +
- {localize('com_ui_custom_prompt_mode' as any)}
diff --git a/client/src/components/Chat/Input/ChatForm.tsx b/client/src/components/Chat/Input/ChatForm.tsx index 0736c7dc61..d1cc975832 100644 --- a/client/src/components/Chat/Input/ChatForm.tsx +++ b/client/src/components/Chat/Input/ChatForm.tsx @@ -247,6 +247,7 @@ const ChatForm = memo(({ index = 0 }: { index?: number }) => { )} > + {/* WIP */} ( 'w-full min-w-0 justify-between text-sm', isServerInitializing && 'opacity-50 hover:bg-transparent dark:hover:bg-transparent', + isSelected && 'bg-surface-active', )} >
- {serverName}
{statusIcon &&
{statusIcon}
} diff --git a/client/src/components/Chat/Input/ToolsDropdown.tsx b/client/src/components/Chat/Input/ToolsDropdown.tsx index 003faf2cec..720c0bb92e 100644 --- a/client/src/components/Chat/Input/ToolsDropdown.tsx +++ b/client/src/components/Chat/Input/ToolsDropdown.tsx @@ -310,7 +310,7 @@ const ToolsDropdown = ({ disabled }: ToolsDropdownProps) => { )} >
- +
} diff --git a/client/src/components/Nav/AccountSettings.tsx b/client/src/components/Nav/AccountSettings.tsx index 6bf48e6fb2..654bf9319c 100644 --- a/client/src/components/Nav/AccountSettings.tsx +++ b/client/src/components/Nav/AccountSettings.tsx @@ -25,7 +25,7 @@ function AccountSettings() {
@@ -40,11 +40,10 @@ function AccountSettings() {
diff --git a/client/src/style.css b/client/src/style.css index 1a3747c80c..7f5d0a86ed 100644 --- a/client/src/style.css +++ b/client/src/style.css @@ -2581,7 +2581,7 @@ html { flex-direction: column; overflow: auto; overscroll-behavior: contain; - border-radius: 1rem; + border-radius: 0.7rem; border-width: 1px; border-style: solid; border-color: var(--border-light); @@ -2654,6 +2654,7 @@ html { translate: 0; } +.animate-popover-top, .animate-popover { transform-origin: top; opacity: 0; @@ -2662,12 +2663,13 @@ html { transform 150ms cubic-bezier(0.4, 0, 0.2, 1); transform: scale(0.95) translateY(-0.5rem); } - +.animate-popover-top[data-enter], .animate-popover[data-enter] { opacity: 1; transform: scale(1) translateY(0); } +/* Left (existing) */ .animate-popover-left { transform-origin: left; opacity: 0; @@ -2676,12 +2678,92 @@ html { transform 150ms cubic-bezier(0.4, 0, 0.2, 1); transform: scale(0.95) translateX(-0.5rem); } - .animate-popover-left[data-enter] { opacity: 1; transform: scale(1) translateX(0); } +/* Right */ +.animate-popover-right { + transform-origin: right; + opacity: 0; + transition: + opacity 150ms cubic-bezier(0.4, 0, 0.2, 1), + transform 150ms cubic-bezier(0.4, 0, 0.2, 1); + transform: scale(0.95) translateX(0.5rem); +} +.animate-popover-right[data-enter] { + opacity: 1; + transform: scale(1) translateX(0); +} + +/* Bottom */ +.animate-popover-bottom { + transform-origin: bottom; + opacity: 0; + transition: + opacity 150ms cubic-bezier(0.4, 0, 0.2, 1), + transform 150ms cubic-bezier(0.4, 0, 0.2, 1); + transform: scale(0.95) translateY(0.5rem); +} +.animate-popover-bottom[data-enter] { + opacity: 1; + transform: scale(1) translateY(0); +} + +/* Corners */ +.animate-popover-top-left { + transform-origin: top left; + opacity: 0; + transition: + opacity 150ms cubic-bezier(0.4, 0, 0.2, 1), + transform 150ms cubic-bezier(0.4, 0, 0.2, 1); + transform: scale(0.95) translate(-0.5rem, -0.5rem); +} +.animate-popover-top-left[data-enter] { + opacity: 1; + transform: scale(1) translate(0, 0); +} + +.animate-popover-top-right { + transform-origin: top right; + opacity: 0; + transition: + opacity 150ms cubic-bezier(0.4, 0, 0.2, 1), + transform 150ms cubic-bezier(0.4, 0, 0.2, 1); + transform: scale(0.95) translate(0.5rem, -0.5rem); +} +.animate-popover-top-right[data-enter] { + opacity: 1; + transform: scale(1) translate(0, 0); +} + +.animate-popover-bottom-left { + transform-origin: bottom left; + opacity: 0; + transition: + opacity 150ms cubic-bezier(0.4, 0, 0.2, 1), + transform 150ms cubic-bezier(0.4, 0, 0.2, 1); + transform: scale(0.95) translate(-0.5rem, 0.5rem); +} +.animate-popover-bottom-left[data-enter] { + opacity: 1; + transform: scale(1) translate(0, 0); +} + +.animate-popover-bottom-right { + transform-origin: bottom right; + opacity: 0; + transition: + opacity 150ms cubic-bezier(0.4, 0, 0.2, 1), + transform 150ms cubic-bezier(0.4, 0, 0.2, 1); + transform: scale(0.95) translate(0.5rem, 0.5rem); +} +.animate-popover-bottom-right[data-enter] { + opacity: 1; + transform: scale(1) translate(0, 0); +} + /** Note: ensure KaTeX can spread across visible space */ .message-content pre:has(> span.katex) { overflow: visible !important;