strat-gameplay-webapp/frontend-sba/.claude/MOBILE_TEXT_SELECTION_REVIEW.md
Cal Corum 52706bed40 CLAUDE: Mobile drag-drop lineup builder and touch-friendly UI improvements
- Add vuedraggable for mobile-friendly lineup building
- Add touch delay and threshold settings for better mobile UX
- Add drag ghost/chosen/dragging visual states
- Add replacement mode visual feedback when dragging over occupied slots
- Add getBench action to useGameActions for substitution panel
- Add BN (bench) to valid positions in LineupPlayerState
- Update lineup service to load full lineup (active + bench)
- Add touch-manipulation CSS to UI components (ActionButton, ButtonGroup, ToggleSwitch)
- Add select-none to prevent text selection during touch interactions
- Add mobile touch patterns documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 22:17:16 -06:00

6.3 KiB

Mobile Text Selection Prevention Review

Date: 2026-01-17 Purpose: Review and apply text selection prevention patterns for mobile touch/drag interactions

Pattern Applied

/* Prevent text selection on all draggable/interactive elements AND their children */
:deep([draggable="true"]),
:deep([draggable="true"] *),
:deep(.sortable-item),
:deep(.sortable-item *),
.interactive-item,
.interactive-item * {
  -webkit-user-select: none !important;
  -moz-user-select: none !important;
  -ms-user-select: none !important;
  user-select: none !important;
  -webkit-touch-callout: none !important; /* Prevent iOS callout menu */
}

/* Touch action on containers only */
:deep([draggable="true"]),
:deep(.sortable-item) {
  touch-action: manipulation; /* Allow pan/zoom but optimize for touch */
}

Tailwind utilities used: select-none and touch-manipulation

Components Reviewed

Already Compliant (No Changes Needed)

LineupBuilder.vue

  • Status: Fully compliant
  • Reason: Already has comprehensive text selection prevention for vuedraggable components
  • Implementation: Uses :deep() selectors with complete iOS support
  • Details:
    • Prevents text selection on all draggable roster items
    • Prevents text selection on lineup slot items
    • Applies to all child elements using wildcard selectors
    • Includes iOS-specific -webkit-touch-callout: none for callout menu prevention
    • Uses touch-action: manipulation for proper touch optimization

Updated Components

1. UI/ToggleSwitch.vue

  • Changes:
    • Added select-none class to root container
    • Added <style scoped> block with text selection prevention for button and all children
    • Added touch-action: manipulation to button
  • Reason: Toggle switches are frequently tapped on mobile and users were selecting text accidentally

2. UI/ButtonGroup.vue

  • Changes:
    • Added select-none class to root container
    • Added <style scoped> block with text selection prevention for all buttons and children
    • Added touch-action: manipulation to buttons
  • Reason: Button groups used for decisions (infield depth, outfield depth) are touch-intensive

3. UI/ActionButton.vue

  • Changes:
    • Added select-none touch-manipulation Tailwind classes to button element
    • Added <style scoped> block with text selection prevention for button and all children
  • Reason: Primary action buttons (Submit, Roll Dice, etc.) are core mobile interactions

4. Schedule/GameCard.vue

  • Changes:
    • Added select-none touch-manipulation classes to "Play This Game" button
  • Reason: Game card buttons are frequently tapped to start games

5. Substitutions/SubstitutionPanel.vue

  • Changes:
    • Added select-none class to tab navigation container
    • Added select-none class to player selection grid
    • Added touch-manipulation class to player buttons
    • Updated CSS for .tab-button with user-select and touch-action properties
    • Updated CSS for .player-button with user-select properties
  • Reason: Tab navigation and player selection involve frequent tapping on mobile

6. Decisions/OffensiveApproach.vue

  • Changes:
    • Added select-none class to action selection grid container
    • Added touch-manipulation class to action buttons
  • Reason: Action selection buttons (Swing Away, Steal, Hit and Run, etc.) are tapped frequently

⚠️ Components NOT Modified (No Touch/Drag Interactions)

Display/Read-Only Components

  • Game/ScoreBoard.vue - Pure display, no interaction
  • Game/GameBoard.vue - Visual diamond display, no dragging
  • Game/CurrentSituation.vue - Player card display
  • Game/PlayByPlay.vue - Text feed, needs text selection for copying plays
  • Game/GameStats.vue - Tabular data display

Decision Input Components (Already Use UI Components)

  • Decisions/DecisionPanel.vue - Container only, uses child components that were updated
  • Decisions/DefensiveSetup.vue - Uses ButtonGroup and ToggleSwitch (already updated)
  • Decisions/StolenBaseInputs.vue - Uses ToggleSwitch (already updated)

Gameplay Components

  • Gameplay/DiceRoller.vue - Uses ActionButton (already updated)
  • Gameplay/ManualOutcomeEntry.vue - Form inputs (needs text selection)
  • Gameplay/PlayResult.vue - Display only

Substitution Components (Use Updated SubstitutionPanel)

  • Substitutions/PinchHitterSelector.vue - Uses parent panel's classes
  • Substitutions/PitchingChangeSelector.vue - Uses parent panel's classes
  • Substitutions/DefensiveReplacementSelector.vue - Uses parent panel's classes

Summary Statistics

  • Total Components Reviewed: 33 Vue files
  • Components Updated: 6
  • Components Already Compliant: 1 (LineupBuilder.vue)
  • Components Skipped (Read-Only/Form Inputs): 26

Testing Recommendations

Test on actual mobile devices:

  1. iPhone/iPad (iOS Safari) - Test -webkit-touch-callout prevention
  2. Android (Chrome Mobile) - Test general touch behavior
  3. Focus Areas:
    • Tap buttons rapidly without text selection
    • Drag roster players in LineupBuilder without selecting text
    • Toggle switches in defensive/offensive decisions
    • Tap player cards in substitution panel
    • Select actions in OffensiveApproach

Pattern Rationale

Why select-none on Interactive Elements?

  • Mobile users often tap and hold slightly too long, triggering text selection
  • Text selection on buttons/cards creates confusing blue highlight overlays
  • Improves perceived responsiveness of the UI

Why touch-manipulation?

  • Optimizes touch events for browser (faster response)
  • Allows pan/zoom gestures but disables double-tap-to-zoom on these elements
  • Better UX for game controls

Why NOT Apply to Everything?

  • Form inputs need text selection for editing values
  • Play-by-play text users may want to copy/paste plays
  • Score displays may be useful to copy scores
  • Only apply where text selection is purely accidental and never intentional

Future Considerations

If new components are added with:

  • Drag-and-drop functionality
  • Touch-based sliders/toggles
  • Clickable cards/buttons
  • Tab navigation

Remember to apply this pattern immediately.


Reviewed By: Claude (Atlas - Principal Engineer) Review Type: Mobile UX Enhancement Compliance: Mobile-First Design Standards