Shop tabs overflow: Replace horizontal tabs with custom dropdown select #7

Closed
opened 2026-03-01 13:30:40 +01:00 by jperera · 0 comments
Owner

Problem

The current shop navigation uses horizontal tabs that are displayed in a flexbox row where each tab takes equal space (flex: 1). As the number of shops grows, the tabs become increasingly cramped and difficult to use.

Current state:

  • 5 shops: Mercadona, Carrefour, Aldi, FamilyCash, Others
  • Container max-width: 500px
  • Each tab shares equal space, getting smaller with each new shop

Issues with current design:

  1. Scalability - Adding more shops makes tabs unreadable
  2. Accessibility - Small tap targets on mobile devices
  3. Text truncation - Longer shop names get cut off
  4. Poor UX - Hard to read and click when many shops exist

Current Implementation

<div class="tabs">
  <button class="tab" data-store="mercadona">Mercadona<span class="badge"></span></button>
  <button class="tab" data-store="carrefour">Carrefour<span class="badge"></span></button>
  <button class="tab" data-store="aldi">Aldi<span class="badge"></span></button>
  <button class="tab" data-store="familycash">FamilyCash<span class="badge"></span></button>
  <button class="tab" data-store="others">Others<span class="badge"></span></button>
</div>
.tabs {
  display: flex;
  background: var(--color-gray-100);
  border-bottom: 1px solid var(--color-gray-200);
}

.tab {
  flex: 1;  /* This causes equal sharing of space */
  padding: 1rem;
  /* ... */
}

Proposed Solution: Custom Dropdown Select

Replace the horizontal tabs with a custom dropdown menu that:

Design

  • Shows the currently selected shop prominently at the top
  • Expands to show all available shops when clicked
  • Displays item count badges next to each shop name
  • Matches the existing visual design (gradient, colors, shadows)

Features

  1. Header button - Shows current shop with a dropdown arrow icon
  2. Dropdown panel - List of all shops with hover states
  3. Badge indicators - Show item counts (preserved from current design)
  4. Keyboard navigation - Arrow keys, Enter, Escape support
  5. Click-outside to close - Standard dropdown behavior
  6. Mobile-friendly - Large touch targets

Technical Approach

  • Pure CSS + vanilla TypeScript (no additional dependencies)
  • Maintain existing currentStore state and localStorage persistence
  • Preserve WebSocket integration for real-time badge updates
  • Add smooth animations for open/close transitions

Example Mockup

┌─────────────────────────────────────┐
│  🛒 Mercadona                 ▼ 3   │  ← Header button (current shop + badge)
├─────────────────────────────────────┤
│  🛒 Mercadona                    3  │  ← Dropdown expanded
│  🛒 Carrefour                    5  │
│  🛒 Aldi                         2  │
│  🛒 FamilyCash                   1  │
│  🛒 Others                       0  │
└─────────────────────────────────────┘

Alternative Solutions Considered

  1. Scrollable tabs - Horizontal scroll with arrows

    • Pros: Keeps tab-like navigation
    • Cons: Hidden shops not immediately visible, extra UI complexity
  2. Native <select> element

    • Pros: Native accessibility, minimal code
    • Cons: Limited styling options, inconsistent with app design
  3. Collapsible sidebar

    • Pros: More space for shop details
    • Cons: Major layout change, may be overkill

Acceptance Criteria

  • Custom dropdown replaces horizontal tabs
  • Current shop clearly displayed in collapsed state
  • All shops visible when dropdown is open
  • Item count badges work correctly
  • Keyboard accessible (Tab, Arrow keys, Enter, Escape)
  • Mobile-friendly touch targets
  • Smooth animations for open/close
  • localStorage persistence continues to work
  • Existing WebSocket functionality preserved
## Problem The current shop navigation uses horizontal tabs that are displayed in a flexbox row where each tab takes equal space (`flex: 1`). As the number of shops grows, the tabs become increasingly cramped and difficult to use. **Current state:** - 5 shops: Mercadona, Carrefour, Aldi, FamilyCash, Others - Container max-width: 500px - Each tab shares equal space, getting smaller with each new shop **Issues with current design:** 1. **Scalability** - Adding more shops makes tabs unreadable 2. **Accessibility** - Small tap targets on mobile devices 3. **Text truncation** - Longer shop names get cut off 4. **Poor UX** - Hard to read and click when many shops exist ## Current Implementation ```html <div class="tabs"> <button class="tab" data-store="mercadona">Mercadona<span class="badge"></span></button> <button class="tab" data-store="carrefour">Carrefour<span class="badge"></span></button> <button class="tab" data-store="aldi">Aldi<span class="badge"></span></button> <button class="tab" data-store="familycash">FamilyCash<span class="badge"></span></button> <button class="tab" data-store="others">Others<span class="badge"></span></button> </div> ``` ```css .tabs { display: flex; background: var(--color-gray-100); border-bottom: 1px solid var(--color-gray-200); } .tab { flex: 1; /* This causes equal sharing of space */ padding: 1rem; /* ... */ } ``` ## Proposed Solution: Custom Dropdown Select Replace the horizontal tabs with a **custom dropdown menu** that: ### Design - Shows the currently selected shop prominently at the top - Expands to show all available shops when clicked - Displays item count badges next to each shop name - Matches the existing visual design (gradient, colors, shadows) ### Features 1. **Header button** - Shows current shop with a dropdown arrow icon 2. **Dropdown panel** - List of all shops with hover states 3. **Badge indicators** - Show item counts (preserved from current design) 4. **Keyboard navigation** - Arrow keys, Enter, Escape support 5. **Click-outside to close** - Standard dropdown behavior 6. **Mobile-friendly** - Large touch targets ### Technical Approach - Pure CSS + vanilla TypeScript (no additional dependencies) - Maintain existing `currentStore` state and localStorage persistence - Preserve WebSocket integration for real-time badge updates - Add smooth animations for open/close transitions ### Example Mockup ``` ┌─────────────────────────────────────┐ │ 🛒 Mercadona ▼ 3 │ ← Header button (current shop + badge) ├─────────────────────────────────────┤ │ 🛒 Mercadona 3 │ ← Dropdown expanded │ 🛒 Carrefour 5 │ │ 🛒 Aldi 2 │ │ 🛒 FamilyCash 1 │ │ 🛒 Others 0 │ └─────────────────────────────────────┘ ``` ## Alternative Solutions Considered 1. **Scrollable tabs** - Horizontal scroll with arrows - Pros: Keeps tab-like navigation - Cons: Hidden shops not immediately visible, extra UI complexity 2. **Native `<select>` element** - Pros: Native accessibility, minimal code - Cons: Limited styling options, inconsistent with app design 3. **Collapsible sidebar** - Pros: More space for shop details - Cons: Major layout change, may be overkill ## Acceptance Criteria - [ ] Custom dropdown replaces horizontal tabs - [ ] Current shop clearly displayed in collapsed state - [ ] All shops visible when dropdown is open - [ ] Item count badges work correctly - [ ] Keyboard accessible (Tab, Arrow keys, Enter, Escape) - [ ] Mobile-friendly touch targets - [ ] Smooth animations for open/close - [ ] localStorage persistence continues to work - [ ] Existing WebSocket functionality preserved
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
jperera/shopping#7
No description provided.