aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorClaude <noreply@anthropic.com>2026-05-01 07:13:33 +0000
committerClaude <noreply@anthropic.com>2026-05-01 07:13:33 +0000
commit03ef32ad7840d711141ae8df0d33a7a7004ef6dd (patch)
treec93de7ebba536e3c519486c78ced196d406ac913
parente3576b4b3cb0428a6cc738289a66b7951a133320 (diff)
downloadkioku-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.tsx105
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"