fix: route mobile terminal swipes to the terminal, not the page layout
- Add touch-action: none and overscroll-behavior: none to mobile terminal
page, content, wrapper, container, and xterm viewport so the browser
never treats swipes as page/address-bar scrolling or pull-to-refresh.
- Make .terminal-page.mobile fixed-position to prevent viewport layout
scroll; keep the overlay toolbar as absolute with pointer-events only
on interactive parts.
- Rework the mobile touch handler in terminal.tsx:
* Detect normal vs alternate buffer via term.buffer.active.type instead
of measuring the DOM viewport, which was unreliable in tmux/vim.
* Accumulate swipe distance and emit SGR 1006 mouse-wheel sequences in
steps, so tmux pane scrolling tracks the gesture correctly.
* Prevent default as soon as the swipe is recognized so the page does
not start a competing scroll gesture.
Quality gates: npm run typecheck, npm run lint clean, npm test -- --run 87 passed.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
dir: apps/web/src/styles
|
||||
|
||||
## role
|
||||
Provides the complete visual design system and styling foundation for a web application, including themes, utilities, and component-specific styles.
|
||||
Provides the complete visual design system and styling foundation for the web application, including themes, tokens, utilities, and component-specific styles.
|
||||
## parent
|
||||
index: apps/web/src/.pi-map.index.md
|
||||
map: apps/web/src/.pi-map.md
|
||||
|
||||
@@ -4,14 +4,14 @@ dir: apps/web/src/styles
|
||||
index: apps/web/src/styles/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Provides the complete visual design system and styling foundation for a web application, including themes, utilities, and component-specific styles.
|
||||
Provides the complete visual design system and styling foundation for the web application, including themes, tokens, utilities, and component-specific styles.
|
||||
## files
|
||||
- global.css | Defines global CSS styles for a web application shell layout, navigation, cards, forms, dialogs, settings pages, and responsive design patterns. | dep: CSS custom properties (CSS variables: --border, --panel, --brand, --muted, --ink, --bg, --danger, --success, --warning, --font-size-xs, --font-size-sm, --space-2, --space-3, --space-4, --space-5)
|
||||
- syntax-highlight.css | Stylesheet for a syntax highlighting component with toolbar, line numbers, code display, and Prism.js theme integration | dep: Prism.js
|
||||
- tokens.css | Defines a comprehensive CSS design token system with light/dark themes, spacing scales, breakpoints, and fluid typography for a web application.
|
||||
- utilities.css | Provides a comprehensive responsive CSS utility system with terminal-specific styling, mobile adaptations, and component patterns for a web application. | dep: CSS custom properties (var(--space-*), var(--border), var(--bg), var(--text), var(--brand), var(--muted), var(--success), var(--danger), var(--danger-light)), xterm.js (terminal integration)
|
||||
- utilities.css | Provides responsive CSS utility classes and component-specific styles for a web application including layout systems, terminal styling, session management, and mobile-first adaptations. | dep: CSS custom properties (var(--space-*), var(--border), var(--bg), var(--text), var(--brand), var(--success), var(--danger), var(--muted)), xterm.js (terminal library)
|
||||
## arch
|
||||
Token-based CSS architecture using CSS custom properties for light/dark theming, with layered stylesheets separating tokens, global styles, utilities, and component-specific styling, supporting responsive and fluid design patterns.
|
||||
Token-driven CSS architecture using CSS custom properties for light/dark theming, utility-first responsive classes, and modular separation of concerns across global styles, syntax highlighting, design tokens, and utility helpers.
|
||||
## tags
|
||||
var(, space, global, css, web, application, syntax, defines
|
||||
## symbols
|
||||
|
||||
@@ -551,6 +551,14 @@ a.nav-item,
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
touch-action: none;
|
||||
overscroll-behavior: none;
|
||||
}
|
||||
|
||||
/* Ensure xterm's internal viewport also disables browser gestures on mobile */
|
||||
.terminal-container .xterm-viewport {
|
||||
touch-action: none;
|
||||
overscroll-behavior: none;
|
||||
}
|
||||
|
||||
/* xterm.js manages its own positioning and sizing */
|
||||
@@ -564,6 +572,13 @@ a.nav-item,
|
||||
/* Mobile terminal container - no padding to maximize space */
|
||||
.terminal-wrapper.mobile .terminal-container {
|
||||
padding: 0;
|
||||
touch-action: none;
|
||||
overscroll-behavior: none;
|
||||
}
|
||||
|
||||
.terminal-wrapper.mobile {
|
||||
touch-action: none;
|
||||
overscroll-behavior: none;
|
||||
}
|
||||
|
||||
/* Ensure xterm viewport fills container properly */
|
||||
@@ -855,17 +870,23 @@ a.nav-item,
|
||||
Mobile Terminal Overlay
|
||||
============================================ */
|
||||
|
||||
/* Mobile terminal page — no padding, terminal fills viewport */
|
||||
/* Mobile terminal page — no padding, terminal fills viewport, locked in place */
|
||||
.terminal-page.mobile {
|
||||
padding: 0;
|
||||
gap: 0;
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
position: relative;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
touch-action: none;
|
||||
overscroll-behavior: none;
|
||||
}
|
||||
|
||||
/* Overlay status bar — floats over terminal, never resizes it */
|
||||
/* Overlay status bar — floats over terminal; only its buttons consume pointer events */
|
||||
.mobile-terminal-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -874,11 +895,21 @@ a.nav-item,
|
||||
z-index: 100;
|
||||
background: #2d2d2d;
|
||||
border-bottom: 1px solid #3e3e3e;
|
||||
pointer-events: none;
|
||||
transition:
|
||||
transform 0.3s ease,
|
||||
opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.mobile-terminal-overlay.visible {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.mobile-terminal-overlay > *,
|
||||
.mobile-terminal-overlay-tabs {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.mobile-terminal-overlay.hidden {
|
||||
transform: translateY(-100%);
|
||||
opacity: 0;
|
||||
@@ -978,13 +1009,15 @@ a.nav-item,
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* Terminal content — always fills full viewport on mobile */
|
||||
/* Terminal content — always fills full viewport on mobile, locked against page scroll */
|
||||
.terminal-page-content.mobile-full {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
overflow: hidden;
|
||||
touch-action: none;
|
||||
overscroll-behavior: none;
|
||||
}
|
||||
|
||||
/* Mobile fullscreen */
|
||||
|
||||
Reference in New Issue
Block a user