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

164 lines
6.3 KiB
Markdown

# Mobile Text Selection Prevention Review
**Date**: 2026-01-17
**Purpose**: Review and apply text selection prevention patterns for mobile touch/drag interactions
## Pattern Applied
```css
/* 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