Files
rosterchirp/summary.md

6.5 KiB

Mobile UI Fixes Summary

Date: March 29, 2026
Version: 0.12.45
Focus: Android Chrome mobile browser issues


🎯 Objective

Fix mobile UI issues in RosterChirp application on Android Chrome browser:

  1. Chrome autocomplete bar covering input fields
  2. Calendar popup appearing when selecting end time
  3. Time dropdowns being hidden by keyboard
  4. Inconsistent date/time row behavior

📁 Files Modified

Frontend Components

1. frontend/src/components/SchedulePage.jsx

Changes Made:

  • TimeInput component: Added inputMode="text" and enterKeyHint="done" to prevent calendar popup
  • Form wrapper: Changed from autoComplete="new-password" to autoComplete="off" for standard behavior
  • Dropdown positioning: Increased z-index from 300 to 9999 to prevent calendar interference
  • Input attributes: Added explicit type="text" and inputMode="text" for strong calendar prevention

Lines Modified: 187-222

2. frontend/src/components/MobileEventForm.jsx

Changes Made:

  • TimeInputMobile component: Complete rewrite with intelligent positioning
  • Visual Viewport API: Added keyboard detection and dynamic positioning
  • Smart dropdown logic: Calculates available space above/below input
  • Input attributes: Added inputMode="text" and enterKeyHint="done"
  • Z-index fix: Increased to 9999 to prevent calendar interference
  • End date/time row structure: Fixed to match start date/time row

Lines Modified: 72-181, 554-568

3. frontend/src/components/UserManagerModal.jsx

Changes Made:

  • Form wrapper: Added autoComplete="off" to suppress Chrome autocomplete
  • Input consistency: Ensured all inputs use standard autocomplete suppression

Lines Modified: 293-295

4. frontend/src/pages/GroupManagerPage.jsx

Changes Made:

  • Form wrapper: Added autoComplete="off" for consistent behavior
  • Input attributes: Standardized autocomplete suppression

Lines Modified: 744-746

5. frontend/src/pages/UserManagerPage.jsx

Changes Made:

  • Form wrapper: Added autoComplete="off" for mobile compatibility
  • Input consistency: Updated all input fields

Lines Modified: 624-626

6. frontend/src/index.css

Changes Made:

  • Cleaned up aggressive CSS: Removed -webkit-autofill overrides that could affect iOS/desktop
  • Reverted to standard: Cross-browser compatible approach

Lines Modified: 35-62 (removed aggressive autocomplete CSS)


🔧 Technical Solutions Implemented

1. Chrome Autocomplete Suppression

// Standard approach (safe for all browsers)
<input autoComplete="off" />
<form autoComplete="off">

2. Calendar Popup Prevention

// Strong signals to prevent date picker
<input 
  type="text"
  inputMode="text"
  enterKeyHint="done"
  autoComplete="off"
/>

3. Smart Dropdown Positioning

// Visual Viewport API for keyboard detection
const handleViewportChange = () => {
  if (window.visualViewport) {
    const offset = window.innerHeight - window.visualViewport.height;
    setKeyboardOffset(offset > 0 ? offset : 0);
  }
};

// Intelligent positioning based on available space
const spaceAbove = rect.top;
const spaceBelow = window.innerHeight - rect.bottom - keyboardOffset;

if (spaceBelow >= dropdownHeight) {
  setDropdownPosition({ top: '100%', bottom: 'auto' });
} else {
  setDropdownPosition({ top: 'auto', bottom: '100%' });
}

4. Z-Index Hierarchy Fix

// Time dropdowns above all other UI elements
zIndex: 9999

5. Consistent Date/Time Row Structure

// Before (problematic)
<div onClick={()=>setShowEndDate(true)} style={{cursor:'pointer'}}>
  <span>{date}</span>
  <TimeInputMobile />
</div>

// After (fixed)
<div>
  <span onClick={()=>setShowEndDate(true)} style={{cursor:'pointer'}}>{date}</span>
  <TimeInputMobile />
</div>

🐛 Issues Resolved

Chrome Autocomplete Bar

  • Status: Intended Chrome behavior (not a bug)
  • Solution: Standard autoComplete="off" implementation
  • Result: Consistent with Google Calendar's own behavior

Calendar Popup on End Time

  • Root Cause: Z-index conflict and row structure issues
  • Solution: Increased z-index + separate clickable areas
  • Result: Calendar only triggers on date click, not time click

Keyboard Covering Dropdowns

  • Root Cause: Fixed positioning without keyboard awareness
  • Solution: Visual Viewport API + intelligent positioning
  • Result: Dropdowns appear above keyboard or reposition automatically

Inconsistent Date/Time Rows

  • Root Cause: Different HTML structure between start/end rows
  • Solution: Made both rows structurally identical
  • Result: Consistent behavior for both date and time interactions

📱 Cross-Browser Compatibility

iOS Safari

  • Respects standard autoComplete="off"
  • No aggressive CSS overrides affecting behavior
  • Smart positioning works with Visual Viewport API

Desktop Browsers

  • Standard autocomplete behavior
  • No interference from mobile-specific fixes
  • Consistent time dropdown functionality

Android Chrome

  • Standard autocomplete suppression (as intended by Chrome)
  • Proper time dropdown positioning
  • No calendar interference with time selection

🎯 Key Learnings

  1. Chrome Android autocomplete is intended behavior, not a bug
  2. Even Google Calendar can't suppress it - confirmed by user testing
  3. Standard HTML attributes are the safest approach for cross-browser compatibility
  4. Visual Viewport API provides reliable keyboard detection
  5. Z-index hierarchy is critical for preventing UI element conflicts
  6. Consistent HTML structure prevents interaction conflicts

📦 Version History

  • 0.12.38: Initial autocomplete attempts
  • 0.12.39: Aggressive CSS and JavaScript overrides
  • 0.12.40: Cleaned up to standard approach
  • 0.12.41: Fixed calendar z-index issues
  • 0.12.42: Added smart dropdown positioning
  • 0.12.43: Fixed date/time row structure
  • 0.12.44: Refined positioning logic
  • 0.12.45: Final stable implementation

🚀 Ready for Deployment

All changes are cross-browser compatible and follow web standards. The implementation now:

  • Works consistently across iOS Safari, Android Chrome, and desktop browsers
  • Provides intelligent dropdown positioning
  • Maintains clean, maintainable code
  • Follows React best practices