📱 fix: Mention Touch UX and MCP Tool UI Consistency (#11627)

* refactor: Reorganize imports in MCPTools component

- Updated import statements in MCPTools.tsx for improved clarity and maintainability.
- Moved `useAgentPanelContext` import above others and adjusted the order of `PermissionTypes` and `Permissions` imports to enhance readability.

* chore: imports

* refactor: Update MCPToolItem component props and styles

- Added new props: onToggleDefer, onToggleSelect, and onToggleProgrammatic for improved functionality.
- Adjusted class names for DropdownMenuLabel and text spans to enhance visual consistency and clarity.
- Increased width of DropdownMenuContent for better layout.

* refactor: Update DropdownMenu styles for improved visual consistency

- Changed background color of DropdownMenuContent and DropdownMenuSubContent from secondary to primary for better alignment with design standards.
- Updated text color to ensure readability against the new background, enhancing overall user experience.

* refactor: Update Mention component styles and interaction handling

- Increased ROW_HEIGHT in Mention and PromptsCommand components for improved layout consistency.
- Enhanced MentionItem component with touch event handling to improve mobile interaction experience.
- Updated button styles to ensure better visual alignment and responsiveness.

* refactor: Enhance MentionItem component event handling and button attributes

- Updated the onClick prop type in MentionItem to support both mouse and touch events, improving mobile interaction.
- Added a button type attribute for better accessibility and compliance with HTML standards.
- Refined event handling to ensure consistent behavior across different input methods.

* refactor: Add button type attribute to MentionItem for improved accessibility

- Added a type="button" attribute to the MentionItem component to enhance accessibility and compliance with HTML standards.
- This change ensures better interaction behavior across different input methods.

* refactor: Simplify MentionItem event handling for improved clarity

- Removed touch event handling from the MentionItem component, streamlining the onClick prop to only accept mouse events.
- This change simplifies the interaction logic, enhancing maintainability while retaining functionality for mouse interactions.
This commit is contained in:
Danny Avila 2026-02-04 15:22:32 +01:00 committed by GitHub
parent 2cef9368ea
commit e89e514fcb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 18 additions and 17 deletions

View file

@ -12,7 +12,7 @@ import useMentions from '~/hooks/Input/useMentions';
import { removeCharIfLast } from '~/utils';
import MentionItem from './MentionItem';
const ROW_HEIGHT = 40;
const ROW_HEIGHT = 44;
export default function Mention({
conversation,

View file

@ -25,15 +25,16 @@ export default function MentionItem({
}: MentionItemProps) {
return (
<button
type="button"
style={style}
tabIndex={index}
onClick={onClick}
id={`${type}-item-${index}`}
className="w-full"
style={style}
className="w-full touch-manipulation"
>
<div
className={cn(
'text-token-text-primary bg-token-main-surface-secondary group flex h-10 items-center gap-2 rounded-lg px-2 text-sm font-medium hover:bg-surface-secondary',
'text-token-text-primary bg-token-main-surface-secondary group flex min-h-[44px] items-center gap-2 rounded-lg px-2 text-sm font-medium hover:bg-surface-secondary active:bg-surface-active',
isActive === true ? 'bg-surface-active' : 'bg-transparent',
)}
>

View file

@ -4,8 +4,8 @@ import { Spinner, useCombobox } from '@librechat/client';
import { useSetRecoilState, useRecoilValue } from 'recoil';
import type { TPromptGroup } from 'librechat-data-provider';
import type { PromptOption } from '~/common';
import { removeCharIfLast, detectVariables } from '~/utils';
import VariableDialog from '~/components/Prompts/Groups/VariableDialog';
import { removeCharIfLast, detectVariables } from '~/utils';
import { usePromptGroupsContext } from '~/Providers';
import MentionItem from './MentionItem';
import { useLocalize } from '~/hooks';
@ -48,7 +48,7 @@ const PopoverContainer = memo(
},
);
const ROW_HEIGHT = 40;
const ROW_HEIGHT = 44;
function PromptsCommand({
index,

View file

@ -42,12 +42,12 @@ export default function MCPToolItem({
tool,
isSelected,
isDeferred,
onToggleDefer,
onToggleSelect,
isProgrammatic,
onToggleProgrammatic,
deferredToolsEnabled,
programmaticToolsEnabled,
onToggleSelect,
onToggleDefer,
onToggleProgrammatic,
}: MCPToolItemProps) {
const localize = useLocalize();
const hasOptions = isDeferred || isProgrammatic;
@ -104,10 +104,10 @@ export default function MCPToolItem({
<DropdownMenuContent
align="end"
side="left"
className="w-64"
className="w-80"
onClick={(e) => e.stopPropagation()}
>
<DropdownMenuLabel className="text-xs font-normal text-text-secondary">
<DropdownMenuLabel className="text-xs font-normal text-text-primary">
{tool.metadata.description || localize('com_ui_mcp_no_description')}
</DropdownMenuLabel>
<DropdownMenuSeparator />
@ -121,7 +121,7 @@ export default function MCPToolItem({
<Clock className="h-4 w-4 text-amber-500" />
<div className="flex flex-col">
<span>{localize('com_ui_mcp_defer_loading')}</span>
<span className="text-xs text-text-tertiary">
<span className="text-xs text-text-secondary">
{localize('com_ui_mcp_click_to_defer')}
</span>
</div>
@ -138,7 +138,7 @@ export default function MCPToolItem({
<Code2 className="h-4 w-4 text-violet-500" />
<div className="flex flex-col">
<span>{localize('com_ui_mcp_programmatic')}</span>
<span className="text-xs text-text-tertiary">
<span className="text-xs text-text-secondary">
{localize('com_ui_mcp_click_to_programmatic')}
</span>
</div>

View file

@ -1,10 +1,10 @@
import React from 'react';
import { PermissionTypes, Permissions } from 'librechat-data-provider';
import UninitializedMCPTool from './UninitializedMCPTool';
import UnconfiguredMCPTool from './UnconfiguredMCPTool';
import { useAgentPanelContext } from '~/Providers';
import { useHasAccess, useLocalize } from '~/hooks';
import { useAgentPanelContext } from '~/Providers';
import MCPTool from './MCPTool';
import { PermissionTypes, Permissions } from 'librechat-data-provider';
export default function MCPTools({
agentId,

View file

@ -30,7 +30,7 @@ function DropdownMenuContent({
data-slot="dropdown-menu-content"
sideOffset={sideOffset}
className={cn(
'text-popover-foreground max-h-(--radix-dropdown-menu-content-available-height) origin-(--radix-dropdown-menu-content-transform-origin) z-40 min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border border-border-light bg-surface-secondary p-1 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
'max-h-(--radix-dropdown-menu-content-available-height) origin-(--radix-dropdown-menu-content-transform-origin) z-40 min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border border-border-medium bg-surface-primary p-1 text-text-primary shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
className,
)}
{...props}
@ -198,7 +198,7 @@ function DropdownMenuSubContent({
<DropdownMenuPrimitive.SubContent
data-slot="dropdown-menu-sub-content"
className={cn(
'text-popover-foreground origin-(--radix-dropdown-menu-content-transform-origin) z-40 min-w-[8rem] overflow-hidden rounded-md border border-border-medium bg-surface-secondary p-1 shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
'origin-(--radix-dropdown-menu-content-transform-origin) z-40 min-w-[8rem] overflow-hidden rounded-md border border-border-medium bg-surface-primary p-1 text-text-primary shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
className,
)}
{...props}