diff options
| author | Claude <noreply@anthropic.com> | 2026-05-01 07:13:33 +0000 |
|---|---|---|
| committer | Claude <noreply@anthropic.com> | 2026-05-01 07:13:33 +0000 |
| commit | 03ef32ad7840d711141ae8df0d33a7a7004ef6dd (patch) | |
| tree | c93de7ebba536e3c519486c78ced196d406ac913 | |
| parent | e3576b4b3cb0428a6cc738289a66b7951a133320 (diff) | |
| download | kioku-03ef32ad7840d711141ae8df0d33a7a7004ef6dd.tar.gz kioku-03ef32ad7840d711141ae8df0d33a7a7004ef6dd.tar.zst kioku-03ef32ad7840d711141ae8df0d33a7a7004ef6dd.zip | |
fix(study): prevent card layout shift from undo button visibility
Move the undo button next to the edit button (absolutely positioned
inside the card) so its conditional appearance no longer pushes the
card down.
https://claude.ai/code/session_01DEGwZf6bmzv4X2XTsK95Wk
| -rw-r--r-- | src/client/pages/StudyPage.tsx | 105 |
1 files changed, 59 insertions, 46 deletions
diff --git a/src/client/pages/StudyPage.tsx b/src/client/pages/StudyPage.tsx index 9127e39..584f543 100644 --- a/src/client/pages/StudyPage.tsx +++ b/src/client/pages/StudyPage.tsx @@ -295,28 +295,6 @@ function StudySession({ )} </div> - {/* Undo Button */} - {pendingReview && !isFlipped && !isSessionComplete && ( - <div className="flex justify-end mb-4"> - <button - type="button" - data-testid="undo-button" - onClick={handleUndo} - className="inline-flex items-center gap-1.5 text-muted hover:text-slate text-sm transition-colors" - > - <FontAwesomeIcon - icon={faRotateLeft} - className="w-3.5 h-3.5" - aria-hidden="true" - /> - Undo - <kbd className="ml-1 px-1.5 py-0.5 bg-ivory rounded text-xs font-mono"> - Z - </kbd> - </button> - </div> - )} - {/* No Cards State */} {hasNoCards && ( <div @@ -425,32 +403,67 @@ function StudySession({ : "bg-ivory/50" }`} > - {/* Edit button */} - {/* biome-ignore lint/a11y/useSemanticElements: Cannot nest <button> inside parent <button>, using span with role="button" instead */} - <span - role="button" - tabIndex={0} - data-testid="edit-card-button" - onClick={(e) => { - e.stopPropagation(); - setEditingNoteId(currentCard.noteId); - }} - onKeyDown={(e) => { - if (e.key === "Enter" || e.key === " ") { + {/* Top-right action buttons */} + <div className="absolute top-3 right-3 flex items-center gap-1"> + {/* Undo button */} + {pendingReview && !isFlipped && ( + /* biome-ignore lint/a11y/useSemanticElements: Cannot nest <button> inside parent <button>, using span with role="button" instead */ + <span + role="button" + tabIndex={0} + data-testid="undo-button" + onClick={(e) => { + e.stopPropagation(); + handleUndo(); + }} + onKeyDown={(e) => { + if (e.key === "Enter" || e.key === " ") { + e.stopPropagation(); + e.preventDefault(); + handleUndo(); + } + }} + className="h-8 px-2 flex items-center gap-1.5 text-muted hover:text-slate text-sm transition-colors rounded-lg hover:bg-ivory" + aria-label="Undo last rating" + > + <FontAwesomeIcon + icon={faRotateLeft} + className="w-3.5 h-3.5" + aria-hidden="true" + /> + Undo + <kbd className="px-1.5 py-0.5 bg-ivory rounded text-xs font-mono"> + Z + </kbd> + </span> + )} + {/* Edit button */} + {/* biome-ignore lint/a11y/useSemanticElements: Cannot nest <button> inside parent <button>, using span with role="button" instead */} + <span + role="button" + tabIndex={0} + data-testid="edit-card-button" + onClick={(e) => { e.stopPropagation(); - e.preventDefault(); setEditingNoteId(currentCard.noteId); - } - }} - className="absolute top-3 right-3 w-8 h-8 flex items-center justify-center text-muted hover:text-slate transition-colors rounded-lg hover:bg-ivory" - aria-label="Edit card" - > - <FontAwesomeIcon - icon={faPen} - className="w-3.5 h-3.5" - aria-hidden="true" - /> - </span> + }} + onKeyDown={(e) => { + if (e.key === "Enter" || e.key === " ") { + e.stopPropagation(); + e.preventDefault(); + setEditingNoteId(currentCard.noteId); + } + }} + className="w-8 h-8 flex items-center justify-center text-muted hover:text-slate transition-colors rounded-lg hover:bg-ivory" + aria-label="Edit card" + > + <FontAwesomeIcon + icon={faPen} + className="w-3.5 h-3.5" + aria-hidden="true" + /> + </span> + </div> {/* Card state badge */} <span data-testid="card-state-badge" |
