Skip to content

[eslint-plugin] Animation shorthand expansion#1538

Merged
abhakat merged 4 commits intomainfrom
animation-shorthand-expansion
Mar 23, 2026
Merged

[eslint-plugin] Animation shorthand expansion#1538
abhakat merged 4 commits intomainfrom
animation-shorthand-expansion

Conversation

@abhakat
Copy link
Copy Markdown
Contributor

@abhakat abhakat commented Mar 20, 2026

What changed / motivation ?

Added animation shorthand expansion to stylex-valid-shorthands following the same createSpecificTransformer pattern used by existing shorthand expanders.

This change makes the rule report and autofix animation shorthand values into longhands for supported single-animation inputs.

Changes:

  • Added animation: createSpecificTransformer('animation') to shorthand aliases.
  • Added expandAnimationShorthand() in splitShorthands.js to parse and expand:
    • animationDuration
    • animationTimingFunction
    • animationDelay
    • animationIterationCount
    • animationDirection
    • animationFillMode
    • animationPlayState
    • animationName
  • Added animation dispatch in splitSpecificShorthands.
  • Added robust test coverage for common and edge shorthand forms.

Supported behavior:

  • Duration/name (slidein 3s)
  • Timing functions (ease-in, cubic-bezier(...), steps(...), linear(...))
  • Delay (slidein 3s 1s)
  • Iteration count including pre-duration order (2 3s slidein)
  • Direction / fill-mode / play-state keywords
  • !important propagation to expanded longhands
  • Multi-animation lists (comma-separated) are detected and returned as CANNOT_FIX

Safest semantic handling for ambiguous none:

  • animation: '1s none' expands to both:
    • animationFillMode: 'none'
    • animationName: 'none'
  • This preserves semantics for the ambiguous shorthand case.
  • animation: 'fadein 1s none' expands to:
    • animationDuration: '1s'
    • animationFillMode: 'none'
    • animationName: 'fadein'

Motivation:

  • Bring animation shorthand handling in line with existing shorthand autofix behavior.
  • Reduce manual migration effort from shorthand to StyleX-preferred longhands.
  • Keep autofix safe by avoiding multi-animation list rewrites and preserving ambiguous none semantics.

Linked PR/Issues

N/A

Additional Context

Example autofix:

  • Input: animation: '3s ease-in 1s 2 reverse both paused slidein'
  • Output:
    • animationDuration: '3s'
    • animationTimingFunction: 'ease-in'
    • animationDelay: '1s'
    • animationIterationCount: '2'
    • animationDirection: 'reverse'
    • animationFillMode: 'both'
    • animationPlayState: 'paused'
    • animationName: 'slidein'

Tests:

  • npx jest --watchman=false --coverage=false stylex-valid-shorthands-test.js
  • Result on this branch: PASS (95 passed, 0 failed)

Screenshots:

  • N/A (ESLint rule + autofix behavior change)

Pre-flight checklist

@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
stylex Skipped Skipped Mar 23, 2026 5:20pm

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Mar 20, 2026
@abhakat abhakat changed the title Animation shorthand expansion [eslint-plugin] Animation shorthand expansion Mar 20, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 20, 2026

workflow: benchmarks/perf

Comparison of performance test results, measured in operations per second. Larger is better.
yarn workspace v1.22.22
yarn run v1.22.22
$ node ./compare.js /tmp/tmp.aCTlxCgY8V /tmp/tmp.R64Lg0Oa6K

Results Base Patch Ratio
babel-plugin: stylex.create
· basic create 556 542 0.97 -
· complex create 66 67 1.02 +
babel-plugin: stylex.createTheme
· basic themes 417 423 1.01 +
· complex themes 33 34 1.03 +
Done in 0.07s.
Done in 0.30s.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 20, 2026

workflow: benchmarks/size

Comparison of minified (terser) and compressed (brotli) size results, measured in bytes. Smaller is better.
yarn workspace v1.22.22
yarn run v1.22.22
$ node ./compare.js /tmp/tmp.9Rysw5SNwk /tmp/tmp.cHVJ3CcrXU

Results Base Patch Ratio
@stylexjs/stylex/lib/cjs/stylex.js
· compressed 1,447 1,447 1.00
· minified 4,558 4,558 1.00
@stylexjs/stylex/lib/cjs/inject.js
· compressed 1,793 1,793 1.00
· minified 4,915 4,915 1.00
benchmarks/size/.build/bundle.js
· compressed 496,650 496,650 1.00
· minified 4,847,840 4,847,840 1.00
benchmarks/size/.build/stylex.css
· compressed 99,653 99,653 1.00
· minified 747,850 747,850 1.00
Done in 0.08s.
Done in 0.33s.

Comment thread packages/@stylexjs/eslint-plugin/__tests__/stylex-valid-shorthands-test.js Outdated
Anay Bhakat added 4 commits March 23, 2026 10:19
…rthands

Add animation shorthand expansion following the createSpecificTransformer
pattern. The rule now reports an error and autofixes when users write
`animation: 'slidein 3s ease-in'` instead of the expanded longhands.

Handles all CSS spec cases:
- Duration and delay (first time = duration, second = delay)
- Timing functions: keywords (ease, linear, etc.) and functions
  (cubic-bezier(), steps())
- Iteration count: number or infinite
- Direction: normal, reverse, alternate, alternate-reverse
- Fill mode: forwards, backwards, both
- Play state: running, paused
- Animation name: any unclassified identifier
- Comma-separated multi-animation returns CANNOT_FIX
- !important support
@abhakat abhakat force-pushed the animation-shorthand-expansion branch from 557f0fd to 7d92306 Compare March 23, 2026 17:20
@abhakat abhakat merged commit 139e9bf into main Mar 23, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants