-
Notifications
You must be signed in to change notification settings - Fork 62
refactor: improve state management and accessibility in components #123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -132,8 +132,8 @@ export const AssistantMessageContainer = ({ | |||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| {/* PaperDebugger blocks */} | ||||||||||||||||||||||||||||||||
| {parsedMessage.paperDebuggerContent.map((content, index) => ( | ||||||||||||||||||||||||||||||||
| <TextPatches key={index} attachment={prevAttachment}> | ||||||||||||||||||||||||||||||||
| {parsedMessage.paperDebuggerContent.map((content) => ( | ||||||||||||||||||||||||||||||||
| <TextPatches key={content} attachment={prevAttachment}> | ||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Content string as React key risks duplicate keysMedium Severity Using |
||||||||||||||||||||||||||||||||
| {content} | ||||||||||||||||||||||||||||||||
| </TextPatches> | ||||||||||||||||||||||||||||||||
| ))} | ||||||||||||||||||||||||||||||||
|
|
@@ -147,7 +147,7 @@ export const AssistantMessageContainer = ({ | |||||||||||||||||||||||||||||||
| {((parsedMessage.regularContent?.length || 0) > 0 || parsedMessage.paperDebuggerContent.length > 0) && ( | ||||||||||||||||||||||||||||||||
| <div className="actions rnd-cancel noselect"> | ||||||||||||||||||||||||||||||||
| <Tooltip content="Copy" placement="bottom" size="sm" delay={1000}> | ||||||||||||||||||||||||||||||||
| <span onClick={handleCopy} tabIndex={0} role="button" aria-label="Copy message"> | ||||||||||||||||||||||||||||||||
| <span onClick={handleCopy} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { handleCopy(); } }} tabIndex={0} role="button" aria-label="Copy message"> | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
| <span onClick={handleCopy} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { handleCopy(); } }} tabIndex={0} role="button" aria-label="Copy message"> | |
| <span | |
| onClick={handleCopy} | |
| onKeyDown={(e) => { | |
| if (e.key === 'Enter' || e.key === ' ') { | |
| if (e.key === ' ') { | |
| e.preventDefault(); | |
| } | |
| handleCopy(); | |
| } | |
| }} | |
| tabIndex={0} | |
| role="button" | |
| aria-label="Copy message" | |
| > |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -95,7 +95,7 @@ export const GeneralToolCard = ({ | |||||
| // When there is a message, show the compact card with collapsible content | ||||||
| return ( | ||||||
| <div className={cn("tool-card noselect compact", { animated: animated })}> | ||||||
| <div className="flex items-center gap-1 cursor-pointer" onClick={toggleCollapse}> | ||||||
| <div className="flex items-center gap-1 cursor-pointer" role="button" tabIndex={0} onClick={toggleCollapse} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { toggleCollapse(); } }}> | ||||||
|
||||||
| <div className="flex items-center gap-1 cursor-pointer" role="button" tabIndex={0} onClick={toggleCollapse} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { toggleCollapse(); } }}> | |
| <div className="flex items-center gap-1 cursor-pointer" role="button" tabIndex={0} onClick={toggleCollapse} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggleCollapse(); } }}> |
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -38,7 +38,10 @@ export const FilterControls = ({ | |||||||||||||||
| <div> | ||||||||||||||||
| <div | ||||||||||||||||
| className="!flex !items-center !justify-between !mb-1 !px-2 cursor-pointer" | ||||||||||||||||
| role="button" | ||||||||||||||||
| tabIndex={0} | ||||||||||||||||
| onClick={() => setIsSuggestionsExpanded(!isSuggestionsExpanded)} | ||||||||||||||||
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsSuggestionsExpanded(!isSuggestionsExpanded); } }} | ||||||||||||||||
|
||||||||||||||||
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsSuggestionsExpanded(!isSuggestionsExpanded); } }} | |
| onKeyDown={(e) => { | |
| if (e.key === 'Enter' || e.key === ' ') { | |
| e.preventDefault(); | |
| setIsSuggestionsExpanded(!isSuggestionsExpanded); | |
| } | |
| }} |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -40,7 +40,10 @@ export const GenerateCitationsCard = ({ functionName, message, preparing, animat | |||||||||||||||||||
| {/* Header with Error label and arrow button */} | ||||||||||||||||||||
| <div | ||||||||||||||||||||
| className="flex items-center justify-between cursor-pointer" | ||||||||||||||||||||
| role="button" | ||||||||||||||||||||
| tabIndex={0} | ||||||||||||||||||||
| onClick={() => setIsMetadataCollapsed(!isMetadataCollapsed)} | ||||||||||||||||||||
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsMetadataCollapsed(!isMetadataCollapsed); } }} | ||||||||||||||||||||
|
||||||||||||||||||||
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsMetadataCollapsed(!isMetadataCollapsed); } }} | |
| onKeyDown={(e) => { | |
| if (e.key === 'Enter' || e.key === ' ') { | |
| if (e.key === ' ') { | |
| e.preventDefault(); | |
| } | |
| setIsMetadataCollapsed(!isMetadataCollapsed); | |
| } | |
| }} |
Copilot
AI
Feb 18, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Space key handler should call e.preventDefault() to prevent the default scrolling behavior. When a user presses Space on a focusable element, the browser will scroll the page by default, which is likely not the intended behavior here.
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsMetadataCollapsed(!isMetadataCollapsed); } }} | |
| onKeyDown={(e) => { | |
| if (e.key === 'Enter' || e.key === ' ') { | |
| if (e.key === ' ') { | |
| e.preventDefault(); | |
| } | |
| setIsMetadataCollapsed(!isMetadataCollapsed); | |
| } | |
| }} |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -40,7 +40,10 @@ export const OnlineSearchPapersCard = ({ functionName, message, preparing, anima | |||||||||||||||||||
| {/* Header with Error label and arrow button */} | ||||||||||||||||||||
| <div | ||||||||||||||||||||
| className="flex items-center justify-between cursor-pointer" | ||||||||||||||||||||
| role="button" | ||||||||||||||||||||
| tabIndex={0} | ||||||||||||||||||||
| onClick={() => setIsMetadataCollapsed(!isMetadataCollapsed)} | ||||||||||||||||||||
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsMetadataCollapsed(!isMetadataCollapsed); } }} | ||||||||||||||||||||
|
||||||||||||||||||||
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsMetadataCollapsed(!isMetadataCollapsed); } }} | |
| onKeyDown={(e) => { | |
| if (e.key === 'Enter' || e.key === ' ') { | |
| if (e.key === ' ') { | |
| e.preventDefault(); | |
| } | |
| setIsMetadataCollapsed(!isMetadataCollapsed); | |
| } | |
| }} |
Copilot
AI
Feb 18, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Space key handler should call e.preventDefault() to prevent the default scrolling behavior. When a user presses Space on a focusable element, the browser will scroll the page by default, which is likely not the intended behavior here.
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsMetadataCollapsed(!isMetadataCollapsed); } }} | |
| onKeyDown={(e) => { | |
| if (e.key === 'Enter' || e.key === ' ') { | |
| e.preventDefault(); | |
| setIsMetadataCollapsed(!isMetadataCollapsed); | |
| } | |
| }} |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,8 +4,8 @@ import MarkdownComponent from "../../../markdown"; | |||||||||||||||||||
| import { useState } from "react"; | ||||||||||||||||||||
| import { XtraMcpToolCardProps, parseXtraMcpToolResult, CollapseArrowButton, CollapseWrapper } from "./utils/common"; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Helper function to render severity levels with strikethrough | ||||||||||||||||||||
| const renderSeverityLevels = (threshold: string) => { | ||||||||||||||||||||
| // Component to render severity levels with strikethrough | ||||||||||||||||||||
| const SeverityLevels = ({ threshold }: { threshold: string }) => { | ||||||||||||||||||||
| const levels = ["nit", "minor", "major", "blocker"]; | ||||||||||||||||||||
| const thresholdIndex = levels.indexOf(threshold.toLowerCase()); | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
@@ -30,7 +30,7 @@ const renderSeverityLevels = (threshold: string) => { | |||||||||||||||||||
| ); | ||||||||||||||||||||
| }; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| const renderSections = (sections: Array<string>) => { | ||||||||||||||||||||
| const Sections = ({ sections }: { sections: Array<string> }) => { | ||||||||||||||||||||
| return ( | ||||||||||||||||||||
| <span> | ||||||||||||||||||||
| {sections.map((section, index) => ( | ||||||||||||||||||||
|
|
@@ -81,7 +81,10 @@ export const ReviewPaperCard = ({ functionName, message, preparing, animated }: | |||||||||||||||||||
| {/* Header with Error label and arrow button */} | ||||||||||||||||||||
| <div | ||||||||||||||||||||
| className="flex items-center justify-between cursor-pointer" | ||||||||||||||||||||
| role="button" | ||||||||||||||||||||
| tabIndex={0} | ||||||||||||||||||||
| onClick={() => setIsMetadataCollapsed(!isMetadataCollapsed)} | ||||||||||||||||||||
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsMetadataCollapsed(!isMetadataCollapsed); } }} | ||||||||||||||||||||
|
||||||||||||||||||||
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsMetadataCollapsed(!isMetadataCollapsed); } }} | |
| onKeyDown={(e) => { | |
| if (e.key === "Enter" || e.key === " ") { | |
| if (e.key === " ") { | |
| e.preventDefault(); | |
| } | |
| setIsMetadataCollapsed(!isMetadataCollapsed); | |
| } | |
| }} |
Copilot
AI
Feb 18, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Space key handler should call e.preventDefault() to prevent the default scrolling behavior. When a user presses Space on a focusable element, the browser will scroll the page by default, which is likely not the intended behavior here.
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsMetadataCollapsed(!isMetadataCollapsed); } }} | |
| onKeyDown={(e) => { | |
| if (e.key === 'Enter' || e.key === ' ') { | |
| e.preventDefault(); | |
| setIsMetadataCollapsed(!isMetadataCollapsed); | |
| } | |
| }} |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -48,7 +48,10 @@ export const SearchRelevantPapersCard = ({ functionName, message, preparing, ani | |||||||||||||||||||
| {/* Header with Error label and arrow button */} | ||||||||||||||||||||
| <div | ||||||||||||||||||||
| className="flex items-center justify-between cursor-pointer" | ||||||||||||||||||||
| role="button" | ||||||||||||||||||||
| tabIndex={0} | ||||||||||||||||||||
| onClick={() => setIsMetadataCollapsed(!isMetadataCollapsed)} | ||||||||||||||||||||
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsMetadataCollapsed(!isMetadataCollapsed); } }} | ||||||||||||||||||||
|
||||||||||||||||||||
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsMetadataCollapsed(!isMetadataCollapsed); } }} | |
| onKeyDown={(e) => { | |
| if (e.key === 'Enter' || e.key === ' ') { | |
| if (e.key === ' ') { | |
| e.preventDefault(); | |
| } | |
| setIsMetadataCollapsed(!isMetadataCollapsed); | |
| } | |
| }} |
Copilot
AI
Feb 18, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Space key handler should call e.preventDefault() to prevent the default scrolling behavior. When a user presses Space on a focusable element, the browser will scroll the page by default, which is likely not the intended behavior here.
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsMetadataCollapsed(!isMetadataCollapsed); } }} | |
| onKeyDown={(e) => { | |
| if (e.key === 'Enter' || e.key === ' ') { | |
| e.preventDefault(); | |
| setIsMetadataCollapsed(!isMetadataCollapsed); | |
| } | |
| }} |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -40,7 +40,10 @@ export const VerifyCitationsCard = ({ functionName, message, preparing, animated | |||||||||||||||||||
| {/* Header with Error label and arrow button */} | ||||||||||||||||||||
| <div | ||||||||||||||||||||
| className="flex items-center justify-between cursor-pointer" | ||||||||||||||||||||
| role="button" | ||||||||||||||||||||
| tabIndex={0} | ||||||||||||||||||||
| onClick={() => setIsMetadataCollapsed(!isMetadataCollapsed)} | ||||||||||||||||||||
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsMetadataCollapsed(!isMetadataCollapsed); } }} | ||||||||||||||||||||
|
||||||||||||||||||||
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsMetadataCollapsed(!isMetadataCollapsed); } }} | |
| onKeyDown={(e) => { | |
| if (e.key === 'Enter') { | |
| setIsMetadataCollapsed(!isMetadataCollapsed); | |
| } else if (e.key === ' ') { | |
| e.preventDefault(); | |
| setIsMetadataCollapsed(!isMetadataCollapsed); | |
| } | |
| }} |
Copilot
AI
Feb 18, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Space key handler should call e.preventDefault() to prevent the default scrolling behavior. When a user presses Space on a focusable element, the browser will scroll the page by default, which is likely not the intended behavior here.
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsMetadataCollapsed(!isMetadataCollapsed); } }} | |
| onKeyDown={(e) => { | |
| if (e.key === 'Enter') { | |
| setIsMetadataCollapsed(!isMetadataCollapsed); | |
| } else if (e.key === ' ') { | |
| e.preventDefault(); | |
| setIsMetadataCollapsed(!isMetadataCollapsed); | |
| } | |
| }} |
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -40,7 +40,10 @@ export const XtraMcpGenericCard = ({ functionName, message, preparing, animated | |||||||||||||||
| {/* Header with Error label and arrow button */} | ||||||||||||||||
| <div | ||||||||||||||||
| className="flex items-center justify-between cursor-pointer" | ||||||||||||||||
| role="button" | ||||||||||||||||
| tabIndex={0} | ||||||||||||||||
| onClick={() => setIsMetadataCollapsed(!isMetadataCollapsed)} | ||||||||||||||||
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsMetadataCollapsed(!isMetadataCollapsed); } }} | ||||||||||||||||
|
||||||||||||||||
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsMetadataCollapsed(!isMetadataCollapsed); } }} | |
| onKeyDown={(e) => { | |
| if (e.key === 'Enter' || e.key === ' ') { | |
| e.preventDefault(); | |
| setIsMetadataCollapsed(!isMetadataCollapsed); | |
| } | |
| }} |
Copilot
AI
Feb 18, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Space key handler should call e.preventDefault() to prevent the default scrolling behavior. When a user presses Space on a focusable element, the browser will scroll the page by default, which is likely not the intended behavior here.
| onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { setIsMetadataCollapsed(!isMetadataCollapsed); } }} | |
| onKeyDown={(e) => { | |
| if (e.key === "Enter" || e.key === " ") { | |
| e.preventDefault(); | |
| setIsMetadataCollapsed(!isMetadataCollapsed); | |
| } | |
| }} |
Copilot
AI
Feb 18, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Space key handler should call e.preventDefault() to prevent the default scrolling behavior. When a user presses Space on a focusable element, the browser will scroll the page by default, which is likely not the intended behavior here.


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using the content string itself as a React key is problematic because duplicate content will have the same key, violating React's uniqueness requirement for keys. This can cause rendering issues if the array contains duplicate strings. Consider using the index or a combination of index and content hash to ensure unique keys.