feat: improve mobile edit modal swipe gestures and tab navigation (#256)

* feat: improve mobile edit modal swipe gestures and tab navigation

Replace React passive touch handlers with native non-passive
addEventListener via useEffect for reliable horizontal swipe blocking.
Reduce axis-lock threshold from 18-26px to 6px for more responsive
gesture detection. Remove isInteractive() guard so swipe works on
input fields. Add tab strip auto-scroll via scrollIntoView when
active tab changes. Fix vertical scrolling by changing readonly
fieldset from display:block to display:flex.

Closes #252

* fix: guard scrollIntoView for jsdom test compatibility
This commit is contained in:
Daniel Volz
2026-02-21 18:00:02 +01:00
committed by GitHub
parent 0cf1c5353e
commit 94bd8bd6e8
2 changed files with 640 additions and 400 deletions
File diff suppressed because it is too large Load Diff
+74 -9
View File
@@ -192,24 +192,25 @@
/* Mobile Edit Modal */
.mobile-edit-overlay {
align-items: flex-start;
padding-top: 0.75rem;
padding-bottom: 0.75rem;
padding-top: 0.35rem;
padding-bottom: 0.35rem;
}
.edit-modal {
max-width: 95vw;
max-height: none;
height: min(92dvh, 92vh);
padding: 0.75rem;
height: min(96dvh, 96vh);
padding: 0.6rem;
display: flex;
flex-direction: column;
overflow: hidden;
overflow-x: hidden;
}
.edit-modal-header {
display: flex;
align-items: center;
justify-content: space-between;
justify-content: flex-start;
gap: 0.75rem;
margin-bottom: 1rem;
}
@@ -217,25 +218,89 @@
.edit-modal-header h2 {
font-size: 1.25rem;
margin: 0;
text-align: left;
min-width: 0;
}
.mobile-edit-form.form-grid {
display: flex;
flex-direction: column;
gap: 0.75rem;
gap: 0.5rem;
flex: 1;
min-height: 0;
overflow: hidden;
overflow-x: hidden;
}
.mobile-edit-form .modal-footer {
border-top: none;
padding: 0.45rem 0.15rem calc(0.45rem + env(safe-area-inset-bottom, 0px));
gap: 0.6rem;
margin-top: 0;
}
.mobile-edit-form .readonly-fieldset {
display: flex;
flex-direction: column;
border: 0;
margin: 0;
padding: 0;
min-inline-size: 0;
flex: 1;
min-height: 0;
overflow: hidden;
overscroll-behavior: contain;
}
.mobile-edit-form .readonly-fieldset.swiping-horizontal {
overflow-y: hidden;
}
.mobile-edit-form .mobile-tab-viewport {
flex: 1;
min-height: 0;
overflow: hidden;
}
.mobile-edit-form .readonly-fieldset {
.mobile-edit-form .mobile-tab-track {
display: flex;
height: 100%;
will-change: transform;
}
.mobile-edit-form .mobile-tab-track:not(.is-swiping) {
transition: transform 220ms ease;
}
.mobile-edit-form .mobile-tab-track > .form-tab-panel {
display: block;
flex: 1;
min-height: 0;
flex: 0 0 100%;
min-width: 100%;
height: 100%;
overflow-y: auto;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
padding-right: 0.1rem;
overscroll-behavior: contain;
}
.mobile-edit-form .form-tabs {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
scrollbar-width: none;
}
.mobile-edit-form .form-tabs::-webkit-scrollbar {
display: none;
}
.mobile-edit-form .form-tab {
flex: 0 0 auto;
min-width: max-content;
overflow: visible;
text-overflow: clip;
}
.mobile-edit-form .form-tab-panel.active {
display: block;
}