Skip to content

Add Stage.tsx refactoring foundation: hooks and tool behaviors#38

Open
bengotow wants to merge 4 commits intomasterfrom
claude/review-world-operator-UgHEJ
Open

Add Stage.tsx refactoring foundation: hooks and tool behaviors#38
bengotow wants to merge 4 commits intomasterfrom
claude/review-world-operator-UgHEJ

Conversation

@bengotow
Copy link
Copy Markdown
Collaborator

This commit lays the groundwork for refactoring Stage.tsx into smaller,
testable pieces:

Extracted hooks with full test coverage:

  • useStageCoordinates: coordinate transformations (client -> px -> grid)
  • useStageZoom: scale/fit management with window resize
  • useStageSelection: selection rectangle state management
  • useStagePopover: actor selection popover state

Created tool-behaviors.ts with strategy pattern:

  • Declarative tool behavior definitions instead of scattered switch statements
  • Each tool's click/drag behavior defined in one place
  • Makes adding new tools simpler and more maintainable

Added comprehensive unit tests for pure functions:

  • 52 new tests for coordinate, zoom, and selection logic
  • All 304 project tests pass

This is Phase 1 of the refactoring. Next steps:

  • Extract useStageDragDrop hook
  • Extract useStageMouseHandlers hook
  • Integrate hooks into Stage component

This commit lays the groundwork for refactoring Stage.tsx into smaller,
testable pieces:

Extracted hooks with full test coverage:
- useStageCoordinates: coordinate transformations (client -> px -> grid)
- useStageZoom: scale/fit management with window resize
- useStageSelection: selection rectangle state management
- useStagePopover: actor selection popover state

Created tool-behaviors.ts with strategy pattern:
- Declarative tool behavior definitions instead of scattered switch statements
- Each tool's click/drag behavior defined in one place
- Makes adding new tools simpler and more maintainable

Added comprehensive unit tests for pure functions:
- 52 new tests for coordinate, zoom, and selection logic
- All 304 project tests pass

This is Phase 1 of the refactoring. Next steps:
- Extract useStageDragDrop hook
- Extract useStageMouseHandlers hook
- Integrate hooks into Stage component
Fixes based on code review:

1. tool-behaviors.ts:
   - Added Integration Contract documentation explaining how to
     properly integrate tool behaviors (popover handling, click-as-drag,
     resetAfterUse, special cases)
   - Clarified STAMP tool: onDragPosition is intentionally undefined
     because stamping logic requires complex actor creation helpers
     that live in stage.tsx
   - Documented that STAMP popover only applies when selecting source

2. useStageZoom.ts:
   - Removed refs from dependency array to match original stage.tsx
   - Added comment explaining why refs are excluded (they're stable
     and read at execution time)

3. useStageCoordinates.ts:
   - Clarified closure semantics documentation
   - Explained how stageElRef.current vs scale capture works
Continues the Stage component refactoring by extracting drag/drop logic
into a dedicated hook with pure functions for testability.

Changes:
- Add useStageDragDrop hook with handlers for sprite, appearance, and
  handle drag events
- Extract pure functions for parsing drop data and calculating extents
- Add 60 unit tests for the new hook
- Integrate hook into stage.tsx, removing ~200 lines of inline code
- Remove refs from useCallback dependency arrays (best practice)
- Add documentation for intentional inline tool logic preservation
- Extract WRAP_DETECTION_THRESHOLD constant with documentation

Stage.tsx reduced from 909 lines (original) to 701 lines.
All 340 tests pass.
Creates symmetric creation and parsing utilities for drag data:
- createActorSpriteData(): Creates sprite data for actor drags
- createCharacterSpriteData(): Creates sprite data for character drags
- createAppearanceData(): Creates appearance change data
- setHandleDragData(): Sets handle drag data on dataTransfer

Updates call sites to use the new utilities:
- actor-sprite.tsx: Uses createActorSpriteData
- recording-handle.tsx: Uses setHandleDragData with HandleSide type
- library.tsx: Uses createCharacterSpriteData and createAppearanceData

Also fixes CharacterDropData type to use `appearance` (not `appearanceId`)
to match the actual data format used throughout the codebase.

Adds 10 new tests for round-trip verification of create/parse pairs.
All 350 tests pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants