From b5f41e4ed5a240c1746862755be815d1b4d0e64c Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 24 Mar 2026 09:29:01 +0000 Subject: [PATCH] feat: improve React component performance and accessibility - Wrap ChatMessageBubble with React.memo to prevent unnecessary re-renders - Replace window.location.reload() with Inertia router.reload() in apps settings - Add ARIA attributes to StyledModal (role, aria-modal, aria-labelledby) - Add aria-label to chat textarea, send button, and suggestion buttons - Memoize suggestion click handler with useCallback in ChatInterface - Add role="article" to chat message containers for screen readers https://claude.ai/code/session_01JFvpTYgm8GiE4vJ4cJKsFx --- admin/inertia/components/StyledModal.tsx | 5 ++++- .../inertia/components/chat/ChatInterface.tsx | 21 ++++++++++++------- .../components/chat/ChatMessageBubble.tsx | 7 ++++++- admin/inertia/pages/settings/apps.tsx | 10 ++++----- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/admin/inertia/components/StyledModal.tsx b/admin/inertia/components/StyledModal.tsx index 0e0d784..31b9349 100644 --- a/admin/inertia/components/StyledModal.tsx +++ b/admin/inertia/components/StyledModal.tsx @@ -45,6 +45,9 @@ const StyledModal: React.FC = ({ if (onClose) onClose() }} className="relative z-50" + role="dialog" + aria-modal="true" + aria-labelledby="styled-modal-title" > = ({
{icon &&
{icon}
}
- + {title}
{children}
diff --git a/admin/inertia/components/chat/ChatInterface.tsx b/admin/inertia/components/chat/ChatInterface.tsx index ffdd017..90e2b8a 100644 --- a/admin/inertia/components/chat/ChatInterface.tsx +++ b/admin/inertia/components/chat/ChatInterface.tsx @@ -1,5 +1,5 @@ import { IconSend, IconWand } from '@tabler/icons-react' -import { useState, useRef, useEffect } from 'react' +import { useState, useRef, useEffect, useCallback } from 'react' import classNames from '~/lib/classNames' import { ChatMessage } from '../../../types/chat' import ChatMessageBubble from './ChatMessageBubble' @@ -84,6 +84,14 @@ export default function ChatInterface({ e.target.style.height = `${Math.min(e.target.scrollHeight, 200)}px` } + const handleSuggestionClick = useCallback((suggestion: string) => { + setInput(suggestion) + // Focus the textarea after setting input + setTimeout(() => { + textareaRef.current?.focus() + }, 0) + }, []) + return (
@@ -102,13 +110,8 @@ export default function ChatInterface({ {chatSuggestions.map((suggestion, index) => (