Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .jules/palette.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Palette's Journal

## UX and Accessibility Learnings
8 changes: 8 additions & 0 deletions plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
1. **Target Component:** `resume-builder-ui/src/components/SectionControls.tsx`
2. **Current State:** The component has three buttons: "Up" (↑), "Down" (↓), and "Delete" (πŸ—‘) using emojis without accessible names or proper focus styles.
3. **UX Improvement:**
- Add proper `aria-label` to each button for screen reader support (e.g., "Move section up", "Move section down", "Delete section").
- Replace emojis with SVG icons using `react-icons/md` (`MdArrowUpward`, `MdArrowDownward`, `MdDelete`) for a more consistent and professional look.
- Add `title` attributes for tooltips on hover.
- Improve hover, focus, and disabled states with more descriptive tailwind classes.
4. **Pre-commit Step:** Complete pre-commit steps to ensure proper testing, verification, review, and reflection are done.
34 changes: 24 additions & 10 deletions resume-builder-ui/src/components/SectionControls.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import React from "react";
import { MdArrowUpward, MdArrowDownward, MdDeleteOutline } from "react-icons/md";

const SectionControls: React.FC<{
sectionIndex: number;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
sections: any[];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
setSections: (sections: any[]) => void;
Comment on lines +6 to 9
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using any and disabling the linter rule reduces type safety. Since this component doesn't need to know the internal structure of the section items, you can replace any[] with the type-safe unknown[]. This makes the component more robust and maintainable.

Suggested change
// eslint-disable-next-line @typescript-eslint/no-explicit-any
sections: any[];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
setSections: (sections: any[]) => void;
sections: unknown[];
setSections: (sections: unknown[]) => void;

}> = ({ sectionIndex, sections, setSections }) => {
const moveSection = (fromIndex: number, toIndex: number) => {
Expand All @@ -19,32 +24,41 @@ const SectionControls: React.FC<{
return (
<div className="absolute top-4 right-4 flex gap-2">
<button
type="button"
onClick={() => moveSection(sectionIndex, sectionIndex - 1)}
disabled={sectionIndex === 0}
className={`px-2 py-1 rounded ${
aria-label="Move section up"
title="Move section up"
className={`p-2 rounded-lg transition-colors focus-visible:ring-2 focus-visible:ring-accent ${
sectionIndex === 0
? "bg-gray-300 cursor-not-allowed"
: "bg-accent hover:bg-accent text-ink"
? "text-gray-400 bg-gray-100 cursor-not-allowed"
: "text-gray-600 hover:text-accent hover:bg-accent/[0.06] active:bg-accent/[0.1]"
}`}
>
↑
<MdArrowUpward className="text-xl" aria-hidden="true" />
</button>
<button
type="button"
onClick={() => moveSection(sectionIndex, sectionIndex + 1)}
disabled={sectionIndex === sections.length - 1}
className={`px-2 py-1 rounded ${
aria-label="Move section down"
title="Move section down"
className={`p-2 rounded-lg transition-colors focus-visible:ring-2 focus-visible:ring-accent ${
sectionIndex === sections.length - 1
? "bg-gray-300 cursor-not-allowed"
: "bg-accent hover:bg-accent text-ink"
? "text-gray-400 bg-gray-100 cursor-not-allowed"
: "text-gray-600 hover:text-accent hover:bg-accent/[0.06] active:bg-accent/[0.1]"
}`}
>
↓
<MdArrowDownward className="text-xl" aria-hidden="true" />
</button>
Comment on lines 26 to 53
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The up and down buttons share a significant amount of Tailwind CSS classes, leading to code duplication. To improve maintainability and ensure consistency, you could extract the common and state-specific classes into variables.

For example:
const baseClasses = "p-2 rounded-lg transition-colors focus-visible:ring-2 focus-visible:ring-accent";
const disabledClasses = "text-gray-400 bg-gray-100 cursor-not-allowed";
const enabledClasses = "text-gray-600 hover:text-accent hover:bg-accent/[0.06] active:bg-accent/[0.1]";

// Then apply them like this:
<button
// ...
className={${baseClasses} ${disabled ? disabledClasses : enabledClasses}}
/>
This would make the styling logic cleaner and easier to manage.

<button
type="button"
onClick={deleteSection}
className="bg-red-500 hover:bg-red-600 text-white px-3 py-1 rounded"
aria-label="Delete section"
title="Delete section"
className="p-2 rounded-lg text-gray-500 hover:text-red-600 hover:bg-red-50 transition-colors focus-visible:ring-2 focus-visible:ring-red-500 ml-1"
>
πŸ—‘
<MdDeleteOutline className="text-xl" aria-hidden="true" />
</button>
</div>
);
Expand Down
Loading