From b794906f152503459fdb5f156dcf09a6305af350 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Fri, 18 Sep 2026 14:01:50 +0000 Subject: [PATCH 01/14] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20=EC=95=85?= =?UTF-8?q?=EB=B3=B4=20=EB=B7=B0=EC=96=B4=20=EC=95=84=EC=9D=B4=EC=BD=98=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=EC=97=90=20=ED=88=B4=ED=8C=81=20=EB=B0=8F=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=EC=84=B1=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/features/score/ScoreViewer.test.tsx | 16 +++- .../src/features/score/ScoreViewer.tsx | 95 +++++++++++-------- 2 files changed, 68 insertions(+), 43 deletions(-) diff --git a/apps/desktop/src/features/score/ScoreViewer.test.tsx b/apps/desktop/src/features/score/ScoreViewer.test.tsx index 3ac2dd605..429f11871 100644 --- a/apps/desktop/src/features/score/ScoreViewer.test.tsx +++ b/apps/desktop/src/features/score/ScoreViewer.test.tsx @@ -120,8 +120,8 @@ describe("ScoreViewer", () => { expect(page.render).toHaveBeenCalled(); }); expect(page.getViewport).toHaveBeenCalledWith({ scale: 1 }); - expect(screen.getByRole("button", { name: "Previous page" })).toBeDisabled(); - expect(screen.getByRole("button", { name: "Next page" })).toBeEnabled(); + expect(screen.getByRole("button", { name: "Previous page" })).toHaveAttribute("aria-disabled", "true"); + expect(screen.getByRole("button", { name: "Next page" })).not.toHaveAttribute("aria-disabled"); }); it("shows the file name when provided", async () => { @@ -174,14 +174,22 @@ describe("ScoreViewer", () => { expect(await screen.findByText("Page 1 of 3")).toBeInTheDocument(); const previousButton = screen.getByRole("button", { name: "Previous page" }); const nextButton = screen.getByRole("button", { name: "Next page" }); - expect(previousButton).toBeDisabled(); + expect(previousButton).toHaveAttribute("aria-disabled", "true"); + + // Test clicking previous when disabled + fireEvent.click(previousButton); + expect(screen.getByText("Page 1 of 3")).toBeInTheDocument(); fireEvent.click(nextButton); expect(screen.getByText("Page 2 of 3")).toBeInTheDocument(); fireEvent.click(nextButton); expect(screen.getByText("Page 3 of 3")).toBeInTheDocument(); - expect(nextButton).toBeDisabled(); + expect(nextButton).toHaveAttribute("aria-disabled", "true"); + + // Test clicking next when disabled + fireEvent.click(nextButton); + expect(screen.getByText("Page 3 of 3")).toBeInTheDocument(); await waitFor(() => { expect(doc.getPage).toHaveBeenCalledWith(3); diff --git a/apps/desktop/src/features/score/ScoreViewer.tsx b/apps/desktop/src/features/score/ScoreViewer.tsx index 82692469e..f18e7ec99 100644 --- a/apps/desktop/src/features/score/ScoreViewer.tsx +++ b/apps/desktop/src/features/score/ScoreViewer.tsx @@ -12,8 +12,9 @@ import { ZoomOut, } from "lucide-react"; import { createTranslator, detectPreferredLocale } from "../../i18n"; -import { Button } from "@/components/ui/button"; +import { Button, buttonVariants } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; +import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { loadScorePdf } from "./pdfjs"; /** Viewer lifecycle states following the clearfolio LOADING/FAILED/READY contract. */ @@ -253,24 +254,26 @@ export function ScoreViewer({ data, fileName, onStatusChange }: ScoreViewerProps )}
- - + + + + {t("scoreViewerZoomOut")} + + + + + {t("scoreViewerZoomIn")} +
- + + ) => { + if (e.currentTarget.getAttribute("aria-disabled") === "true") { + e.preventDefault(); + return; + } + goToPreviousPage(); + }} + > + + {t("scoreViewerPrevPage")} + {pageIndicator} - + + = pageCount ? "true" : undefined} + onClick={(e: React.MouseEvent) => { + if (e.currentTarget.getAttribute("aria-disabled") === "true") { + e.preventDefault(); + return; + } + goToNextPage(); + }} + > + + {t("scoreViewerNextPage")} +
From 746c06a8e56542cb17f23f211b1a44a08dfbe9cd Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sat, 19 Sep 2026 01:03:25 +0000 Subject: [PATCH 02/14] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20=EC=95=85?= =?UTF-8?q?=EB=B3=B4=20=EB=B7=B0=EC=96=B4=20=EC=95=84=EC=9D=B4=EC=BD=98=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=EC=97=90=20=ED=88=B4=ED=8C=81=20=EB=B0=8F=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=EC=84=B1=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 3fc9962d6c92b7f7768e7b44c43a107708917fea Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sat, 19 Sep 2026 12:25:04 +0000 Subject: [PATCH 03/14] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20=EC=95=85?= =?UTF-8?q?=EB=B3=B4=20=EB=B7=B0=EC=96=B4=20=EC=95=84=EC=9D=B4=EC=BD=98=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=EC=97=90=20=ED=88=B4=ED=8C=81=20=EB=B0=8F=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=EC=84=B1=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 7f3fdc824ca87e21f795298ab3443200b02fe8cb Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sat, 19 Sep 2026 21:34:48 +0000 Subject: [PATCH 04/14] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20=EC=95=85?= =?UTF-8?q?=EB=B3=B4=20=EB=B7=B0=EC=96=B4=20=EC=95=84=EC=9D=B4=EC=BD=98=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=EC=97=90=20=ED=88=B4=ED=8C=81=20=EB=B0=8F=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=EC=84=B1=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 6890f8dfffefd487ac5a3a432a621e6e3a9d3491 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sun, 20 Sep 2026 21:49:08 +0000 Subject: [PATCH 05/14] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20=EC=95=85?= =?UTF-8?q?=EB=B3=B4=20=EB=B7=B0=EC=96=B4=20=EC=95=84=EC=9D=B4=EC=BD=98=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=EC=97=90=20=ED=88=B4=ED=8C=81=20=EB=B0=8F=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=EC=84=B1=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/features/score/ScoreViewer.test.tsx | 16 +--- .../src/features/score/ScoreViewer.tsx | 95 ++++++++----------- 2 files changed, 43 insertions(+), 68 deletions(-) diff --git a/apps/desktop/src/features/score/ScoreViewer.test.tsx b/apps/desktop/src/features/score/ScoreViewer.test.tsx index 429f11871..3ac2dd605 100644 --- a/apps/desktop/src/features/score/ScoreViewer.test.tsx +++ b/apps/desktop/src/features/score/ScoreViewer.test.tsx @@ -120,8 +120,8 @@ describe("ScoreViewer", () => { expect(page.render).toHaveBeenCalled(); }); expect(page.getViewport).toHaveBeenCalledWith({ scale: 1 }); - expect(screen.getByRole("button", { name: "Previous page" })).toHaveAttribute("aria-disabled", "true"); - expect(screen.getByRole("button", { name: "Next page" })).not.toHaveAttribute("aria-disabled"); + expect(screen.getByRole("button", { name: "Previous page" })).toBeDisabled(); + expect(screen.getByRole("button", { name: "Next page" })).toBeEnabled(); }); it("shows the file name when provided", async () => { @@ -174,22 +174,14 @@ describe("ScoreViewer", () => { expect(await screen.findByText("Page 1 of 3")).toBeInTheDocument(); const previousButton = screen.getByRole("button", { name: "Previous page" }); const nextButton = screen.getByRole("button", { name: "Next page" }); - expect(previousButton).toHaveAttribute("aria-disabled", "true"); - - // Test clicking previous when disabled - fireEvent.click(previousButton); - expect(screen.getByText("Page 1 of 3")).toBeInTheDocument(); + expect(previousButton).toBeDisabled(); fireEvent.click(nextButton); expect(screen.getByText("Page 2 of 3")).toBeInTheDocument(); fireEvent.click(nextButton); expect(screen.getByText("Page 3 of 3")).toBeInTheDocument(); - expect(nextButton).toHaveAttribute("aria-disabled", "true"); - - // Test clicking next when disabled - fireEvent.click(nextButton); - expect(screen.getByText("Page 3 of 3")).toBeInTheDocument(); + expect(nextButton).toBeDisabled(); await waitFor(() => { expect(doc.getPage).toHaveBeenCalledWith(3); diff --git a/apps/desktop/src/features/score/ScoreViewer.tsx b/apps/desktop/src/features/score/ScoreViewer.tsx index f18e7ec99..82692469e 100644 --- a/apps/desktop/src/features/score/ScoreViewer.tsx +++ b/apps/desktop/src/features/score/ScoreViewer.tsx @@ -12,9 +12,8 @@ import { ZoomOut, } from "lucide-react"; import { createTranslator, detectPreferredLocale } from "../../i18n"; -import { Button, buttonVariants } from "@/components/ui/button"; +import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; -import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { loadScorePdf } from "./pdfjs"; /** Viewer lifecycle states following the clearfolio LOADING/FAILED/READY contract. */ @@ -254,26 +253,24 @@ export function ScoreViewer({ data, fileName, onStatusChange }: ScoreViewerProps )}
- - - - {t("scoreViewerZoomOut")} - - - - - {t("scoreViewerZoomIn")} - + +
- - ) => { - if (e.currentTarget.getAttribute("aria-disabled") === "true") { - e.preventDefault(); - return; - } - goToPreviousPage(); - }} - > - - {t("scoreViewerPrevPage")} - + {pageIndicator} - - = pageCount ? "true" : undefined} - onClick={(e: React.MouseEvent) => { - if (e.currentTarget.getAttribute("aria-disabled") === "true") { - e.preventDefault(); - return; - } - goToNextPage(); - }} - > - - {t("scoreViewerNextPage")} - +
From 0995a5ee5093e0a613420cd2034870f56f1e1036 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 23 Sep 2026 07:06:26 +0900 Subject: [PATCH 06/14] repair(ui): restore ScoreViewer tooltip preservation contract --- .../src/features/score/ScoreViewer.test.tsx | 16 +++- .../src/features/score/ScoreViewer.tsx | 95 +++++++++++-------- 2 files changed, 68 insertions(+), 43 deletions(-) diff --git a/apps/desktop/src/features/score/ScoreViewer.test.tsx b/apps/desktop/src/features/score/ScoreViewer.test.tsx index 3ac2dd605..429f11871 100644 --- a/apps/desktop/src/features/score/ScoreViewer.test.tsx +++ b/apps/desktop/src/features/score/ScoreViewer.test.tsx @@ -120,8 +120,8 @@ describe("ScoreViewer", () => { expect(page.render).toHaveBeenCalled(); }); expect(page.getViewport).toHaveBeenCalledWith({ scale: 1 }); - expect(screen.getByRole("button", { name: "Previous page" })).toBeDisabled(); - expect(screen.getByRole("button", { name: "Next page" })).toBeEnabled(); + expect(screen.getByRole("button", { name: "Previous page" })).toHaveAttribute("aria-disabled", "true"); + expect(screen.getByRole("button", { name: "Next page" })).not.toHaveAttribute("aria-disabled"); }); it("shows the file name when provided", async () => { @@ -174,14 +174,22 @@ describe("ScoreViewer", () => { expect(await screen.findByText("Page 1 of 3")).toBeInTheDocument(); const previousButton = screen.getByRole("button", { name: "Previous page" }); const nextButton = screen.getByRole("button", { name: "Next page" }); - expect(previousButton).toBeDisabled(); + expect(previousButton).toHaveAttribute("aria-disabled", "true"); + + // Test clicking previous when disabled + fireEvent.click(previousButton); + expect(screen.getByText("Page 1 of 3")).toBeInTheDocument(); fireEvent.click(nextButton); expect(screen.getByText("Page 2 of 3")).toBeInTheDocument(); fireEvent.click(nextButton); expect(screen.getByText("Page 3 of 3")).toBeInTheDocument(); - expect(nextButton).toBeDisabled(); + expect(nextButton).toHaveAttribute("aria-disabled", "true"); + + // Test clicking next when disabled + fireEvent.click(nextButton); + expect(screen.getByText("Page 3 of 3")).toBeInTheDocument(); await waitFor(() => { expect(doc.getPage).toHaveBeenCalledWith(3); diff --git a/apps/desktop/src/features/score/ScoreViewer.tsx b/apps/desktop/src/features/score/ScoreViewer.tsx index 82692469e..f18e7ec99 100644 --- a/apps/desktop/src/features/score/ScoreViewer.tsx +++ b/apps/desktop/src/features/score/ScoreViewer.tsx @@ -12,8 +12,9 @@ import { ZoomOut, } from "lucide-react"; import { createTranslator, detectPreferredLocale } from "../../i18n"; -import { Button } from "@/components/ui/button"; +import { Button, buttonVariants } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; +import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { loadScorePdf } from "./pdfjs"; /** Viewer lifecycle states following the clearfolio LOADING/FAILED/READY contract. */ @@ -253,24 +254,26 @@ export function ScoreViewer({ data, fileName, onStatusChange }: ScoreViewerProps )}
- - + + + + {t("scoreViewerZoomOut")} + + + + + {t("scoreViewerZoomIn")} +
- + + ) => { + if (e.currentTarget.getAttribute("aria-disabled") === "true") { + e.preventDefault(); + return; + } + goToPreviousPage(); + }} + > + + {t("scoreViewerPrevPage")} + {pageIndicator} - + + = pageCount ? "true" : undefined} + onClick={(e: React.MouseEvent) => { + if (e.currentTarget.getAttribute("aria-disabled") === "true") { + e.preventDefault(); + return; + } + goToNextPage(); + }} + > + + {t("scoreViewerNextPage")} +
From b367155eccd94c22f2ede80e024892e39bca1947 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Wed, 23 Sep 2026 03:53:35 +0000 Subject: [PATCH 07/14] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20=EC=95=85?= =?UTF-8?q?=EB=B3=B4=20=EB=B7=B0=EC=96=B4=20=EC=95=84=EC=9D=B4=EC=BD=98=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=EC=97=90=20=ED=88=B4=ED=8C=81=20=EB=B0=8F=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=EC=84=B1=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/features/score/ScoreViewer.test.tsx | 16 +--- .../src/features/score/ScoreViewer.tsx | 95 ++++++++----------- 2 files changed, 43 insertions(+), 68 deletions(-) diff --git a/apps/desktop/src/features/score/ScoreViewer.test.tsx b/apps/desktop/src/features/score/ScoreViewer.test.tsx index 429f11871..3ac2dd605 100644 --- a/apps/desktop/src/features/score/ScoreViewer.test.tsx +++ b/apps/desktop/src/features/score/ScoreViewer.test.tsx @@ -120,8 +120,8 @@ describe("ScoreViewer", () => { expect(page.render).toHaveBeenCalled(); }); expect(page.getViewport).toHaveBeenCalledWith({ scale: 1 }); - expect(screen.getByRole("button", { name: "Previous page" })).toHaveAttribute("aria-disabled", "true"); - expect(screen.getByRole("button", { name: "Next page" })).not.toHaveAttribute("aria-disabled"); + expect(screen.getByRole("button", { name: "Previous page" })).toBeDisabled(); + expect(screen.getByRole("button", { name: "Next page" })).toBeEnabled(); }); it("shows the file name when provided", async () => { @@ -174,22 +174,14 @@ describe("ScoreViewer", () => { expect(await screen.findByText("Page 1 of 3")).toBeInTheDocument(); const previousButton = screen.getByRole("button", { name: "Previous page" }); const nextButton = screen.getByRole("button", { name: "Next page" }); - expect(previousButton).toHaveAttribute("aria-disabled", "true"); - - // Test clicking previous when disabled - fireEvent.click(previousButton); - expect(screen.getByText("Page 1 of 3")).toBeInTheDocument(); + expect(previousButton).toBeDisabled(); fireEvent.click(nextButton); expect(screen.getByText("Page 2 of 3")).toBeInTheDocument(); fireEvent.click(nextButton); expect(screen.getByText("Page 3 of 3")).toBeInTheDocument(); - expect(nextButton).toHaveAttribute("aria-disabled", "true"); - - // Test clicking next when disabled - fireEvent.click(nextButton); - expect(screen.getByText("Page 3 of 3")).toBeInTheDocument(); + expect(nextButton).toBeDisabled(); await waitFor(() => { expect(doc.getPage).toHaveBeenCalledWith(3); diff --git a/apps/desktop/src/features/score/ScoreViewer.tsx b/apps/desktop/src/features/score/ScoreViewer.tsx index f18e7ec99..82692469e 100644 --- a/apps/desktop/src/features/score/ScoreViewer.tsx +++ b/apps/desktop/src/features/score/ScoreViewer.tsx @@ -12,9 +12,8 @@ import { ZoomOut, } from "lucide-react"; import { createTranslator, detectPreferredLocale } from "../../i18n"; -import { Button, buttonVariants } from "@/components/ui/button"; +import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; -import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { loadScorePdf } from "./pdfjs"; /** Viewer lifecycle states following the clearfolio LOADING/FAILED/READY contract. */ @@ -254,26 +253,24 @@ export function ScoreViewer({ data, fileName, onStatusChange }: ScoreViewerProps )}
- - - - {t("scoreViewerZoomOut")} - - - - - {t("scoreViewerZoomIn")} - + +
- - ) => { - if (e.currentTarget.getAttribute("aria-disabled") === "true") { - e.preventDefault(); - return; - } - goToPreviousPage(); - }} - > - - {t("scoreViewerPrevPage")} - + {pageIndicator} - - = pageCount ? "true" : undefined} - onClick={(e: React.MouseEvent) => { - if (e.currentTarget.getAttribute("aria-disabled") === "true") { - e.preventDefault(); - return; - } - goToNextPage(); - }} - > - - {t("scoreViewerNextPage")} - +
From 1db8197ba1f8104760a60430eab991f635b32686 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 23 Sep 2026 13:03:45 +0900 Subject: [PATCH 08/14] repair(ui): restore ScoreViewer preservation contract after regression --- .../src/features/score/ScoreViewer.test.tsx | 16 +++- .../src/features/score/ScoreViewer.tsx | 95 +++++++++++-------- 2 files changed, 68 insertions(+), 43 deletions(-) diff --git a/apps/desktop/src/features/score/ScoreViewer.test.tsx b/apps/desktop/src/features/score/ScoreViewer.test.tsx index 3ac2dd605..429f11871 100644 --- a/apps/desktop/src/features/score/ScoreViewer.test.tsx +++ b/apps/desktop/src/features/score/ScoreViewer.test.tsx @@ -120,8 +120,8 @@ describe("ScoreViewer", () => { expect(page.render).toHaveBeenCalled(); }); expect(page.getViewport).toHaveBeenCalledWith({ scale: 1 }); - expect(screen.getByRole("button", { name: "Previous page" })).toBeDisabled(); - expect(screen.getByRole("button", { name: "Next page" })).toBeEnabled(); + expect(screen.getByRole("button", { name: "Previous page" })).toHaveAttribute("aria-disabled", "true"); + expect(screen.getByRole("button", { name: "Next page" })).not.toHaveAttribute("aria-disabled"); }); it("shows the file name when provided", async () => { @@ -174,14 +174,22 @@ describe("ScoreViewer", () => { expect(await screen.findByText("Page 1 of 3")).toBeInTheDocument(); const previousButton = screen.getByRole("button", { name: "Previous page" }); const nextButton = screen.getByRole("button", { name: "Next page" }); - expect(previousButton).toBeDisabled(); + expect(previousButton).toHaveAttribute("aria-disabled", "true"); + + // Test clicking previous when disabled + fireEvent.click(previousButton); + expect(screen.getByText("Page 1 of 3")).toBeInTheDocument(); fireEvent.click(nextButton); expect(screen.getByText("Page 2 of 3")).toBeInTheDocument(); fireEvent.click(nextButton); expect(screen.getByText("Page 3 of 3")).toBeInTheDocument(); - expect(nextButton).toBeDisabled(); + expect(nextButton).toHaveAttribute("aria-disabled", "true"); + + // Test clicking next when disabled + fireEvent.click(nextButton); + expect(screen.getByText("Page 3 of 3")).toBeInTheDocument(); await waitFor(() => { expect(doc.getPage).toHaveBeenCalledWith(3); diff --git a/apps/desktop/src/features/score/ScoreViewer.tsx b/apps/desktop/src/features/score/ScoreViewer.tsx index 82692469e..f18e7ec99 100644 --- a/apps/desktop/src/features/score/ScoreViewer.tsx +++ b/apps/desktop/src/features/score/ScoreViewer.tsx @@ -12,8 +12,9 @@ import { ZoomOut, } from "lucide-react"; import { createTranslator, detectPreferredLocale } from "../../i18n"; -import { Button } from "@/components/ui/button"; +import { Button, buttonVariants } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; +import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { loadScorePdf } from "./pdfjs"; /** Viewer lifecycle states following the clearfolio LOADING/FAILED/READY contract. */ @@ -253,24 +254,26 @@ export function ScoreViewer({ data, fileName, onStatusChange }: ScoreViewerProps )}
- - + + + + {t("scoreViewerZoomOut")} + + + + + {t("scoreViewerZoomIn")} +
- + + ) => { + if (e.currentTarget.getAttribute("aria-disabled") === "true") { + e.preventDefault(); + return; + } + goToPreviousPage(); + }} + > + + {t("scoreViewerPrevPage")} + {pageIndicator} - + + = pageCount ? "true" : undefined} + onClick={(e: React.MouseEvent) => { + if (e.currentTarget.getAttribute("aria-disabled") === "true") { + e.preventDefault(); + return; + } + goToNextPage(); + }} + > + + {t("scoreViewerNextPage")} +
From 4d1ad7d64a88013df3a6291143700a7d5191ebfb Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Wed, 23 Sep 2026 09:55:35 +0000 Subject: [PATCH 09/14] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20=EC=95=85?= =?UTF-8?q?=EB=B3=B4=20=EB=B7=B0=EC=96=B4=20=EC=95=84=EC=9D=B4=EC=BD=98=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=EC=97=90=20=ED=88=B4=ED=8C=81=20=EB=B0=8F=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=EC=84=B1=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/features/score/ScoreViewer.test.tsx | 16 +--- .../src/features/score/ScoreViewer.tsx | 95 ++++++++----------- 2 files changed, 43 insertions(+), 68 deletions(-) diff --git a/apps/desktop/src/features/score/ScoreViewer.test.tsx b/apps/desktop/src/features/score/ScoreViewer.test.tsx index 429f11871..3ac2dd605 100644 --- a/apps/desktop/src/features/score/ScoreViewer.test.tsx +++ b/apps/desktop/src/features/score/ScoreViewer.test.tsx @@ -120,8 +120,8 @@ describe("ScoreViewer", () => { expect(page.render).toHaveBeenCalled(); }); expect(page.getViewport).toHaveBeenCalledWith({ scale: 1 }); - expect(screen.getByRole("button", { name: "Previous page" })).toHaveAttribute("aria-disabled", "true"); - expect(screen.getByRole("button", { name: "Next page" })).not.toHaveAttribute("aria-disabled"); + expect(screen.getByRole("button", { name: "Previous page" })).toBeDisabled(); + expect(screen.getByRole("button", { name: "Next page" })).toBeEnabled(); }); it("shows the file name when provided", async () => { @@ -174,22 +174,14 @@ describe("ScoreViewer", () => { expect(await screen.findByText("Page 1 of 3")).toBeInTheDocument(); const previousButton = screen.getByRole("button", { name: "Previous page" }); const nextButton = screen.getByRole("button", { name: "Next page" }); - expect(previousButton).toHaveAttribute("aria-disabled", "true"); - - // Test clicking previous when disabled - fireEvent.click(previousButton); - expect(screen.getByText("Page 1 of 3")).toBeInTheDocument(); + expect(previousButton).toBeDisabled(); fireEvent.click(nextButton); expect(screen.getByText("Page 2 of 3")).toBeInTheDocument(); fireEvent.click(nextButton); expect(screen.getByText("Page 3 of 3")).toBeInTheDocument(); - expect(nextButton).toHaveAttribute("aria-disabled", "true"); - - // Test clicking next when disabled - fireEvent.click(nextButton); - expect(screen.getByText("Page 3 of 3")).toBeInTheDocument(); + expect(nextButton).toBeDisabled(); await waitFor(() => { expect(doc.getPage).toHaveBeenCalledWith(3); diff --git a/apps/desktop/src/features/score/ScoreViewer.tsx b/apps/desktop/src/features/score/ScoreViewer.tsx index f18e7ec99..82692469e 100644 --- a/apps/desktop/src/features/score/ScoreViewer.tsx +++ b/apps/desktop/src/features/score/ScoreViewer.tsx @@ -12,9 +12,8 @@ import { ZoomOut, } from "lucide-react"; import { createTranslator, detectPreferredLocale } from "../../i18n"; -import { Button, buttonVariants } from "@/components/ui/button"; +import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; -import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { loadScorePdf } from "./pdfjs"; /** Viewer lifecycle states following the clearfolio LOADING/FAILED/READY contract. */ @@ -254,26 +253,24 @@ export function ScoreViewer({ data, fileName, onStatusChange }: ScoreViewerProps )}
- - - - {t("scoreViewerZoomOut")} - - - - - {t("scoreViewerZoomIn")} - + +
- - ) => { - if (e.currentTarget.getAttribute("aria-disabled") === "true") { - e.preventDefault(); - return; - } - goToPreviousPage(); - }} - > - - {t("scoreViewerPrevPage")} - + {pageIndicator} - - = pageCount ? "true" : undefined} - onClick={(e: React.MouseEvent) => { - if (e.currentTarget.getAttribute("aria-disabled") === "true") { - e.preventDefault(); - return; - } - goToNextPage(); - }} - > - - {t("scoreViewerNextPage")} - +
From 6d86c7de511241c45b6d1bc7c4dd492ab074eacb Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Thu, 24 Sep 2026 00:28:58 +0000 Subject: [PATCH 10/14] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20=EC=95=85?= =?UTF-8?q?=EB=B3=B4=20=EB=B7=B0=EC=96=B4=20=EC=95=84=EC=9D=B4=EC=BD=98=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=EC=97=90=20=ED=88=B4=ED=8C=81=20=EB=B0=8F=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=EC=84=B1=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 88756b5806047d2004f4df1567e514c745b2613e Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Thu, 24 Sep 2026 03:12:35 +0000 Subject: [PATCH 11/14] Acknowledging that this work is now obsolete and stopping work on this task From 040425a01cd5c68aa9597d81a52d634ca5f479be Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Thu, 24 Sep 2026 06:09:42 +0000 Subject: [PATCH 12/14] Acknowledging that this work is now obsolete and stopping work on this task From e9ed0d39db53199e6680fb90db4a0b9763d2b190 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Thu, 24 Sep 2026 07:10:41 +0000 Subject: [PATCH 13/14] Acknowledging that this work is now obsolete and stopping work on this task From 96b753875e1be327a95aa031c7b5d27bf94bbdda Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Thu, 24 Sep 2026 18:21:36 +0000 Subject: [PATCH 14/14] Acknowledging that this work is now obsolete and stopping work on this task