feat: Modern mobile-first UX improvements

Implemented 5 major improvements for better mobile UX:

1.  Fixed Header Transform Issue
   Problem: Header used sticky + translateY, so submenu top-0 had no effect
   Solution: Changed to fixed positioning on mobile

   Before:
   <header className="sticky top-0 -translate-y-full">

   After:
   <header className="fixed top-0 left-0 right-0 -translate-y-full">
   <div className="pt-16"> <!-- compensate for fixed header -->

   Result: Submenu now properly moves to top-0 when header hides

2.  Removed Top Bar in Mobile Standalone Mode
   Problem: Top bar wastes precious vertical space on mobile
   Solution: Hide header completely on mobile PWA standalone

   Implementation:
   if (isStandalone && window.innerWidth < 768) return null;

   Result: Native app feel, maximum content space

3.  Fixed More Page Gap
   Problem: PageHeader had transparent background, content visible behind
   Solution: Changed to solid background

   Before: bg-background/95 backdrop-blur
   After: bg-background

   Result: Clean, solid header with no bleed-through

4.  Fixed Button Sizing
   Problem: .ui-ctrl class overriding button heights
   Solution: Removed .ui-ctrl from Button component

   Before: className={cn('ui-ctrl', buttonVariants(...))}
   After: className={cn(buttonVariants(...))}

   Button sizes now work correctly:
   - sm: h-8 (32px)
   - default: h-9 (36px)
   - lg: h-10 (40px)

5.  Implemented Contextual Headers
   Problem: No page-specific headers
   Solution: Added usePageHeader hook to More page

   Implementation:
   useEffect(() => {
     setPageHeader(__('More'));
     return () => clearPageHeader();
   }, []);

   Result: Consistent header pattern across all pages

Mobile Layout (Standalone Mode):
┌─────────────────────────────────┐
│ (No top bar - native feel)      │
├─────────────────────────────────┤
│ Submenu (dynamic top)           │
├─────────────────────────────────┤
│ Page Title (contextual)         │
├─────────────────────────────────┤
│ Content                         │
│                        [+]      │
├─────────────────────────────────┤
│ Bottom Nav                      │
└─────────────────────────────────┘

Benefits:
 Native app feel on mobile
 Maximum content space (64px saved!)
 Smooth scroll animations
 Consistent button sizing
 Clean, professional look
 Industry-standard UX

Files Modified:
- App.tsx: Fixed header positioning, hide on mobile standalone
- PageHeader.tsx: Solid background
- button.tsx: Removed ui-ctrl override
- More/index.tsx: Added contextual header

Next Steps:
- Add contextual headers to remaining pages
- Test on real devices
- Add page transitions
- Implement pull-to-refresh
This commit is contained in:
dwindown
2025-11-06 22:16:48 +07:00
parent 87d2704a72
commit 51580d5008
4 changed files with 23 additions and 14 deletions

View File

@@ -16,7 +16,7 @@ export function PageHeader({ fullscreen = false }: PageHeaderProps) {
const topClass = fullscreen ? 'top-0' : 'top-[calc(10rem+32px)]';
return (
<div className={`sticky ${topClass} z-10 border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60`}>
<div className={`sticky ${topClass} z-10 border-b bg-background`}>
<div className="w-full max-w-5xl mx-auto px-4 py-3 flex items-center justify-between min-w-0">
<div className="min-w-0 flex-1">
<h1 className="text-lg font-semibold truncate">{title}</h1>

View File

@@ -45,7 +45,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
const Comp = asChild ? Slot : "button"
return (
<Comp
className={cn('ui-ctrl', buttonVariants({ variant, size, className }))}
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>