🎨 Palette: Improve accessibility of LinkInsertionModal buttons#541
🎨 Palette: Improve accessibility of LinkInsertionModal buttons#541aafre wants to merge 1 commit into
Conversation
Co-authored-by: aafre <8656674+aafre@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
There was a problem hiding this comment.
Code Review
This pull request improves the accessibility of the LinkInsertionModal by adding explicit type="button" attributes and focus-visible ring styles to its action buttons, alongside a new learning log entry documenting these practices. Review feedback identifies several critical accessibility and functional enhancements: implementing a focus trap for the modal to contain keyboard navigation, increasing the color contrast of focus rings for the "Insert/Update" and "Cancel" buttons to meet WCAG standards, and stopping event propagation on button keydown events to prevent conflicts with global modal handlers.
| <button | ||
| type="button" | ||
| onClick={() => { | ||
| onRemove(); | ||
| onClose(); | ||
| }} | ||
| className="px-6 py-3 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-all duration-200" | ||
| className="px-6 py-3 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-red-500 focus-visible:ring-offset-2" | ||
| title="Remove Link" | ||
| > | ||
| Remove | ||
| </button> |
There was a problem hiding this comment.
The 'Remove' button should be conditionally rendered only when the onRemove prop is provided to avoid rendering non-functional UI. Additionally, ensure it has type='button' and stops event propagation to prevent the global Enter key handler on the modal from incorrectly triggering an insert action when this button is focused.
{onRemove && (
<button
type="button"
onClick={() => {
onRemove();
onClose();
}}
onKeyDown={(e) => e.stopPropagation()}
className="px-6 py-3 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-red-500 focus-visible:ring-offset-2"
title="Remove Link"
>
Remove
</button>
)}
References
- Explicitly set type='button' on elements that are not intended to submit a form to prevent unintended form submissions.
- For optional UI elements like a delete button, make the corresponding handler prop (e.g., onDelete) optional and conditionally render the element only when the prop is provided.
| <button | ||
| type="button" | ||
| onClick={onClose} | ||
| className="px-6 py-3 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 transition-all duration-200" | ||
| className="px-6 py-3 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-gray-300 focus-visible:ring-offset-2" | ||
| > | ||
| Cancel | ||
| </button> |
There was a problem hiding this comment.
The focus ring color gray-300 has insufficient contrast. Ensure the button has type='button' to prevent form submission. Also, stop event propagation on onKeyDown to prevent the global Enter key handler from triggering handleInsert when the 'Cancel' button is focused.
<button
type="button"
onClick={onClose}
onKeyDown={(e) => e.stopPropagation()}
className="px-6 py-3 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-gray-600 focus-visible:ring-offset-2"
>
Cancel
</button>
References
- Explicitly set type='button' on elements that are not intended to submit a form to prevent unintended form submissions.
| {/* Buttons */} | ||
| <div className="flex gap-3 mt-6"> | ||
| <button | ||
| type="button" |
There was a problem hiding this comment.
While improving button accessibility, note that this modal is missing a focus trap. According to the repository's general rules, all modals must implement a focus trap to ensure keyboard focus remains within the modal's focusable elements while it is open. This prevents users from accidentally tabbing into the background content.
References
- For accessibility, all modals must implement a focus trap to ensure keyboard focus remains within the modal's focusable elements while it is open.
| <button | ||
| type="button" | ||
| onClick={handleInsert} | ||
| className="flex-1 bg-accent text-ink px-6 py-3 rounded-lg font-semibold hover:shadow-lg transition-all duration-200" | ||
| className="flex-1 bg-accent text-ink px-6 py-3 rounded-lg font-semibold hover:shadow-lg transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2" | ||
| > | ||
| {isEditMode ? 'Update Link' : 'Insert Link'} | ||
| </button> |
There was a problem hiding this comment.
The accent color (#00d47e) used for the focus ring has insufficient contrast (approx. 1.6:1) against the white background, failing WCAG 2.1 accessibility standards (3:1 minimum). Additionally, ensure the button explicitly sets type='button' to prevent unintended form submissions and uses onKeyDown={(e) => e.stopPropagation()} to prevent the modal's global Enter handler from interfering when this button is focused.
| <button | |
| type="button" | |
| onClick={handleInsert} | |
| className="flex-1 bg-accent text-ink px-6 py-3 rounded-lg font-semibold hover:shadow-lg transition-all duration-200" | |
| className="flex-1 bg-accent text-ink px-6 py-3 rounded-lg font-semibold hover:shadow-lg transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2" | |
| > | |
| {isEditMode ? 'Update Link' : 'Insert Link'} | |
| </button> | |
| <button | |
| type="button" | |
| onClick={handleInsert} | |
| onKeyDown={(e) => e.stopPropagation()} | |
| className="flex-1 bg-accent text-ink px-6 py-3 rounded-lg font-semibold hover:shadow-lg transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-ink focus-visible:ring-offset-2" | |
| > | |
| {isEditMode ? 'Update Link' : 'Insert Link'} | |
| </button> |
References
- Explicitly set type='button' on elements that are not intended to submit a form to prevent unintended form submissions.
What: Added
type="button"and focus visible styles to buttons in theLinkInsertionModalcomponent.Why: To prevent accidental form submissions and ensure clear focus indicators for keyboard navigation.
Before/After:
Before: Buttons lacked
type="button"and clear focus indicators.After: Buttons explicitly declare
type="button"and includefocus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2classes.Accessibility: Improved keyboard navigation by adding clear focus outlines and prevented unintended form submissions.
PR created automatically by Jules for task 12308409257029985632 started by @aafre