- 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>
6.3 KiB
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: nonefor callout menu prevention - Uses
touch-action: manipulationfor proper touch optimization
✅ Updated Components
1. UI/ToggleSwitch.vue
- Changes:
- Added
select-noneclass to root container - Added
<style scoped>block with text selection prevention for button and all children - Added
touch-action: manipulationto button
- Added
- Reason: Toggle switches are frequently tapped on mobile and users were selecting text accidentally
2. UI/ButtonGroup.vue
- Changes:
- Added
select-noneclass to root container - Added
<style scoped>block with text selection prevention for all buttons and children - Added
touch-action: manipulationto buttons
- Added
- Reason: Button groups used for decisions (infield depth, outfield depth) are touch-intensive
3. UI/ActionButton.vue
- Changes:
- Added
select-none touch-manipulationTailwind classes to button element - Added
<style scoped>block with text selection prevention for button and all children
- Added
- Reason: Primary action buttons (Submit, Roll Dice, etc.) are core mobile interactions
4. Schedule/GameCard.vue
- Changes:
- Added
select-none touch-manipulationclasses to "Play This Game" button
- Added
- Reason: Game card buttons are frequently tapped to start games
5. Substitutions/SubstitutionPanel.vue
- Changes:
- Added
select-noneclass to tab navigation container - Added
select-noneclass to player selection grid - Added
touch-manipulationclass to player buttons - Updated CSS for
.tab-buttonwith user-select and touch-action properties - Updated CSS for
.player-buttonwith user-select properties
- Added
- Reason: Tab navigation and player selection involve frequent tapping on mobile
6. Decisions/OffensiveApproach.vue
- Changes:
- Added
select-noneclass to action selection grid container - Added
touch-manipulationclass to action buttons
- Added
- 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:
- iPhone/iPad (iOS Safari) - Test
-webkit-touch-calloutprevention - Android (Chrome Mobile) - Test general touch behavior
- 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