Skip to content

Feat/2.0.0 - #1

Merged
scottcanoni merged 3 commits into
mainfrom
feat/2.0.0
Sep 14, 2026
Merged

scottcanoni merged 3 commits into
mainfrom
feat/2.0.0

Conversation

@scottcanoni

Copy link
Copy Markdown
Owner

No description provided.

scottcanoni and others added 3 commits September 13, 2026 22:34
This package was in worse shape than its sibling. All twelve defects fixed in
react-anagram-animation 2.0.0 were present here too, plus four of its own.

BREAKING CHANGE: the stylesheet is gone, class names are namespaced, deep
imports no longer resolve, main moved to dist/index.cjs, the browser floor
rose to ~Chrome 80 / Safari 13.1, and the animation genuinely looks different
because v1 was positioning letters in the wrong coordinate space.

Unique to this package
- Positioning used getBoundingClientRect().x, a VIEWPORT-relative coordinate,
  assigned to the `left` of an absolutely positioned element whose containing
  block is the component. Any instance not flush against the left edge of the
  window was offset by its own inset, and everything drifted with horizontal
  page scroll. Now uses offsetLeft/offsetTop, which were already being
  measured and then thrown away.
- `top` was never assigned at all, although the transition string listed it
  and offsetTop was measured. Wrapped phrases collapsed onto one line.
- The element had no width or height: every layer was absolutely positioned,
  so it collapsed to zero and overlapped whatever followed. The three layers
  now share a single CSS grid cell sized by the longer phrase.
- opacity was set but was not in the transition list, so the appear/disappear
  fade - the entire reason this package exists apart from its sibling -
  popped instantly.
- The glyph swap was hardcoded at 500ms instead of transitionDuration / 2. At
  the documented transitionDuration: 4000 a letter changed identity 3.5s
  before it arrived.
- Loader rebuilt the `words` array literal on every render and the child
  depended on it, so the effect restarted unconditionally on every render and
  consumer memoisation could not help. The child now takes two string props.

Shared with the sibling
- Timer cleanup, so the loop no longer outlives unmount and StrictMode no
  longer leaves two out-of-phase animations. This package schedules four
  timers per letter, so it leaked twice as fast.
- createRef removal, useLayoutEffect measurement, ResizeObserver re-measure,
  prefers-reduced-motion, aria-hidden on the measurement words, graceful
  degradation instead of throwing, and the useFonts rewrite.
- Vite dual ESM+CJS build, exports map, hand-written types, zero runtime
  dependencies (core-js and Babel gone), ESLint 9 flat config, LICENSE,
  CI running lint/typecheck/test/build, Pages deploy, npm provenance.
- className is merged rather than replacing the component's own class.

Verification
- 19 tests. Every fix was mutation-tested: reverted individually, and each
  time the matching test caught it.
- In a real browser: an indented instance renders its letters inside its own
  box (the v1 bug put them outside), a 380px-wide container wraps the phrase
  and letters animate between two lines, the fade is observed, and 13
  distinct animation states appear over one cycle with no console errors.
- require() and import() of the built output both succeed under plain Node,
  which is what makes it usable in SSR and RSC.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Replaces the tag-triggered workflow with one that runs on every push to main
but only publishes when package.json carries a version npm has not seen.
Without that guard every README fix would attempt a publish and fail with
"cannot publish over previously published version".

Authentication is Trusted Publishing over OIDC rather than a stored token, so
there is no npm credential in this repository to leak, rotate, or silently
expire. Provenance comes for free with it.

Node 22 ships npm 10.x and Trusted Publishing needs >= 11.5.1, hence the
explicit npm upgrade step. A concurrency group prevents two runs racing on an
irreversible action.

Guard verified against the live registry: 1.5.1 resolves and skips, 2.0.0 does
not resolve and publishes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Publish-on-merge couples two decisions that are separate: "this code is good"
and "ship it to the world". With it, clicking Merge on a version-bumping PR
puts the package on npm immediately, with no window to pull the built tarball
and inspect it - which is exactly the window you want for a major release.

Releasing is now `npm version <bump> && git push --follow-tags`. Merging to
main is always safe, so dependency bumps, README fixes and CI changes can land
freely without any chance of an accidental release.

`npm version` writes package.json and cuts the tag in one operation, so the
two cannot drift. A guard fails the job loudly if a hand-made tag ever
disagrees with package.json, rather than publishing a version nobody intended.

Auth is unchanged: Trusted Publishing over OIDC, no stored token.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@scottcanoni
scottcanoni merged commit a9c1c2f into main Sep 14, 2026
4 checks passed

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are so AWESOME for chipping in and helping out. Thanks! Keep up the GOOD WORK!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant