From e6623b2784652e2f646b4a63c4d46f7759c4d6f3 Mon Sep 17 00:00:00 2001 From: "v.lagerev" Date: Sat, 25 Apr 2026 20:18:38 +0300 Subject: [PATCH] fix(auth): stabilize compact auth form scrolling --- src/app/pages/auth/AuthLayout.tsx | 205 ++++++++++++++++-------------- src/app/pages/auth/styles.css.ts | 35 ++--- 2 files changed, 122 insertions(+), 118 deletions(-) diff --git a/src/app/pages/auth/AuthLayout.tsx b/src/app/pages/auth/AuthLayout.tsx index 19671a55..d720522f 100644 --- a/src/app/pages/auth/AuthLayout.tsx +++ b/src/app/pages/auth/AuthLayout.tsx @@ -77,6 +77,17 @@ function ServerEditDialog({ inputRef.current?.select(); }, []); + useEffect(() => { + const handleKeyDown = (evt: KeyboardEvent) => { + if (evt.key === 'Escape' && !evt.defaultPrevented && !evt.isComposing) { + onCancel(); + } + }; + + document.addEventListener('keydown', handleKeyDown); + return () => document.removeEventListener('keydown', handleKeyDown); + }, [onCancel]); + const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); const trimmed = value.trim(); @@ -84,12 +95,7 @@ function ServerEditDialog({ }; return ( -
{ if (e.key === 'Escape') onCancel(); }} - > +
diff --git a/src/app/pages/auth/styles.css.ts b/src/app/pages/auth/styles.css.ts index 01039433..3b16ed95 100644 --- a/src/app/pages/auth/styles.css.ts +++ b/src/app/pages/auth/styles.css.ts @@ -108,14 +108,25 @@ export const AuthCard = style({ }); export const AuthCardContent = style({ - display: 'flex', - flexDirection: 'column', borderRadius: 'inherit', backgroundColor: 'rgba(18, 19, 22, 0.55)', backdropFilter: 'blur(22px) saturate(150%)', WebkitBackdropFilter: 'blur(22px) saturate(150%)', border: '1px solid rgba(255, 255, 255, 0.08)', width: `min(${toRem(492)}, calc(100vw - 2rem))`, + boxSizing: 'border-box', + maxHeight: 'var(--vojo-modal-max-h)', + overflowY: 'hidden', +}); + +export const AuthCardContentScrollable = style({ + overflowY: 'auto', + overscrollBehavior: 'contain', +}); + +export const AuthCardBody = style({ + display: 'flex', + flexDirection: 'column', padding: `${toRem(32)} ${toRem(40)}`, boxSizing: 'border-box', gap: toRem(20), @@ -128,12 +139,6 @@ export const AuthCardContent = style({ }, }); -export const AuthCardContentConstrained = style({ - maxHeight: 'var(--vojo-modal-max-h)', - overflowY: 'auto', - overscrollBehavior: 'contain', -}); - /* ── Server info row ── */ export const ServerRow = style({ display: 'grid', @@ -285,20 +290,6 @@ globalStyle(`${AuthCardContent} input::placeholder`, { color: 'rgba(232, 228, 223, 0.35)', }); -/* - * Floor for input boxes when the modal is height-constrained (small screen - * or on-screen keyboard). Natural input height is 3rem; floor at 2rem so - * the keyboard can still squeeze the form to ~66% before hitting the stop. - * Past the floor, flex can't compress further — the form overflows the - * AuthLayout (overflow: hidden) and the bottom is covered by the keyboard. - * - * `:has(> input)` targets the folds Input's outer wrapper (the box that - * flex-shrinks) rather than the native . Excludes checkboxes. - */ -globalStyle(`${AuthCardContent} div:has(> input:not([type="checkbox"]))`, { - minHeight: toRem(48), -}); - /* * Chromium's UA stylesheet paints a saved-credentials overlay on * :-webkit-autofill inputs, forcing a light background and dark text. Without