From c59c6c3baa602e609115a07334d14dc942c7532f Mon Sep 17 00:00:00 2001 From: onespaceman Date: Wed, 21 Jan 2026 16:03:27 -0500 Subject: [PATCH] QOL changes to client (#165) --- client/app/app.css | 31 +++++++------------- client/app/components/modals/DeleteModal.tsx | 2 +- client/app/components/modals/MergeModal.tsx | 13 ++++---- client/app/components/modals/Modal.tsx | 30 +++++++++++++++++-- 4 files changed, 46 insertions(+), 30 deletions(-) diff --git a/client/app/app.css b/client/app/app.css index 217e955..eb5e7f6 100644 --- a/client/app/app.css +++ b/client/app/app.css @@ -130,30 +130,21 @@ h4 { text-decoration: underline; } -input[type="text"] { - border: 1px solid var(--color-bg); -} -input[type="text"]:focus { - outline: none; - border: 1px solid var(--color-fg-tertiary); -} +input[type="text"], +input[type="password"], textarea { border: 1px solid var(--color-bg); } +input[type="checkbox"] { + height: fit-content; +} +input:focus, +button:focus, +a:focus, +select:focus, textarea:focus { - outline: none; - border: 1px solid var(--color-fg-tertiary); -} -input[type="password"] { - border: 1px solid var(--color-bg); -} -input[type="password"]:focus { - outline: none; - border: 1px solid var(--color-fg-tertiary); -} -input[type="checkbox"]:focus { - outline: none; - border: 1px solid var(--color-fg-tertiary); + border-color: transparent; + outline: 2px solid var(--color-fg-tertiary); } button:hover { diff --git a/client/app/components/modals/DeleteModal.tsx b/client/app/components/modals/DeleteModal.tsx index 06bfdaf..227951e 100644 --- a/client/app/components/modals/DeleteModal.tsx +++ b/client/app/components/modals/DeleteModal.tsx @@ -20,7 +20,7 @@ export default function DeleteModal({ open, setOpen, title, id, type }: Props) { setLoading(true); deleteItem(type.toLowerCase(), id).then((r) => { if (r.ok) { - navigate("/"); + navigate(-1); } else { console.log(r); } diff --git a/client/app/components/modals/MergeModal.tsx b/client/app/components/modals/MergeModal.tsx index 61e2618..c78681d 100644 --- a/client/app/components/modals/MergeModal.tsx +++ b/client/app/components/modals/MergeModal.tsx @@ -19,7 +19,7 @@ interface Props { } export default function MergeModal(props: Props) { - const [query, setQuery] = useState(""); + const [query, setQuery] = useState(props.currentTitle); const [data, setData] = useState(); const [debouncedQuery, setDebouncedQuery] = useState(query); const [mergeTarget, setMergeTarget] = useState<{ title: string; id: number }>( @@ -101,11 +101,12 @@ export default function MergeModal(props: Props) { { setQuery(e.target.value); e.target.select()}} onChange={(e) => setQuery(e.target.value)} /> @@ -128,7 +129,7 @@ export default function MergeModal(props: Props) { > Merge Items -
+
{(props.type.toLowerCase() === "album" || props.type.toLowerCase() === "artist") && ( -
+
{ const handleKeyDown = (e: KeyboardEvent) => { - if (e.key === 'Escape') onClose(); + // Close on Escape key + if (e.key === 'Escape') { + onClose() + // Trap tab navigation to the modal + } else if (e.key === 'Tab') { + if (modalRef.current) { + const focusableEls = modalRef.current.querySelectorAll( + 'button:not(:disabled), [href], input:not(:disabled), select:not(:disabled), textarea:not(:disabled), [tabindex]:not([tabindex="-1"])' + ); + const firstEl = focusableEls[0]; + const lastEl = focusableEls[focusableEls.length - 1]; + const activeEl = document.activeElement + + if (e.shiftKey && activeEl === firstEl) { + e.preventDefault(); + lastEl.focus(); + } else if (!e.shiftKey && activeEl === lastEl) { + e.preventDefault(); + firstEl.focus(); + } else if (!Array.from(focusableEls).find(node => node.isEqualNode(activeEl))) { + e.preventDefault(); + firstEl.focus(); + } + } + }; }; if (isOpen) document.addEventListener('keydown', handleKeyDown); return () => document.removeEventListener('keydown', handleKeyDown); @@ -70,13 +94,13 @@ export function Modal({ }`} style={{ maxWidth: maxW ?? 600, height: h ?? '' }} > + {children} - {children}
, document.body