@nerdev/skillset 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +351 -0
- package/bin/skillset.mjs +205 -0
- package/curations/README.md +53 -0
- package/curations/TEMPLATE/WHY.md +23 -0
- package/curations/TEMPLATE/overlay/SKILL.md +6 -0
- package/curations/impeccable/WHY.md +34 -0
- package/curations/impeccable/overlay/SKILL.md +116 -0
- package/package.json +43 -0
- package/scripts/ste-gate.mjs +39 -0
- package/scripts/ste-lint.py +201 -0
- package/scripts/sync.mjs +174 -0
- package/skills/ai-agent/agent-docs-writer/SKILL.md +105 -0
- package/skills/ai-agent/agent-docs-writer/references/principles.md +73 -0
- package/skills/ai-agent/agent-docs-writer/templates/AGENTS.template.md +44 -0
- package/skills/ai-agent/agent-docs-writer/templates/README.template.md +19 -0
- package/skills/ai-agent/ultra-context-engine/SKILL.md +941 -0
- package/skills/architecture/blueprint/SKILL.md +191 -0
- package/skills/architecture/code-tour/SKILL.md +204 -0
- package/skills/architecture/progress-guard/SKILL.md +148 -0
- package/skills/architecture/search-first/SKILL.md +97 -0
- package/skills/backend/api-design/SKILL.md +456 -0
- package/skills/backend/auth/SKILL.md +596 -0
- package/skills/backend/database/SKILL.md +431 -0
- package/skills/backend/realtime/SKILL.md +670 -0
- package/skills/backend/security/SKILL.md +590 -0
- package/skills/business/brag/SKILL.md +177 -0
- package/skills/business/brag/assets/music/README.md +20 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-1-by-ende-dot-app.music-cues.json +3846 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-1-by-ende-dot-app.music-cues.md +35 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-10-by-ende-dot-app.music-cues.json +1826 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-10-by-ende-dot-app.music-cues.md +35 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-11-by-ende-dot-app.music-cues.json +2266 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-11-by-ende-dot-app.music-cues.md +35 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-12-by-ende-dot-app.music-cues.json +2806 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-12-by-ende-dot-app.music-cues.md +35 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-9-by-ende-dot-app.music-cues.json +2796 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-9-by-ende-dot-app.music-cues.md +35 -0
- package/skills/business/brag/assets/music/happy-beats-business-moves-vol-1-by-ende-dot-app.mp3 +0 -0
- package/skills/business/brag/assets/music/happy-beats-business-moves-vol-10-by-ende-dot-app.mp3 +0 -0
- package/skills/business/brag/assets/music/happy-beats-business-moves-vol-11-by-ende-dot-app.mp3 +0 -0
- package/skills/business/brag/assets/music/happy-beats-business-moves-vol-12-by-ende-dot-app.mp3 +0 -0
- package/skills/business/brag/assets/music/happy-beats-business-moves-vol-9-by-ende-dot-app.mp3 +0 -0
- package/skills/business/brag/assets/sfx/casino/card-fan-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-fan-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-place-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-place-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-place-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-place-4.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-shove-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-shove-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-shove-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-shove-4.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-shuffle.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-slide-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-slide-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-slide-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-slide-4.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-slide-5.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-slide-6.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-slide-7.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-slide-8.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/cards-pack-open-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/cards-pack-open-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chip-lay-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chip-lay-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chip-lay-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-collide-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-collide-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-collide-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-collide-4.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-handle-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-handle-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-handle-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-handle-4.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-handle-6.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-stack-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-stack-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-stack-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-stack-4.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-stack-5.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-stack-6.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/dice-grab-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/dice-grab-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/dice-shake-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/dice-shake-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/dice-shake-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/dice-throw-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/dice-throw-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/dice-throw-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/die-throw-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/die-throw-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/die-throw-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/die-throw-4.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_carpet_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_carpet_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_carpet_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_concrete_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_concrete_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_concrete_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_concrete_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_concrete_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_grass_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_grass_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_grass_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_grass_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_grass_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_snow_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_snow_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_snow_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_snow_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_snow_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_wood_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_wood_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_wood_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_wood_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_wood_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactBell_heavy_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactBell_heavy_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactBell_heavy_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGeneric_light_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGeneric_light_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGeneric_light_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGeneric_light_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGeneric_light_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGlass_heavy_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGlass_light_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGlass_light_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGlass_light_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGlass_medium_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGlass_medium_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGlass_medium_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_heavy_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_heavy_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_heavy_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_light_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_light_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_medium_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_medium_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_medium_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_medium_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_medium_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMining_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlank_medium_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlank_medium_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlank_medium_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlank_medium_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlank_medium_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_heavy_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_heavy_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_heavy_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_heavy_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_heavy_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_light_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_light_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_light_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_light_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_light_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_medium_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_medium_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_medium_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_medium_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_medium_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_heavy_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_heavy_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_heavy_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_heavy_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_heavy_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_medium_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_medium_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_medium_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_medium_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_medium_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_heavy_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_heavy_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_heavy_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_heavy_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_heavy_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_medium_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_medium_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_medium_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_medium_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_medium_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactTin_medium_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactTin_medium_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactTin_medium_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactTin_medium_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactTin_medium_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_heavy_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_heavy_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_heavy_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_heavy_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_heavy_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_light_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_light_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_light_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_light_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_light_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_medium_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_medium_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_medium_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_medium_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_medium_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/bong_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/click_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/click_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/click_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/click_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/click_005.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/drop_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/drop_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/drop_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/error_005.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/error_006.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/glitch_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/glitch_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/select_008.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/switch_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/switch_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/switch_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/switch_005.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/switch_006.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/switch_007.ogg +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-001.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-002.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-003.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-004.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-005.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-006.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-007.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-008.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-009.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-010.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-011.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-012.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-013.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-014.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-015.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-016.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-017.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-018.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-019.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-020.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-021.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-022.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-023.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-024.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-025.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-026.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-027.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-028.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-029.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-030.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-031.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-032.wav +0 -0
- package/skills/business/brag/assets/sfx/sfx-analysis.json +15584 -0
- package/skills/business/brag/assets/sfx/sfx-analysis.md +75 -0
- package/skills/business/brag/assets/sfx/ui/click1.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/click2.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/click3.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/click4.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/click5.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/mouseclick1.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/rollover1.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/rollover2.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/rollover4.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/rollover5.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch1.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch10.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch11.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch12.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch13.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch14.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch15.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch16.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch17.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch18.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch19.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch2.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch20.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch21.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch22.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch23.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch24.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch25.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch26.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch27.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch28.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch29.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch3.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch30.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch31.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch32.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch33.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch34.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch35.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch36.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch37.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch38.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch4.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch5.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch6.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch7.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch8.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch9.ogg +0 -0
- package/skills/business/brag/references/audio.md +307 -0
- package/skills/business/brag/references/step-1-inspect.md +133 -0
- package/skills/business/brag/references/step-2-plan.md +234 -0
- package/skills/business/brag/references/step-3-compose.md +210 -0
- package/skills/business/brag/references/step-4-deliver.md +168 -0
- package/skills/business/brag/references/tones.md +231 -0
- package/skills/business/brag/scripts/analyze_music_cues.py +309 -0
- package/skills/business/brag/scripts/pyproject.toml +14 -0
- package/skills/business/brag/scripts/uv.lock +819 -0
- package/skills/business/copywriting/SKILL.md +178 -0
- package/skills/business/customer-research/SKILL.md +259 -0
- package/skills/business/freelancing/SKILL.md +679 -0
- package/skills/business/launch/SKILL.md +273 -0
- package/skills/business/marketing-psychology/SKILL.md +364 -0
- package/skills/business/pricing/SKILL.md +233 -0
- package/skills/business/resume-revamp-jake-ats/SKILL.md +64 -0
- package/skills/business/startup-founder/SKILL.md +400 -0
- package/skills/business/startup-founder/references/funding.md +48 -0
- package/skills/business/startup-founder/references/further-reading.md +132 -0
- package/skills/business/startup-founder/references/gtm-tools.md +57 -0
- package/skills/business/startup-founder/references/legal-india.md +36 -0
- package/skills/business/startup-founder/references/marketing/README.md +16 -0
- package/skills/business/startup-founder/references/marketing/cold-email.md +172 -0
- package/skills/business/startup-founder/references/marketing/competitors.md +245 -0
- package/skills/business/startup-founder/references/marketing/customer-research.md +276 -0
- package/skills/business/startup-founder/references/marketing/free-tools.md +168 -0
- package/skills/business/startup-founder/references/marketing/launch.md +343 -0
- package/skills/business/startup-founder/references/marketing/marketing-plan.md +270 -0
- package/skills/business/startup-founder/references/marketing/pricing.md +237 -0
- package/skills/business/startup-founder/references/marketing/product-marketing.md +250 -0
- package/skills/business/startup-founder/references/validation.md +267 -0
- package/skills/devops/deployments/SKILL.md +339 -0
- package/skills/devops/git-ci/SKILL.md +372 -0
- package/skills/devops/performance/SKILL.md +523 -0
- package/skills/devops/testing/SKILL.md +558 -0
- package/skills/engineering/code-review/SKILL.md +149 -0
- package/skills/engineering/coding-standards/SKILL.md +229 -0
- package/skills/engineering/product-engineering/SKILL.md +219 -0
- package/skills/engineering/senior-engineer-prompts/SKILL.md +145 -0
- package/skills/engineering/tdd-workflow/SKILL.md +178 -0
- package/skills/engineering/verification-loop/SKILL.md +199 -0
- package/skills/nerdev/nerdev-abstraction/SKILL.md +412 -0
- package/skills/nerdev/nerdev-docs/SKILL.md +527 -0
- package/skills/nerdev/nerdev-docs/templates/adr-template.md +39 -0
- package/skills/nerdev/nerdev-docs/templates/contributing-template.md +140 -0
- package/skills/nerdev/nerdev-docs/templates/deploy-template.md +426 -0
- package/skills/nerdev/nerdev-docs/templates/design-template.md +105 -0
- package/skills/nerdev/nerdev-docs/templates/incident-template.md +66 -0
- package/skills/nerdev/nerdev-monorepo/SKILL.md +522 -0
- package/skills/quality/output-skill/SKILL.md +49 -0
- package/skills/quality/unslop/SKILL.md +67 -0
- package/skills/ui/animaxxing/SKILL.md +58 -0
- package/skills/ui/animaxxing/agents/openai.yaml +7 -0
- package/skills/ui/animaxxing/references/effect-restoration.md +26 -0
- package/skills/ui/animaxxing/references/motion-vocabulary.md +142 -0
- package/skills/ui/animaxxing/references/recipes/blast-off.md +119 -0
- package/skills/ui/animaxxing/references/recipes/particle-effects.md +718 -0
- package/skills/ui/animaxxing/references/recipes/particle-field.md +428 -0
- package/skills/ui/animaxxing/references/recipes/route-letters.md +205 -0
- package/skills/ui/animaxxing/references/recipes/speak-in.md +181 -0
- package/skills/ui/animaxxing/references/recipes/split-entrances.md +345 -0
- package/skills/ui/animaxxing/references/recipes/wave.md +144 -0
- package/skills/ui/animaxxing/references/text-stability.md +68 -0
- package/skills/ui/animaxxing/references/verification.md +44 -0
- package/skills/ui/ask-animation/SKILL.md +178 -0
- package/skills/ui/ask-base-ui/SKILL.md +400 -0
- package/skills/ui/ask-cmdk/SKILL.md +315 -0
- package/skills/ui/ask-command-menu/SKILL.md +262 -0
- package/skills/ui/ask-drawer/SKILL.md +235 -0
- package/skills/ui/ask-form/SKILL.md +229 -0
- package/skills/ui/ask-gsap/SKILL.md +435 -0
- package/skills/ui/ask-modal/SKILL.md +145 -0
- package/skills/ui/ask-motion/SKILL.md +339 -0
- package/skills/ui/ask-rhf/SKILL.md +388 -0
- package/skills/ui/ask-sonner/API.md +64 -0
- package/skills/ui/ask-sonner/SKILL.md +88 -0
- package/skills/ui/ask-table/SKILL.md +253 -0
- package/skills/ui/ask-tanstack-table/SKILL.md +490 -0
- package/skills/ui/ask-toast/SKILL.md +163 -0
- package/skills/ui/ask-vaul/SKILL.md +291 -0
- package/skills/ui/ask-virtual-list/SKILL.md +304 -0
- package/skills/ui/ask-virtuoso/SKILL.md +332 -0
- package/skills/ui/email-craft/SKILL.md +258 -0
- package/skills/ui/frontend-craftsmanship/SKILL.md +462 -0
- package/skills/ui/gsap-astro/SKILL.md +56 -0
- package/skills/ui/gsap-astro/agents/openai.yaml +7 -0
- package/skills/ui/gsap-astro/references/client-router-navigation.md +139 -0
- package/skills/ui/gsap-astro/references/initialization.md +87 -0
- package/skills/ui/gsap-astro/references/motion-system.md +152 -0
- package/skills/ui/gsap-astro/references/scripts-and-islands.md +65 -0
- package/skills/ui/gsap-astro/references/verification.md +44 -0
- package/skills/ui/gsap-core/SKILL.md +254 -0
- package/skills/ui/gsap-frameworks/SKILL.md +266 -0
- package/skills/ui/gsap-nextjs/SKILL.md +51 -0
- package/skills/ui/gsap-nextjs/agents/openai.yaml +7 -0
- package/skills/ui/gsap-nextjs/references/app-router-navigation.md +189 -0
- package/skills/ui/gsap-nextjs/references/initialization.md +87 -0
- package/skills/ui/gsap-nextjs/references/motion-system.md +158 -0
- package/skills/ui/gsap-nextjs/references/verification.md +40 -0
- package/skills/ui/gsap-nuxt/SKILL.md +56 -0
- package/skills/ui/gsap-nuxt/agents/openai.yaml +7 -0
- package/skills/ui/gsap-nuxt/references/initialization.md +87 -0
- package/skills/ui/gsap-nuxt/references/motion-system.md +161 -0
- package/skills/ui/gsap-nuxt/references/navigation.md +145 -0
- package/skills/ui/gsap-nuxt/references/page-transitions.md +107 -0
- package/skills/ui/gsap-nuxt/references/verification.md +42 -0
- package/skills/ui/gsap-performance/SKILL.md +79 -0
- package/skills/ui/gsap-plugins/SKILL.md +433 -0
- package/skills/ui/gsap-react/SKILL.md +136 -0
- package/skills/ui/gsap-react-router/SKILL.md +55 -0
- package/skills/ui/gsap-react-router/agents/openai.yaml +7 -0
- package/skills/ui/gsap-react-router/references/initialization.md +87 -0
- package/skills/ui/gsap-react-router/references/motion-system.md +158 -0
- package/skills/ui/gsap-react-router/references/react-router-navigation.md +165 -0
- package/skills/ui/gsap-react-router/references/route-lifetime.md +74 -0
- package/skills/ui/gsap-react-router/references/verification.md +42 -0
- package/skills/ui/gsap-scrolltrigger/SKILL.md +296 -0
- package/skills/ui/gsap-sveltekit/SKILL.md +54 -0
- package/skills/ui/gsap-sveltekit/agents/openai.yaml +7 -0
- package/skills/ui/gsap-sveltekit/references/initialization.md +87 -0
- package/skills/ui/gsap-sveltekit/references/motion-system.md +156 -0
- package/skills/ui/gsap-sveltekit/references/page-lifetime.md +63 -0
- package/skills/ui/gsap-sveltekit/references/sveltekit-navigation.md +160 -0
- package/skills/ui/gsap-sveltekit/references/verification.md +41 -0
- package/skills/ui/gsap-tanstack-router/SKILL.md +56 -0
- package/skills/ui/gsap-tanstack-router/agents/openai.yaml +7 -0
- package/skills/ui/gsap-tanstack-router/references/initialization.md +87 -0
- package/skills/ui/gsap-tanstack-router/references/motion-system.md +160 -0
- package/skills/ui/gsap-tanstack-router/references/route-lifetime.md +66 -0
- package/skills/ui/gsap-tanstack-router/references/tanstack-navigation.md +156 -0
- package/skills/ui/gsap-tanstack-router/references/verification.md +41 -0
- package/skills/ui/gsap-timeline/SKILL.md +107 -0
- package/skills/ui/gsap-utils/SKILL.md +284 -0
- package/skills/ui/gsap-vanilla/SKILL.md +63 -0
- package/skills/ui/gsap-vanilla/agents/openai.yaml +7 -0
- package/skills/ui/gsap-vanilla/references/cross-document-navigation.md +54 -0
- package/skills/ui/gsap-vanilla/references/initialization.md +87 -0
- package/skills/ui/gsap-vanilla/references/motion-system.md +150 -0
- package/skills/ui/gsap-vanilla/references/page-load.md +96 -0
- package/skills/ui/gsap-vanilla/references/spa-navigation.md +70 -0
- package/skills/ui/gsap-vanilla/references/verification.md +41 -0
- package/skills/ui/house-style/SKILL.md +366 -0
- package/skills/ui/imagegen/SKILL.md +49 -0
- package/skills/ui/imagegen/references/brandkit.md +48 -0
- package/skills/ui/imagegen/references/image-to-code.md +56 -0
- package/skills/ui/imagegen/references/mobile.md +58 -0
- package/skills/ui/imagegen/references/web.md +63 -0
- package/skills/ui/impeccable/SKILL.md +116 -0
- package/skills/ui/impeccable/reference/adapt.md +318 -0
- package/skills/ui/impeccable/reference/adapt.native.md +58 -0
- package/skills/ui/impeccable/reference/android.md +46 -0
- package/skills/ui/impeccable/reference/animate.md +89 -0
- package/skills/ui/impeccable/reference/audit.md +137 -0
- package/skills/ui/impeccable/reference/audit.native.md +139 -0
- package/skills/ui/impeccable/reference/bolder.md +33 -0
- package/skills/ui/impeccable/reference/clarify.md +94 -0
- package/skills/ui/impeccable/reference/colorize.md +86 -0
- package/skills/ui/impeccable/reference/craft-floor.md +44 -0
- package/skills/ui/impeccable/reference/craft.md +5 -0
- package/skills/ui/impeccable/reference/critique.md +806 -0
- package/skills/ui/impeccable/reference/degraded/asset-producer.md +37 -0
- package/skills/ui/impeccable/reference/degraded/documenter.md +24 -0
- package/skills/ui/impeccable/reference/degraded/finish-reviewer.md +38 -0
- package/skills/ui/impeccable/reference/degraded/manual-edit-applier.md +92 -0
- package/skills/ui/impeccable/reference/delight.md +70 -0
- package/skills/ui/impeccable/reference/distill.md +111 -0
- package/skills/ui/impeccable/reference/doctor.md +54 -0
- package/skills/ui/impeccable/reference/document.md +416 -0
- package/skills/ui/impeccable/reference/extract.md +69 -0
- package/skills/ui/impeccable/reference/generate.md +101 -0
- package/skills/ui/impeccable/reference/harden.md +345 -0
- package/skills/ui/impeccable/reference/hooks.md +111 -0
- package/skills/ui/impeccable/reference/init.md +131 -0
- package/skills/ui/impeccable/reference/ios.md +51 -0
- package/skills/ui/impeccable/reference/layout.md +84 -0
- package/skills/ui/impeccable/reference/live-setup.md +104 -0
- package/skills/ui/impeccable/reference/live.md +325 -0
- package/skills/ui/impeccable/reference/new-work.md +145 -0
- package/skills/ui/impeccable/reference/onboard.md +234 -0
- package/skills/ui/impeccable/reference/operate.md +61 -0
- package/skills/ui/impeccable/reference/optimize.md +258 -0
- package/skills/ui/impeccable/reference/overdrive.md +127 -0
- package/skills/ui/impeccable/reference/polish.md +105 -0
- package/skills/ui/impeccable/reference/quieter.md +99 -0
- package/skills/ui/impeccable/reference/routing.md +24 -0
- package/skills/ui/impeccable/reference/shape.md +59 -0
- package/skills/ui/impeccable/reference/typeset.md +80 -0
- package/skills/ui/impeccable/reference/visualize.md +46 -0
- package/skills/ui/impeccable/scripts/VERSION +1 -0
- package/skills/ui/impeccable/scripts/command-metadata.json +98 -0
- package/skills/ui/impeccable/scripts/data/font-index-failures.json +121 -0
- package/skills/ui/impeccable/scripts/data/font-index.json +1 -0
- package/skills/ui/impeccable/scripts/impeccable +206 -0
- package/skills/ui/impeccable/scripts/impeccable.cmd +214 -0
- package/skills/ui/impeccable/scripts/live-browser-dom.js +167 -0
- package/skills/ui/impeccable/scripts/live-browser-ignores.js +242 -0
- package/skills/ui/impeccable/scripts/live-browser-session.js +144 -0
- package/skills/ui/impeccable/scripts/live-browser.js +13510 -0
- package/skills/ui/impeccable/scripts/modern-screenshot.umd.js +14 -0
- package/skills/ui/motion/SKILL.md +207 -0
- package/skills/ui/pick-ui-library/SKILL.md +85 -0
- package/skills/ui/product-messaging/SKILL.md +163 -0
- package/skills/ui/product-site/SKILL.md +465 -0
- package/skills/ui/prototype/PICKER.md +197 -0
- package/skills/ui/prototype/SKILL.md +98 -0
- package/skills/ui/refero-design/SKILL.md +534 -0
- package/skills/ui/refero-design/agents/openai.yaml +4 -0
- package/skills/ui/refero-design/references/anti-ai-slop.md +292 -0
- package/skills/ui/refero-design/references/color.md +563 -0
- package/skills/ui/refero-design/references/copywriting.md +222 -0
- package/skills/ui/refero-design/references/craft-details.md +525 -0
- package/skills/ui/refero-design/references/example-workflow.md +264 -0
- package/skills/ui/refero-design/references/icons.md +166 -0
- package/skills/ui/refero-design/references/mcp-tools.md +258 -0
- package/skills/ui/refero-design/references/motion.md +504 -0
- package/skills/ui/refero-design/references/typography.md +737 -0
- package/skills/ui/refero-design/references/visual-workflow.md +105 -0
- package/skills/ui/style-animaxxing/SKILL.md +48 -0
- package/skills/ui/style-animaxxing/agents/openai.yaml +7 -0
- package/skills/ui/style-animaxxing/references/motion-vocabulary.md +51 -0
- package/skills/ui/style-animaxxing/references/tokens.md +288 -0
- package/skills/ui/style-animaxxing/references/typography-and-layout.md +149 -0
- package/skills/ui/style-animaxxing/references/verification.md +38 -0
- package/skills/ui/typography-picker/SKILL.md +305 -0
- package/skills/ui/ui-core/SKILL.md +345 -0
- package/skills/ui/ui-core/references/accessibility.md +85 -0
- package/skills/ui/ui-core/references/build.md +666 -0
- package/skills/ui/ui-core/references/copy.md +70 -0
- package/skills/ui/ui-core/references/dark-mode.md +76 -0
- package/skills/ui/ui-core/references/direction.md +99 -0
- package/skills/ui/ui-core/references/redesign.md +74 -0
- package/skills/ui/ui-core/references/responsive.md +77 -0
- package/skills/ui/ui-core/references/styles.md +42 -0
- package/skills/ui/ui-core/references/system.md +190 -0
- package/skills/ui/ui-core/references/verify.md +37 -0
- package/skills/ui/ui-engineering/SKILL.md +436 -0
- package/skills/ui/ui-engineering/references/avatars.md +74 -0
- package/skills/ui/ui-engineering/references/card-patterns.md +66 -0
- package/skills/ui/ui-engineering/references/floating-actions.md +65 -0
- package/skills/ui/ui-engineering/references/navigation.md +81 -0
- package/skills/ui/ui-engineering/references/overlays.md +74 -0
- package/skills/ui/ui-engineering/references/pagination.md +71 -0
- package/skills/ui/ui-engineering/references/progress-indicators.md +77 -0
- package/skills/ui/ui-engineering/references/quality-bar.md +293 -0
- package/skills/ui/ui-engineering/references/search.md +68 -0
- package/skills/ui/ui-engineering/references/tailwind-architecture.md +81 -0
- package/skills/ui/ui-theme-picker/SKILL.md +522 -0
- package/skills/ui/ui-theme-picker/references/component-sources.md +223 -0
- package/skills/ui/ui-theme-picker/references/styles.md +298 -0
- package/skills/ui/vitepress-docs/SKILL.md +439 -0
- package/skills/ui/vitepress-docs/references/components.md +333 -0
- package/skills/ui/vitepress-docs/references/layout.md +128 -0
- package/skills/ui/vitepress-docs/references/tokens.md +87 -0
- package/skills/ui/vitepress-docs/references/typography.md +76 -0
- package/skills/workflow/careful/SKILL.md +48 -0
- package/skills/workflow/context-restore/SKILL.md +69 -0
- package/skills/workflow/context-save/SKILL.md +96 -0
- package/skills/workflow/health/SKILL.md +99 -0
- package/skills/workflow/learn/SKILL.md +95 -0
- package/skills/workflow/office-hours/SKILL.md +136 -0
- package/skills/workflow/ship/SKILL.md +95 -0
- package/vendor.json +80 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Route lifetime
|
|
2
|
+
|
|
3
|
+
Read this to know when a route component mounts, updates in place, or unmounts, how the React lifecycle fits GSAP under this router, and what TanStack Start's server rendering changes.
|
|
4
|
+
|
|
5
|
+
## Reuse versus remount
|
|
6
|
+
|
|
7
|
+
The router renders matches as a chain: root, layouts, page, each in its own memoized `Match`. A navigation swaps only the levels whose route changed.
|
|
8
|
+
|
|
9
|
+
- Same route, new params or search: the component is reused. Its loader reruns when `loaderDeps` or `staleTime` say so; `useParams`, `useSearch`, and `useLoaderData` update in the commit. No mount, no unmount, no `useGSAP` with an empty dependency list.
|
|
10
|
+
- Different route under the same layouts: the page unmounts and the new one mounts. The layouts stay, with their state, timelines, and listeners.
|
|
11
|
+
- Layout routes (`route.tsx`, `_pathless` layouts, the root) persist for their subtree and unmount only when the tree leaves them.
|
|
12
|
+
- `router.invalidate` reruns loaders and updates props. Nothing remounts.
|
|
13
|
+
- `remountDeps({ routeId, params, search, loaderDeps })` on a route, or `defaultRemountDeps` on the router, forces a remount whenever its JSON-serializable return value changes. `({ params }) => params` is the documented way to remount per param.
|
|
14
|
+
|
|
15
|
+
So a page intro tied to a mount plays once per mount, not once per visit. Two fixes:
|
|
16
|
+
|
|
17
|
+
- **Rerun the lifecycle on the reused node, the default for GSAP.** Give `useGSAP` the params, or the loader data, as dependencies with `revertOnUpdate`. The DOM already holds settled values and the previous timeline may still be running, so kill it first and write initial state with `set` or `fromTo`, never a `from` tween that trusts a fresh node. Skip when only search params changed unless they mean a different screen.
|
|
18
|
+
- **`remountDeps`.** Every param change destroys and recreates the component, so the mount path replays. It discards component state and inner scroll positions, which is what the docs offer for that case.
|
|
19
|
+
|
|
20
|
+
Do not wrap `<Outlet />` in an element keyed on `useLocation().pathname`. That location moves when loading starts, before the new matches commit, so the wrapper remounts the old page once while it waits and again when the new page arrives. If a keyed wrapper is unavoidable, key it on the leaf of the presented matches, and expect it to remount every nested layout inside it.
|
|
21
|
+
|
|
22
|
+
## Layouts and the controller
|
|
23
|
+
|
|
24
|
+
The root route's component mounts once per document and outlives every client-side navigation. That makes it the home of the route transition controller: one ref'd route container around `<Outlet />`, the blocker, the history subscription, the phase, and the cover. Nested layout routes persist for their subtree and are the place for section-level chrome motion.
|
|
25
|
+
|
|
26
|
+
`Wrap` and `InnerWrap` on the router are for providers only; the docs forbid DOM-rendering components there. Keep the container in the root component.
|
|
27
|
+
|
|
28
|
+
Pages register intro and outro builders with the controller through context and unregister in their effect cleanup. The controller runs the outgoing page's outro from `shouldBlockFn` and the incoming page's intro when it reports ready. Ready is reported through that context only after required preparation, initial writes, and timeline handlers are ready. It drops the cover and releases the matching lock. If readiness times out, recover that incoming owner through [Initialization and recovery](initialization.md) before releasing its cover. A page that registers nothing gets the container-level default.
|
|
29
|
+
|
|
30
|
+
A `useBlocker` in a page sees only navigations away from that page and unregisters when it unmounts. One blocker in the root is simpler than one per page.
|
|
31
|
+
|
|
32
|
+
## React lifecycle for GSAP
|
|
33
|
+
|
|
34
|
+
- `useGSAP` runs in a layout effect after the tree commits, before `onRendered` and before scroll restoration. `gsap-react` covers `scope`, `contextSafe`, `revertOnUpdate`, and cleanup. Use it unchanged.
|
|
35
|
+
- Route components render on the client inside `React.startTransition`. A component that suspends keeps the old tree on screen; the new tree mounts as a whole when it can. Layout effects, and so `useGSAP`, run in that single commit.
|
|
36
|
+
- Never call another component's `contextSafe` function from inside a `useGSAP` callback. GSAP nests contexts: a context whose function runs while another context's callback is executing becomes a child of that outer context, and the outer context's next revert kills it. A page's setup must not synchronously trigger the root controller's builders. Hand off through a microtask, an effect, or an event.
|
|
37
|
+
- Write setup so it is correct when it runs more than once on the same node. React development checks do this, and a reused route runs its keyed effect again on settled DOM. Async work started by the first run can still be in flight when the second starts, so anything a setup triggers outside its own context, such as the cover, must be safe to request twice. Use a ref guard only for work that should happen once per visit.
|
|
38
|
+
- Store the phase in a ref and mirror it as a data attribute. Do not infer it from opacity, DOM presence, or timeline progress.
|
|
39
|
+
- `onEnter`, `onStay`, and `onLeave` on a route run with the match during the load commit, before React renders it. They are for data and analytics, not for DOM work.
|
|
40
|
+
|
|
41
|
+
## Conditional content
|
|
42
|
+
|
|
43
|
+
React unmounts conditional content before an outro can play. Keep the node mounted with a presence controller: render while `visible || leaving`, play the outro, and clear `leaving` from the end callback. See [Conditional show and hide](motion-system.md#conditional-show-and-hide).
|
|
44
|
+
|
|
45
|
+
A modal that is a child route unmounts when the URL leaves it. Close it by playing its outro and then navigating, with `router.history.back()` when it was pushed or `navigate` to the parent otherwise, and tell the root controller that navigation is an overlay close so it runs no page outro and no cover. Undo scroll locks, key listeners, and focus in the effect teardown, which also covers a back navigation you did not initiate. Route masking (`mask`) changes only the URL shown; the component lifetime follows the real route.
|
|
46
|
+
|
|
47
|
+
## SSR and hydration with TanStack Start
|
|
48
|
+
|
|
49
|
+
- The root route renders the document. Its `component`, or its `shellComponent` when the root itself has `ssr: false`, returns `html`, `head` with `<HeadContent />`, and `body` with the children and `<Scripts />` last. `HeadContent` belongs in `head`; `Scripts` belongs at the end of `body`. The client entry, optional, is `hydrateRoot(document, <StartClient />)`.
|
|
50
|
+
- Server HTML paints before hydration, before any effect. If initial state must hide before first paint, render `<ScriptOnce>` from `@tanstack/react-router` as the first child of `body` with an inline script that marks `documentElement` as JavaScript-active, and a CSS rule that hides intro targets only under that mark and only while the root is in its initial phase. `ScriptOnce` renders the script on the server with a trailing `document.currentScript.remove()`, so it runs once during parsing and is gone before hydration, and it returns `null` on the client. Skip the mark under `prefers-reduced-motion` so the page paints settled. Add `suppressHydrationWarning` to `html`, since the server markup does not carry the attribute. Register recovery before setup; advance the phase only after start values and completion handlers are ready. Keep content readable without JavaScript and keep the swap cover separate from the first-paint rule.
|
|
51
|
+
- Keep the early failsafe active until preparation succeeds and the intro can run, not merely until a controller registers. Register rollback before setup, preserve the original deadline, and take the settled path after recovery. Follow [Initialization and recovery](initialization.md).
|
|
52
|
+
- Hydration is the first mount. `useGSAP` runs once React attaches, and `onRendered` fires once with nothing changed. No `onBeforeNavigate` or `onBeforeLoad` precedes it.
|
|
53
|
+
- Do not write inline styles or move DOM before hydration. The pre-paint rule is CSS keyed on the root attribute, which is why it does not break hydration.
|
|
54
|
+
- `ssr: false` or `ssr: 'data-only'` on a route skips server rendering of its component: the server renders the route's `pendingComponent` as a fallback and the client shows it for at least `pendingMinMs` before the real component mounts. That mount is the first lifecycle for the route; nothing settled was painted, so it needs no pre-paint rule. The setting inherits downward and can only become more restrictive. `defaultSsr` in `createStart` sets the default.
|
|
55
|
+
- SPA mode (`spa.enabled`) prerenders only the root and the pending fallback; every route is a client mount. Prerendered routes hydrate like SSR routes.
|
|
56
|
+
- `<ClientOnly fallback>` and `useHydrated` render browser-only content after hydration. Use them for content whose server markup would differ, not as a way to hide intro targets.
|
|
57
|
+
- Deferred hydration (`<Hydrate when>`, experimental) keeps a boundary's server HTML on screen and hydrates it later. GSAP inside it starts only then. Treat it as a component that mounts late with its server HTML as the initial paint, and keep its targets out of the page's pre-paint rule.
|
|
58
|
+
- `useGSAP` never runs on the server. Importing GSAP in a route file is harmless; calling it at module scope is not. Register plugins in one client-only module that route files import lazily or inside effects.
|
|
59
|
+
|
|
60
|
+
## Deferred data and streaming
|
|
61
|
+
|
|
62
|
+
- A loader returns unawaited promises alongside awaited data; the route renders when the awaited data resolves and the rest streams, on the server through the HTML stream and on the client after mount. `<Await promise fallback>` or React 19 `use()` suspends the nearest boundary until each resolves.
|
|
63
|
+
- Treat each streamed region as a component with its own controller: explicit initial state on arrival, a short intro, settled, cleanup. It never reports page ready. Reserve its block size in the fallback so arrival moves nothing.
|
|
64
|
+
- The page outro owns everything present at leave time. Query outro targets when the outro is built, not at setup, so content that streamed in after setup leaves with the page. Intros stay separate: the page intro reveals what mounted with it, the region intro reveals what arrived later.
|
|
65
|
+
- Preloaded loader data lives in the router cache for `preloadStaleTime`; a navigation reuses it or joins the loader still in flight. Do not assume it survives a long outro plus an invalidation.
|
|
66
|
+
- With an external cache such as TanStack Query the loader only primes the cache; the same region rules apply to whatever suspends in the component.
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# TanStack navigation
|
|
2
|
+
|
|
3
|
+
Read this when changing route-level motion or navigation.
|
|
4
|
+
|
|
5
|
+
## Router APIs
|
|
6
|
+
|
|
7
|
+
Check the installed types before using these. Everything below comes from `@tanstack/react-router` unless noted, and describes the current 1.17x releases.
|
|
8
|
+
|
|
9
|
+
- `useBlocker({ shouldBlockFn, withResolver, disabled, enableBeforeUnload })`, marked experimental in the docs. `shouldBlockFn({ current, next, action })` returns `boolean | Promise<boolean>`; `true` blocks. `current` and `next` carry `routeId`, `fullPath`, `pathname`, `params`, and `search`. `action` is `PUSH`, `REPLACE`, `BACK`, `FORWARD`, or `GO`. With `withResolver: true` the hook returns `status` (`blocked` or `idle`), `current`, `next`, `action`, `proceed`, and `reset`; without it, the function's own return value decides. `disabled` removes the blocker. `enableBeforeUnload` defaults to `true` and also raises the browser's unload dialog on reload and tab close; set it `false` for a motion-only blocker. The older `blockerFn` and `condition` forms are deprecated. The hook re-registers whenever `shouldBlockFn` changes identity, so keep it stable and read live state through a ref.
|
|
10
|
+
- Blockers live in the history layer, one list for the whole router, run in order and awaited one at a time. For `PUSH` and `REPLACE` they run before the URL changes and before any loader starts. For back and forward the browser has already moved: the blocker runs from `popstate` with the new entry in the address bar, a block reverses the move with `history.go`, and an allow keeps it. `ignoreBlocker` on a Link or `navigate` skips every blocker.
|
|
11
|
+
- `Link` props: `to`, `params`, `search`, `hash`, `state`, `replace`, `resetScroll`, `hashScrollIntoView`, `viewTransition`, `startTransition`, `ignoreBlocker`, `reloadDocument`, `preload` (`false`, `'intent'`, `'viewport'`, `'render'`), `preloadDelay` (50 ms default), `activeProps`, `inactiveProps`, `activeOptions`, `disabled`, `target`. An active link renders `data-status="active"` and `aria-current="page"`. The router's click handler runs after your `onClick` and skips navigation when the event is `defaultPrevented`, carries a modifier key, is not the primary button, targets anything but `_self`, or the link is `disabled`. An external `href` renders a plain anchor with no router handling. `createLink` builds a typed Link around your own component.
|
|
12
|
+
- `useNavigate({ from })` returns `navigate(options)` taking `NavigateOptions`: `to`, `params`, `search`, `hash`, `state`, `replace`, `resetScroll`, `hashScrollIntoView`, `viewTransition`, `ignoreBlocker`, `reloadDocument`, `href`. It resolves after the destination has rendered, and never if a blocker cancels it, so do not await it for a navigation that may be blocked. `router.navigate` is the same outside components; `Route.useNavigate` presets `from`. `href` to another origin or `reloadDocument` performs a document navigation; blockers still run for it, with `next` equal to `current`.
|
|
13
|
+
- `useRouterState({ select })`: `status` (`pending` or `idle`), `isLoading` (true while pending), `location`, `resolvedLocation`, `matches`. `isTransitioning` existed through router-core 1.171.1x and is gone from current releases; check the installed `RouterState`. Always select a slice.
|
|
14
|
+
- `useLocation({ select })` follows `state.location`, which moves to the destination when loading starts while the old page is still on screen. `resolvedLocation` moves after the new page has rendered.
|
|
15
|
+
- `useMatches`, `useMatch({ from, select })`, `useParams`, `useSearch`, `Route.useLoaderData`: the presented matches, updated in the commit that mounts the new page. `useMatchRoute()({ to, pending: true })` and `<MatchRoute pending>` say whether a destination is the one currently loading.
|
|
16
|
+
- `router.subscribe(event, fn)` returns an unsubscribe. Events: `onBeforeNavigate`, `onBeforeLoad`, `onLoad`, `onBeforeRouteMount`, `onResolved`, `onRendered`, each with `fromLocation` (undefined on the first load), `toLocation`, `pathChanged`, `hrefChanged`, and `hashChanged`.
|
|
17
|
+
- `router.history.subscribe(({ location, action }) => ...)` fires on every history change with `action.type` `PUSH`, `REPLACE`, `BACK`, `FORWARD`, or `GO`. `useCanGoBack()` reads the history index; `router.history.back()` goes back.
|
|
18
|
+
- `location.state.__TSR_index` is the history index and `__TSR_key` the entry key; the router's own view-transition example derives direction from the index. Both are internal fields on a public type; prefer the history action.
|
|
19
|
+
- Route options that shape timing: `pendingComponent`, `pendingMs` (default 1000), `pendingMinMs` (default 500), `staleTime` (default 0), `preloadStaleTime` (30 s), `loaderDeps`, `shouldReload`, `remountDeps`, `ssr`. Router-level defaults carry the `default` prefix. `onEnter`, `onStay`, and `onLeave` receive the match during commit; they are data callbacks, not DOM hooks.
|
|
20
|
+
|
|
21
|
+
## Order of one navigation
|
|
22
|
+
|
|
23
|
+
Read from the client runtime. Confirm against the installed version when timing matters.
|
|
24
|
+
|
|
25
|
+
1. A Link click or `navigate` builds the location. Blockers run, each awaited. A `true` stops here; nothing has changed. A preload that started on hover keeps running.
|
|
26
|
+
2. History push or replace. The URL changes. `history.subscribe` listeners run with the action; the router's own subscription calls `load`.
|
|
27
|
+
3. `onBeforeNavigate`, then `onBeforeLoad`. The outgoing page's scroll positions are snapshotted here.
|
|
28
|
+
4. `status` becomes `pending` and `location` moves to the destination. The old matches are still presented; the old page stays mounted and interactive.
|
|
29
|
+
5. `beforeLoad` and loaders run, reusing a fresh preload or joining one in flight. Past `pendingMs`, the pending component is presented in place of the pending route inside a React transition and held at least `pendingMinMs`.
|
|
30
|
+
6. If a view transition applies, `document.startViewTransition` wraps the next two steps.
|
|
31
|
+
7. Inside `React.startTransition`: the matches commit, `onLoad`, then `onBeforeRouteMount`. React renders the new tree. Reused components receive new params and loader data; new ones mount and run their layout effects, including `useGSAP`.
|
|
32
|
+
8. After the new tree has committed: `resolvedLocation` is set, `status` returns to `idle`, `onResolved`, then `onRendered`. Scroll restoration, the top reset, and hash scrolling run in `onRendered`. The `navigate` promise resolves.
|
|
33
|
+
|
|
34
|
+
A newer navigation abandons an older one at every await, and the abandoned one emits nothing further. Nothing in this list precedes the URL change except the blocker, which is why the outro lives there.
|
|
35
|
+
|
|
36
|
+
`onRendered` runs from a microtask after the root layout effect, so it sees the committed DOM, normally before paint. A page's `useGSAP` runs before it, and before scroll restoration.
|
|
37
|
+
|
|
38
|
+
First load differs: a client-only app runs a full load, so every event fires with `fromLocation` undefined; after TanStack Start hydration the router acknowledges the server-rendered matches and emits only `onRendered`, with nothing changed. In both cases the page's first `useGSAP` is the mount.
|
|
39
|
+
|
|
40
|
+
## Page lifecycle
|
|
41
|
+
|
|
42
|
+
**mount → initial state → intro → settled → outro → end state → unmount**
|
|
43
|
+
|
|
44
|
+
1. **Initial state.** The incoming page has mounted or updated in place, its final size is reserved, measurements are taken, and start values are set before anything is shown.
|
|
45
|
+
2. **Intro.** Reveal the route and play one timeline to the final layout.
|
|
46
|
+
3. **Settled.** Clear temporary styles. CSS owns the page. Everything is interactive.
|
|
47
|
+
4. **Outro.** The outgoing page stays mounted while the blocker holds the navigation. Stop competing component animations and play one outro timeline.
|
|
48
|
+
5. **End state.** Finalize outgoing targets and run completion once while still mounted. Let the navigation proceed. The outgoing tree goes away when the router commits the loaded destination.
|
|
49
|
+
|
|
50
|
+
A controller may track internal states like `waiting` or `preparing`, but they serve these five phases.
|
|
51
|
+
|
|
52
|
+
Store the phase in a ref owned by the root controller and mirror it as a data attribute on the route container, so CSS and tests can read it.
|
|
53
|
+
|
|
54
|
+
## Outro before navigation: two paths
|
|
55
|
+
|
|
56
|
+
Both run on the old page. Pick one per project and use it everywhere.
|
|
57
|
+
|
|
58
|
+
**`useBlocker`, the default.** Mount it once in the root controller. `shouldBlockFn` returns `false` for `BACK`, `FORWARD`, and `GO`, for hash-only and same-location changes, and for anything the design does not transition. Otherwise it returns a promise that the outro's end callback resolves with `false`, which allows the navigation. Never return `false` because an outro or swap is already in progress: that lets the second push commit at once, the outgoing page unmounts mid-outro, its context revert kills the timeline, `onComplete` never fires, and the first promise hangs forever. A navigation that arrives during an outro is blocked too, and the lock decides which promise resolves with `true`. See [One navigation at a time](#one-navigation-at-a-time). Nothing is cancelled or re-issued: the original push continues, so `replace`, `resetScroll`, `viewTransition`, and the Link's intent survive, no blocker re-enters, and `navigate` calls and redirects get the same outro as links. The costs: the URL waits, and so do the loaders, so the end state sits on screen until the destination loads unless `preload="intent"` or `defaultPreload: 'intent'` already started the fetch on hover. Turn intent preloading on when using this path; the navigation reuses the preload or joins the loader still in flight. Set `enableBeforeUnload: false` unless the app also wants the unload dialog.
|
|
59
|
+
|
|
60
|
+
`withResolver: true` is the docs' form for rendering a prompt. In a controller it has a trap: one resolver is shared by every navigation, and resolving any of them resets `status` to `idle`, so a second click during an outro replaces `proceed` and strands the first navigation. If you use it, capture `proceed` and `reset` in a ref the moment `status` turns `blocked` and keep them past the state change. The promise-returning `shouldBlockFn` gives each navigation its own promise and needs no React state; prefer it.
|
|
61
|
+
|
|
62
|
+
**An intercepted Link, the alternative.** Wrap `Link` with an `onClick` that applies the router's own exclusions (modifier keys, non-primary button, `target`, `disabled`, external href), calls `preventDefault`, plays the outro, then calls `navigate` with the same `to`, `params`, `search`, `hash`, `state`, `replace`, `resetScroll`, `hashScrollIntoView`, and `viewTransition`. Because the `Link` still renders, `href`, `preload`, `activeProps`, and `data-status` survive. The costs: buttons, `navigate` calls, redirects, and forms bypass it; every option must be forwarded by hand; and if a `useBlocker` also exists, the re-issued push hits it, so pass `ignoreBlocker: true` or set a guard first. Use it only when a blocker cannot be mounted where the outro is decided.
|
|
63
|
+
|
|
64
|
+
Neither path delays a document unload. `reloadDocument`, external hrefs, and the close button get at most the browser's unload dialog. A hash-only change goes through the same push; return `false` when `next.pathname` equals `current.pathname`.
|
|
65
|
+
|
|
66
|
+
## One navigation at a time
|
|
67
|
+
|
|
68
|
+
- Keep the pending navigation's resolver in a ref. When a second navigation is blocked during outro or preparing, decide once: resolve the earlier promise with `true` to cancel it and adopt the new destination, or resolve the new one with `true` and keep the first. Never leave a promise pending; a pending blocker holds its navigation forever.
|
|
69
|
+
- Release the lock when the incoming intro starts, not when it ends: a click during the intro must kill the intro and start the outro from current values, and holding the lock through the intro leaves every link dead until it finishes.
|
|
70
|
+
- Back or forward during an outro: return `false` at once, kill the outro, resolve its pending promise with `true` so the requested push never commits over the history move, and take the intro-only path.
|
|
71
|
+
- A killed timeline never resolves its promise. Wrap `await` in a helper that also resolves on `onInterrupt` and returns whether the timeline completed, so an interrupted outro never leaves a blocker pending.
|
|
72
|
+
- GSAP's ticker stops in a hidden tab. Race the outro against a timeout so a click from a background tab still navigates.
|
|
73
|
+
- React development runs the controller's effects twice, so the blocker registers, unregisters, and registers again. Keep the phase and resolver in refs so the second run sees the first's state.
|
|
74
|
+
|
|
75
|
+
## Two kinds of navigation
|
|
76
|
+
|
|
77
|
+
- **Requested** (`PUSH` and `REPLACE` from a Link, `navigate`, or a submit handler): the full lifecycle. The blocker holds, the outgoing page plays its outro on live DOM, the router loads and commits, the incoming page prepares and plays its intro.
|
|
78
|
+
- **Unrequested** (`BACK`, `FORWARD`, `GO`, a redirect thrown from `beforeLoad` or a loader, `router.invalidate`, `reloadDocument`, external links): the tree changes without an outro, or the document reloads. Run initial state and intro only, without travel. Keep the shell stable. Optionally give these a `viewTransition` crossfade so the swap is not a hard cut.
|
|
79
|
+
|
|
80
|
+
A redirect during a requested navigation pushes again and reaches the blocker; the in-progress guard above returns `false` for it. Do not keep a copy of the old React tree to fake an outro for unrequested navigation. The outgoing route unmounts on commit, so a copy is stale immediately. Support fewer outro paths instead.
|
|
81
|
+
|
|
82
|
+
## Back and forward
|
|
83
|
+
|
|
84
|
+
- Detect them from `action` in `shouldBlockFn` and from `router.history.subscribe`, which fires before any router event because the history change is what starts the load. Record the action in a ref there and read it when the incoming page reports ready.
|
|
85
|
+
- Never run an outro. The URL has already changed when the blocker runs; blocking reverses history and the user sees a bounce.
|
|
86
|
+
- Scroll restoration runs in `onRendered`, after the page's `useGSAP`. Start history intros from `onRendered` or later, then refresh ScrollTrigger. Reveal-on-scroll targets above the restored position must not stay hidden.
|
|
87
|
+
- A page reached by back that stayed matched with different params is reused, not remounted, and holds settled values. Write initial state explicitly.
|
|
88
|
+
- Leaving the site and coming back may restore the document from the bfcache. No router event runs; `pagehide` only saves scroll. Leave the page readable whenever the document may unload.
|
|
89
|
+
|
|
90
|
+
## Pending UI and the loading gap
|
|
91
|
+
|
|
92
|
+
The router waits for loaders before it swaps, so the old page stays presented and `status` is `pending`. After `pendingMs` it presents `pendingComponent` in place of the pending route, parent layouts included, for at least `pendingMinMs`. Without a pending component the old page stays until the data arrives.
|
|
93
|
+
|
|
94
|
+
- With the blocker path the outro has already finished, so the end state, or the cover, is what the user sees during the wait. Intent preloading shortens it.
|
|
95
|
+
- A pending component mounts inside the route container. Give it the same geometry, treat it as unrequested content with no intro handoff, and let the boundary's ready timeout release the cover. The real page then mounts through the normal path.
|
|
96
|
+
- For a pending hint in chrome, select `status` from `useRouterState` or use `useMatchRoute` with `pending: true` on the link's destination. There is no per-link status hook.
|
|
97
|
+
- Data returned from a loader as an unawaited promise streams: `<Await promise fallback>` or React 19 `use()` suspends the nearest boundary. Treat each such region as a component with its own controller. See [Deferred data](route-lifetime.md#deferred-data-and-streaming).
|
|
98
|
+
|
|
99
|
+
## Overlapping the old and new page
|
|
100
|
+
|
|
101
|
+
The router shows one route tree. An effect that needs both pages on screen at once has two honest options:
|
|
102
|
+
|
|
103
|
+
- **The browser.** `viewTransition` snapshots both trees itself. Types give the CSS the direction and the clip.
|
|
104
|
+
- **A DOM snapshot.** After the outgoing page reaches end state and before resolving the blocker, deep-clone the route container into a fixed layer: strip ids and every data attribute your lifecycle selects on, set `inert` and `aria-hidden`, position it at the container's document offset shifted by the scroll. Let the navigation proceed with no cover. The incoming intro reveals the new page over the clone and removes it at settle, on a ready timeout, on back or forward mid-transition, and at the start of any new navigation.
|
|
105
|
+
|
|
106
|
+
The clone is a static picture, not a React tree: nothing in it updates, and it is gone before the page is interactive. Skip the outgoing outro for this archetype; a faded end state gives the reveal nothing to sit on.
|
|
107
|
+
|
|
108
|
+
## The swap gap and initial state
|
|
109
|
+
|
|
110
|
+
With the blocker path the old page sits at end state while the loaders run and React commits. Cover the route container during that gap, inside the element that wraps route content and never fixed to the viewport, or the header and footer flash on every click. Uncover only after every incoming target has its size and start styles.
|
|
111
|
+
|
|
112
|
+
The initial state must occupy the same layout as the settled state. Prefer `autoAlpha` and transforms. Size images, media, masks, and async regions before the intro. If the effect changes geometry, reserve the settled size with a wrapper or measure both states before writing either.
|
|
113
|
+
|
|
114
|
+
The route container owns geometry during the swap: hold a stable height while trees exchange, or animate it between measured sizes on purpose; if old and new are both mounted, overlap them so only one takes up space; reserve scrollbar space if route height changes would shift it.
|
|
115
|
+
|
|
116
|
+
Under TanStack Start, server HTML paints before hydration. Do not hide it unconditionally; the pre-paint rule in [SSR and hydration](route-lifetime.md#ssr-and-hydration-with-tanstack-start) is the only sanctioned way to hide before the first intro. A client-only app paints nothing before React and needs no such rule.
|
|
117
|
+
|
|
118
|
+
Do not rely only on inline styles: a context revert clears them during a swap. The cover must survive cleanup until the new tree is ready.
|
|
119
|
+
|
|
120
|
+
## Settled state, focus, and scroll
|
|
121
|
+
|
|
122
|
+
On intro completion, mark settled once, clear temporary transforms, visibility, and `will-change`, and do not keep the page inside an active timeline to hold values.
|
|
123
|
+
|
|
124
|
+
- TanStack Router moves no focus. After a client navigation focus stays wherever it was, usually on a link that has unmounted, which drops it to `body`. Move focus to the route container or main heading from the intro's completion when the design needs it, with `tabIndex={-1}` and a visible focus style. Do not steal focus from an active control.
|
|
125
|
+
- Keep the router's scroll behavior. `scrollRestoration: true` restores per history entry and resets new entries to the top, both in `onRendered` before paint; the `<ScrollRestoration />` component is deprecated. `resetScroll: false` on a Link or `navigate` keeps the current position. `scrollToTopSelectors` adds nested scrollers; `scrollRestorationBehavior: 'instant'` stops a smooth scroll from running under an intro; `getScrollRestorationKey` keys by pathname instead of history entry. Without `scrollRestoration` the router still scrolls to the top and to the hash.
|
|
126
|
+
- Refresh ScrollTrigger after `onRendered`, and after the intro if anything above a trigger changed height.
|
|
127
|
+
- The router announces nothing. `head()` updates the title through `HeadContent`; add your own live region if the product needs navigation announced.
|
|
128
|
+
|
|
129
|
+
## Combining with View Transitions
|
|
130
|
+
|
|
131
|
+
`defaultViewTransition: true` or `{ types }` on the router, or `viewTransition` on a Link or `navigate`, wraps the match commit and React render in `document.startViewTransition`. `types` is an array or a function of the location change info that returns an array or `false` to skip; typed transitions need `:active-view-transition-type` support and otherwise run untyped. GSAP runs before it, outro on live DOM held by the blocker, and after it, intro on the new tree. Keep their jobs separate:
|
|
132
|
+
|
|
133
|
+
- The router awaits `updateCallbackDone`, not `finished`. `onResolved`, `onRendered`, and the `navigate` promise fire while the browser animation may still be running.
|
|
134
|
+
- The router does not expose the `ViewTransition` object. Either keep GSAP off the elements the transition animates so the intro can start at mount, or install a thin wrapper around `document.startViewTransition` in the client entry that remembers the active transition, and await its `finished` before the intro.
|
|
135
|
+
- One engine per element per transition. A named morph and a GSAP tween on the same node fight, and a GSAP end state becomes the old snapshot. If the outro fades content the browser will morph, leave the shared element lit at end state or skip the view transition for that navigation.
|
|
136
|
+
- Name only elements that morph, per page, and clear names after each transition. Name chrome to hold it still.
|
|
137
|
+
- Compute direction once, from the recorded history action or from `fromLocation.state.__TSR_index` against `toLocation.state.__TSR_index` as the router's example does, return it as a type, and read the same decision in the GSAP builders.
|
|
138
|
+
- Add `::view-transition { pointer-events: none }` so a running transition does not swallow clicks.
|
|
139
|
+
- Feature-detect `document.startViewTransition`. Every GSAP path must run when it is missing.
|
|
140
|
+
- Reduced motion covers both: zero view transition durations in CSS, return `false` from `types` under the media query, and take the GSAP reduced path.
|
|
141
|
+
|
|
142
|
+
## Cases to design for
|
|
143
|
+
|
|
144
|
+
- Navigation requested mid-intro.
|
|
145
|
+
- Two destinations clicked quickly.
|
|
146
|
+
- Back or forward with no outro, including mid-outro.
|
|
147
|
+
- A page reused with new params, and a search-param-only change.
|
|
148
|
+
- A `navigate` call or redirect that bypasses any Link wrapper.
|
|
149
|
+
- A hash-only link.
|
|
150
|
+
- A slow loader that shows the pending component.
|
|
151
|
+
- An external link and a `reloadDocument` link, which unload the document.
|
|
152
|
+
- Split text or scroll plugins that changed the DOM before cleanup.
|
|
153
|
+
- Streamed data arriving after the intro.
|
|
154
|
+
- React development double-running the controller's effects.
|
|
155
|
+
|
|
156
|
+
Each case must end on one visible, interactive page with stable layout and no stale inline styles.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Verification
|
|
2
|
+
|
|
3
|
+
Check in proportion to what changed. Do not turn a focused animation task into a full audit.
|
|
4
|
+
|
|
5
|
+
## Always
|
|
6
|
+
|
|
7
|
+
- Run the repo's type, lint, format, and test commands where they exist. Regenerate `routeTree.gen.ts` if file-based routes changed.
|
|
8
|
+
- Confirm settled content is visible, interactive, and free of leftover GSAP inline styles.
|
|
9
|
+
- Confirm timelines, triggers, listeners, plugin DOM changes, the blocker, and the history subscription are cleaned up on unmount and on a reused route's rerun.
|
|
10
|
+
- Under TanStack Start, confirm the page is readable with JavaScript disabled and with the pre-paint mark set but hydration blocked.
|
|
11
|
+
- Test reduced motion when the change has a reduced-motion branch, for GSAP and for any `viewTransition` types.
|
|
12
|
+
|
|
13
|
+
## Initially hidden content
|
|
14
|
+
|
|
15
|
+
Run the [failure verification matrix](initialization.md#failure-verification) when adding or changing hiding, preparation, or recovery. It covers disabled JavaScript, a blocked bundle after the marker, throws before/after styles and splits, stalled fonts/media, late initialization, no-flash success, reduced motion, and interruption/repeated setup. Assert text and native links, not opacity alone. Include shell/footer and intentionally hidden content.
|
|
16
|
+
|
|
17
|
+
Use this framework's [integration rules](motion-system.md#initialization-and-recovery) for rendering and navigation expectations. Measure document-load LCP separately from transitions when first-load behavior changes; report measured results and untested paths.
|
|
18
|
+
|
|
19
|
+
## Runtime changes
|
|
20
|
+
|
|
21
|
+
Check the changed lifecycle in a real browser when practical:
|
|
22
|
+
|
|
23
|
+
- Initial state is applied before reveal. Under Start, throttle the network and reload; no settled server HTML flashes before hydration.
|
|
24
|
+
- Intro ends in one settled state.
|
|
25
|
+
- Outro keeps the node mounted until completion runs, and the blocked navigation proceeds only then.
|
|
26
|
+
- Rapid or interrupted input ends in one coherent state, with no blocker promise left pending.
|
|
27
|
+
- Layout boxes do not jump.
|
|
28
|
+
|
|
29
|
+
For route navigation, test the paths the change affects: an ordinary internal link, back and forward, a rapid double navigation, a same-route param change, a search-param-only change, a `navigate` call, a slow loader that shows the pending component, and a reload. Confirm URL, visible route, focus, history, and scroll agree, and that `status` returns to `idle`.
|
|
30
|
+
|
|
31
|
+
For a reused route, the returning lifecycle must run initial state and intro on its preserved DOM with no doubled tweens, and scroll triggers must measure correctly after the new data renders.
|
|
32
|
+
|
|
33
|
+
When both `viewTransition` and GSAP are involved, confirm no element is animated by both and that clicks land during a running transition.
|
|
34
|
+
|
|
35
|
+
For conditional components, test show, hide, and one interruption. Confirm unmount happens after the outro.
|
|
36
|
+
|
|
37
|
+
## Builds and wider checks
|
|
38
|
+
|
|
39
|
+
Run a production build, and `vite preview` or the Start server, for changes to routes, the router options, the Vite or Start config, dependencies, the root document shell, or anything release-facing; the dev server hydrates differently from the built output and React development runs effects twice. Run wider browser, accessibility, responsive, streaming, and performance checks only when the change touches them or the user asks for a full audit.
|
|
40
|
+
|
|
41
|
+
Report which checks ran and which could not. Do not claim runtime behavior was verified when only static review was possible.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gsap-timeline
|
|
3
|
+
description: Official GSAP skill for timelines , gsap.timeline(), position parameter, nesting, playback. Use when sequencing animations, choreographing keyframes, or when the user asks about animation sequencing, timelines, or animation order (in GSAP or when recommending a library that supports timelines).
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# GSAP Timeline
|
|
8
|
+
|
|
9
|
+
## When to Use This Skill
|
|
10
|
+
|
|
11
|
+
Apply when building multi-step animations, coordinating several tweens in sequence or parallel, or when the user asks about timelines, sequencing, or keyframe-style animation in GSAP.
|
|
12
|
+
|
|
13
|
+
**Related skills:** For single tweens and eases use **gsap-core**; for scroll-driven timelines use **gsap-scrolltrigger**; for React use **gsap-react**.
|
|
14
|
+
|
|
15
|
+
## Creating a Timeline
|
|
16
|
+
|
|
17
|
+
```javascript
|
|
18
|
+
const tl = gsap.timeline();
|
|
19
|
+
tl.to(".a", { x: 100, duration: 1 })
|
|
20
|
+
.to(".b", { y: 50, duration: 0.5 })
|
|
21
|
+
.to(".c", { opacity: 0, duration: 0.3 });
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
By default, tweens are **appended** one after another. Use the **position parameter** to place tweens at specific times or relative to other tweens.
|
|
25
|
+
|
|
26
|
+
## Position Parameter
|
|
27
|
+
|
|
28
|
+
Third argument (or position property in vars) controls placement:
|
|
29
|
+
|
|
30
|
+
- **Absolute**: `1` , start at 1 second.
|
|
31
|
+
- **Relative (default)**: `"+=0.5"` , 0.5s after end; `"-=0.2"` , 0.2s before end.
|
|
32
|
+
- **Label**: `"labelName"` , at that label; `"labelName+=0.3"` , 0.3s after label.
|
|
33
|
+
- **Placement**: `"<"` , start when recently-added animation starts; `">"` , start when recently-added animation ends (default); `"<0.2"` , 0.2s after recently-added animation start.
|
|
34
|
+
|
|
35
|
+
Examples:
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
tl.to(".a", { x: 100 }, 0); // at 0
|
|
39
|
+
tl.to(".b", { y: 50 }, "+=0.5"); // 0.5s after last end
|
|
40
|
+
tl.to(".c", { opacity: 0 }, "<"); // same start as previous
|
|
41
|
+
tl.to(".d", { scale: 2 }, "<0.2"); // 0.2s after previous start
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Timeline Defaults
|
|
45
|
+
|
|
46
|
+
Pass defaults into the timeline so all child tweens inherit:
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
const tl = gsap.timeline({ defaults: { duration: 0.5, ease: "power2.out" } });
|
|
50
|
+
tl.to(".a", { x: 100 }).to(".b", { y: 50 }); // both use 0.5s and power2.out
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Timeline Options (constructor)
|
|
54
|
+
|
|
55
|
+
- **paused: true** , create paused; call `.play()` to start.
|
|
56
|
+
- **repeat**, **yoyo** , same as tweens; apply to whole timeline.
|
|
57
|
+
- **onComplete**, **onStart**, **onUpdate** , timeline-level callbacks.
|
|
58
|
+
- **defaults** , vars merged into every child tween.
|
|
59
|
+
|
|
60
|
+
## Labels
|
|
61
|
+
|
|
62
|
+
Add and use labels for readable, maintainable sequencing:
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
tl.addLabel("intro", 0);
|
|
66
|
+
tl.to(".a", { x: 100 }, "intro");
|
|
67
|
+
tl.addLabel("outro", "+=0.5");
|
|
68
|
+
tl.to(".b", { opacity: 0 }, "outro");
|
|
69
|
+
tl.play("outro"); // start from "outro"
|
|
70
|
+
tl.tweenFromTo("intro", "outro"); // pauses the timeline and returns a new Tween that animates the timeline's playhead from intro to outro with no ease.
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Nesting Timelines
|
|
74
|
+
|
|
75
|
+
Timelines can contain other timelines.
|
|
76
|
+
|
|
77
|
+
```javascript
|
|
78
|
+
const master = gsap.timeline();
|
|
79
|
+
const child = gsap.timeline();
|
|
80
|
+
child.to(".a", { x: 100 }).to(".b", { y: 50 });
|
|
81
|
+
master.add(child, 0);
|
|
82
|
+
master.to(".c", { opacity: 0 }, "+=0.2");
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Controlling Playback
|
|
86
|
+
|
|
87
|
+
- **tl.play()** / **tl.pause()**
|
|
88
|
+
- **tl.reverse()** / **tl.progress(1)** then **tl.reverse()**
|
|
89
|
+
- **tl.restart()** , from start.
|
|
90
|
+
- **tl.time(2)** , seek to 2 seconds.
|
|
91
|
+
- **tl.progress(0.5)** , seek to 50%.
|
|
92
|
+
- **tl.kill()** , kill timeline and (by default) its children.
|
|
93
|
+
|
|
94
|
+
## Official GSAP Best practices
|
|
95
|
+
|
|
96
|
+
- ✅ Prefer timelines for sequencing
|
|
97
|
+
- ✅ Use the **position parameter** (third argument) to place tweens at specific times or relative to labels.
|
|
98
|
+
- ✅ Add **labels** with `addLabel()` for readable, maintainable sequencing.
|
|
99
|
+
- ✅ Pass **defaults** into the timeline constructor so child tweens inherit duration, ease, etc.
|
|
100
|
+
- ✅ Put ScrollTrigger on the timeline (or top-level tween), not on tweens inside a timeline.
|
|
101
|
+
|
|
102
|
+
## Do Not
|
|
103
|
+
|
|
104
|
+
- ❌ Chain animations with **delay** when a **timeline** can sequence them; prefer `gsap.timeline()` and the position parameter for multi-step animation.
|
|
105
|
+
- ❌ Forget to pass **defaults** (e.g. `defaults: { duration: 0.5, ease: "power2.out" }`) when many child tweens share the same duration or ease.
|
|
106
|
+
- ❌ Forget that **duration** on the timeline constructor is not the same as tween duration; timeline “duration” is determined by its children.
|
|
107
|
+
- ❌ Nest animations that contain a ScrollTrigger; ScrollTriggers should only be on top-level Tweens/Timelines.
|