4.8 KiB
4.8 KiB
Status
Draft
Story
As a storyteller, I want a sticky split component, so that narrative and media synchronize during scroll.
Acceptance Criteria
- <StickySplit.Section/Sticky/Track/Panel> components implemented with docs.
- Reduced‑motion mode disables heavy animations gracefully.
- Mobile layout stacks content; performance budget respected.
Tasks / Subtasks
- Scaffold pattern components (AC: 1)
- Create folder
src/components/patterns/sticky-split/ - Add files:
Section.tsx,Sticky.tsx,Track.tsx,Panel.tsx,index.ts - Export namespaced API:
StickySplit = { Section, Sticky, Track, Panel } - Define props:
- Section:
{ id: string; height?: string | number; side?: 'left'|'right'; className?: string } - Sticky:
{ offset?: string; className?: string } - Track:
{ className?: string } - Panel:
{ index: number; inVariants?: Variants; outVariants?: Variants; className?: string }
- Section:
- Provide sensible defaults:
height='200vh',side='left', stickyoffset='var(--sticky-top, 8vh)'
- Create folder
- Progress computation (AC: 1)
- Implement
useSectionProgress(id)insrc/components/patterns/sticky-split/useSectionProgress.ts - Use
IntersectionObserveron Section root to compute 0..1 progress across its scroll range - Ensure passive listeners only; no wheel/touch blocking; avoid scroll‑jacking
- Implement
- Animation integration (AC: 1)
- Use
framer-motionmotion.divinsidePaneland mapprogressto opacity/transform viauseTransform - Add optional
inVariants/outVariantsprops; default to subtle fade/scale
- Use
- Reduced motion (AC: 2)
- Use
useReducedMotion()from framer‑motion; if true, disable transforms and show panels as static stack
- Use
- Mobile layout + fallbacks (AC: 3)
- Apply responsive CSS: below
md, stack vertically; disable sticky; panels visible with light reveal‑on‑view (IO add/removeis-visibleclass) - Above
md, two‑column grid with left sticky narrative and right scroll track; allowside='right'to invert
- Apply responsive CSS: below
- Tokens and base styles (AC: 1,3)
- Define CSS vars in
src/app/globals.css:--sticky-top,--panel-gap,--reveal-duration,--reveal-ease - Provide utility classes for the pattern container grid and gaps using Tailwind + CSS vars
- Define CSS vars in
- Documentation & example (AC: 1)
- Add
src/components/patterns/sticky-split/README.mdwith usage, props, and examples - Include a small demo component
Demo.tsxshowcasing 3 panels; do not add a new route in this story
- Add
- Quality gates & perf
- Lint passes:
npm run lint - Build passes:
npm run build - Verify no main thread jank on mid‑range device; keep frame budget ≈16ms for panel transitions
- Confirm passive listeners; no prevention of native scroll
- Lint passes:
Dev Notes
- Context
- Derived from PRD Story 1.3. Target: reusable pattern inspired by “Basement Foundry” style; no scroll‑jacking.
- Typography and tokens are handled in Story 1.1; this story may add a few CSS vars specific to the pattern.
- Relevant Source Tree
- Component home:
src/components/patterns/sticky-split/* - Tailwind/CSS tokens:
src/app/globals.css,tailwind.config.ts - Motion libs:
framer-motion/motionavailable in dependencies.
- Component home:
- Implementation Guidance
- Section renders a responsive two‑column grid (
md:grid md:grid-cols-2) with a fixed sticky column and a scrolling track column; swap order withside. - Sticky uses
position: sticky; top: var(--sticky-top)and inherits tokenized spacing/gap via CSS vars. - Track holds
Panelchildren; each Panel uses the section progress (or per‑panel thresholds likeindex / (N-1)) to compute in/out. - Reduced motion: early return static markup; prefer opacity reveals without transforms.
- Accessibility: preserve DOM order for reading; keep focusable content reachable; avoid trapping focus.
- Performance: avoid large fixed layers; prefer
will-change: transformonly while animating; lazy‑load media inside panels.
- Section renders a responsive two‑column grid (
Testing
- Manual
- With default motion: panels fade/transform smoothly as the section scrolls; no scroll blocking.
- With
prefers-reduced-motion: panels render as static stack; no transforms/animations. - Mobile: stacked layout; sticky disabled; content readable and navigable.
- Perf
- Inspect Chrome Performance or DevTools frame rate timeline; verify transitions stay near 60fps on typical hardware.
- A11y
- Keyboard navigation reaches all interactive elements inside Sticky and Track; focus order logical.
Change Log
| Date | Version | Description | Author |
|---|---|---|---|
| 2025-09-24 | v1 | Initial draft from PRD Story 1.3 | Scrum Master |
Dev Agent Record
Agent Model Used
{{agent_model_name_version}}
Debug Log References
Completion Notes List
File List
QA Results