From 1e7d8ffe7425c806a6b735ac636aafa86cc76c7f Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sun, 2 Aug 2026 14:21:27 +0000 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20[UX=20improvement?= =?UTF-8?q?]=20=EC=A0=91=EA=B7=BC=EC=84=B1=20=EC=9E=88=EB=8A=94=20?= =?UTF-8?q?=ED=88=B4=ED=8C=81=EC=9D=84=20=EC=9C=84=ED=95=9C=20disabled=20?= =?UTF-8?q?=EC=86=8D=EC=84=B1=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit πŸ’‘ What: ScoreView μ»΄ν¬λ„ŒνŠΈ λ‚΄μ˜ "Open score" λ²„νŠΌμ—μ„œ native disabled 속성을 μ œκ±°ν•˜κ³ , aria-disabled와 title 툴팁으둜 λŒ€μ²΄ν–ˆμŠ΅λ‹ˆλ‹€. 🎯 Why: native disabled 속성은 슀크린 λ¦¬λ”μ—μ„œ μš”μ†Œλ₯Ό μ™„μ „νžˆ 숨기고 마우슀 이벀트λ₯Ό μ°¨λ‹¨ν•˜μ—¬, λΉ„ν™œμ„±ν™”λœ 이유λ₯Ό μ„€λͺ…ν•˜λŠ” 툴팁이 ν‘œμ‹œλ˜μ§€ μ•ŠλŠ” μ ‘κ·Όμ„± λ¬Έμ œκ°€ μžˆμ—ˆκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. πŸ“Έ Before/After: ν•΄λ‹Ή μ—†μŒ β™Ώ Accessibility: λΉ„μž₯애인 및 슀크린 리더 μ‚¬μš©μž λͺ¨λ‘ λΉ„ν™œμ„±ν™”λœ 이유("Analyze or open a song first")λ₯Ό λͺ…ν™•νžˆ 인지할 수 μžˆλ„λ‘ κ°œμ„ λ˜μ—ˆμŠ΅λ‹ˆλ‹€. --- apps/desktop/src/features/score/ScoreView.test.tsx | 12 +++++++++++- apps/desktop/src/features/score/ScoreView.tsx | 5 +++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/apps/desktop/src/features/score/ScoreView.test.tsx b/apps/desktop/src/features/score/ScoreView.test.tsx index de4ccb95..4c432e7f 100644 --- a/apps/desktop/src/features/score/ScoreView.test.tsx +++ b/apps/desktop/src/features/score/ScoreView.test.tsx @@ -96,7 +96,7 @@ describe("ScoreView", () => { expect(screen.getByText("Scores attach to the active analysis project.")).toBeInTheDocument(); expect(screen.getByRole("button", { name: "Add score" })).toBeDisabled(); - expect(screen.getByRole("button", { name: "Open score: opener.pdf" })).toBeDisabled(); + expect(screen.getByRole("button", { name: "Open score: opener.pdf" })).toHaveAttribute("aria-disabled", "true"); expect(screen.getByRole("button", { name: "Remove: opener.pdf" })).toBeDisabled(); fireEvent.click(screen.getByRole("button", { name: "Open score: opener.pdf" })); @@ -180,6 +180,16 @@ describe("ScoreView", () => { }); }); + it("renders disabled score open buttons with aria-disabled and a tooltip when there is no projectId", () => { + const song = makeSong([{ id: SCORE_ID, fileName: "opener.pdf" }]); + render(); + + const button = screen.getByRole("button", { name: "Open score: opener.pdf" }); + expect(button).toHaveAttribute("aria-disabled", "true"); + expect(button).toHaveAttribute("title", "scoreNavDisabledHint"); + expect(button).not.toBeDisabled(); + }); + it("accepts Uint8Array read responses from the bridge", async () => { mockInvoke.mockResolvedValueOnce(new Uint8Array([7, 7])); const song = makeSong([{ id: SCORE_ID, fileName: "opener.pdf" }]); diff --git a/apps/desktop/src/features/score/ScoreView.tsx b/apps/desktop/src/features/score/ScoreView.tsx index 72732450..8437b05e 100644 --- a/apps/desktop/src/features/score/ScoreView.tsx +++ b/apps/desktop/src/features/score/ScoreView.tsx @@ -184,10 +184,11 @@ export function ScoreView({ song, projectId, onSongUpdate }: ScoreViewProps) {