Skip to content
Merged
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
46 changes: 37 additions & 9 deletions src/components/Favorite/Favorite.css
Original file line number Diff line number Diff line change
@@ -1,22 +1,50 @@
.favorite-button {
background: transparent;
border: none;
font-size: 1.5rem;
cursor: pointer;
padding: 0.5rem;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.2s ease-in-out;
width: 36px;
height: 36px;
padding: 0;
border: 1px solid var(--border);
background: var(--panel);
border-radius: 8px;
color: var(--muted);
cursor: pointer;
transition:
transform 0.2s ease-in-out,
color 0.2s,
border-color 0.2s,
background 0.2s;
}

.favorite-button svg {
width: 20px;
height: 20px;
fill: none;
stroke: currentColor;
stroke-width: 2;
}

.favorite-button:hover {
transform: scale(1.2);
color: #e0245e;
border-color: #e0245e;
background: #fff0f4;
transform: scale(1.08);
}

/* Filled red heart when the pokemon is a favorite */
.favorite-button.is-favorite {
color: #e0245e;
border-color: #e0245e;
background: #fff0f4;
}

.favorite-button.is-favorite svg {
fill: currentColor;
}

.favorite-button:focus-visible {
outline: 2px solid #0056b3;
outline: 2px solid var(--accent);
outline-offset: 2px;
}

Expand Down
4 changes: 2 additions & 2 deletions src/components/Favorite/Favorite.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ describe("Favorite Component", () => {
render(<Favorite isFavorite={false} onToggle={() => {}} />);

const button = screen.getByRole("button", { name: "Add to favorites" });
expect(button.textContent).toBe("🤍");
expect(button.getAttribute("aria-pressed")).toBe("false");
expect(button.classList.contains("is-favorite")).toBe(false);
});

test("shows filled heart when favorite", () => {
Expand All @@ -17,8 +17,8 @@ describe("Favorite Component", () => {
const button = screen.getByRole("button", {
name: "Remove from favorites",
});
expect(button.textContent).toBe("❤️");
expect(button.getAttribute("aria-pressed")).toBe("true");
expect(button.classList.contains("is-favorite")).toBe(true);
});

test("calls onToggle when clicked", () => {
Expand Down
8 changes: 6 additions & 2 deletions src/components/Favorite/Favorite.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ type FavoriteProps = {
export function Favorite({ isFavorite, onToggle }: FavoriteProps) {
return (
<button
type="button"
onClick={onToggle}
aria-pressed={isFavorite}
aria-label={isFavorite ? "Remove from favorites" : "Add to favorites"}
className="favorite-button"
className={`favorite-button ${isFavorite ? "is-favorite" : ""}`}
>
{isFavorite ? "❤️" : "🤍"}
{/* Own svg instead of an emoji so the heart looks the same on every OS */}
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
</svg>
</button>
);
}
13 changes: 11 additions & 2 deletions src/components/Favorite/__snapshots__/Favorite.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,18 @@ exports[`Favorite Component > matches snapshot 1`] = `
<button
aria-label="Remove from favorites"
aria-pressed="true"
class="favorite-button"
class="favorite-button is-favorite"
type="button"
>
❤️
<svg
aria-hidden="true"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"
/>
</svg>
</button>
</DocumentFragment>
`;