Skip to content

Conversation

@robertpenner
Copy link
Collaborator

@robertpenner robertpenner commented Jan 16, 2026

This pull request completes the migration of calendar animations from legacy CSS keyframe animations to Fluent UI v9 motion components in the @fluentui/react-calendar-compat package. The main focus is on replacing slide and fade animations in the calendar with reusable motion components, improving maintainability and consistency with Fluent UI v9 standards. All related CSS animations and constants have been removed or deprecated, and the necessary dependencies have been added.

Calendar Animation Migration

  • Migrated all calendar slide and fade animations from CSS to motion components (DirectionalSlide, HeaderFade), including day, month, and year views.
  • Removed CSS animation styles and constants from style files and marked all animation constants in animations.ts as @deprecated for backwards compatibility.

Component Refactoring

  • Updated CalendarGridRow to use React.forwardRef to support motion component refs and maintain accessibility.

Dependency Updates

  • Added @fluentui/react-motion and @fluentui/react-motion-components-preview as dependencies to support new motion components.

Package and Documentation Updates

  • Added a detailed migration plan in MOTION_MIGRATION_PLAN.md documenting the phases, completed work, and validation tasks for the motion migration.
  • Added change files for tracking the patch and minor updates to the relevant packages.

- Copied from MessageBarGroup.motions.tsx for now
- Simplified document to reflect completed Phase 1 (slide animations)
- Documented Phase 2 remaining work (CalendarPicker button rows and header fade animations)
- Clarified migration status with table of completed vs remaining CSS animations
- Updated file status table to show Phase 1 completion
- Added specific migration approach for Phase 2 tasks
- Use motionTokens.durationSlower (400ms) instead of hardcoded 367ms
- Rename fromX/fromY props to outX/outY to match Slide.In API
- Simplify distance calculation logic
- Add JSDoc comment explaining duration token choice
- Change from FunctionComponent to forwardRef to enable ref support
- Required for motion components to properly animate table rows
- Add displayName for better debugging
…Slide

- Remove unnecessary <div> wrappers inside DirectionalSlide components
- CalendarGridRow now accepts refs directly via forwardRef
- Fixes invalid DOM nesting (div inside tbody)
- Maintains slide animation functionality
…endarDayGrid

- Remove CSS keyframe animations for row sliding (now handled by DirectionalSlide)
- Remove unused imports (SLIDE_*, DURATION_3, EASING_FUNCTION_1, TRANSITION_ROW_DISAPPEARANCE)
- Remove animation-related style classes from weekRow, firstTransitionWeek, lastTransitionWeek
- Remove animateBackwards and animationDirection logic from style application
- Add comments explaining migration to motion components
- Keeps FADE_IN, DURATION_2, EASING_FUNCTION_2 for header animations (not yet migrated)
- Convert DURATION_* from string seconds to millisecond numbers using motion tokens
- Update comments to clarify which animations still use CSS vs motion components
- Document that DURATION_3 is no longer used (slide animations now use motion)
- Note that EASING_FUNCTION_2 has no exact motion token equivalent
- Add @fluentui/react-motion ^9.11.5
- Add @fluentui/react-motion-components-preview ^0.14.2
- Required for DirectionalSlide motion component
…arGridRow

Required for server-side rendering compatibility with React.forwardRef
…d rows

- Wrap year picker rows with DirectionalSlide motion component
- Consistent animation behavior with CalendarMonth button rows
- Part of Phase 2 motion migration
…endarPicker

- Remove CSS keyframe animations for button row sliding
- Now handled by DirectionalSlide motion component in CalendarMonth/CalendarYear
- Remove unused imports (SLIDE_*, DURATION_3, EASING_FUNCTION_1)
- Keep FADE_IN, DURATION_2, EASING_FUNCTION_2 for header fade animation
…eprecated

- Reorganize animations.ts with used vs deprecated sections
- Add @deprecated JSDoc tags to unused animation constants
- Add eslint-disable for deprecated re-exports in index.ts
- Keep FADE_IN, DURATION_2, EASING_FUNCTION_2 (still used for header fade)
- Maintain backwards compatibility for external consumers
Add HeaderFade component that wraps Fade.In from react-motion-components-preview.
The component uses navigationKey prop to trigger fade animation when the value changes.

- Uses motionTokens.durationGentle (~250ms) matching original DURATION_2 (267ms)
- Replaces CSS keyframe fade animations with motion component
Replace CSS fade animation on month/year header with HeaderFade motion component.

- Add HeaderFade wrapper around monthAndYear span in CalendarDay.tsx
- Remove CSS animation imports and styles from useCalendarDayStyles.styles.ts
Replace CSS fade animation on year string header with HeaderFade motion component.

- Add HeaderFade wrapper around yearString span in CalendarMonth.tsx
Replace CSS fade animation on year range title with HeaderFade motion component.

- Add HeaderFade wrapper around year range spans in CalendarYearTitle
- Handles both clickable button and static div cases
…darPicker styles

Remove CSS fade animation from useCalendarPickerStyles.styles.ts now that header fade
is handled by HeaderFade motion component.

- Remove DURATION_2, EASING_FUNCTION_2, FADE_IN imports
- Remove animation block from useCurrentItemButtonStyles
- Remove animateBackwards destructuring (no longer used)
…mplete

Update MOTION_MIGRATION_PLAN.md to reflect completed migration:

- All CSS animations migrated to motion components
- DirectionalSlide for slide animations
- HeaderFade for header fade animations
- Animation constants marked as deprecated
- Build and tests passing
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant