Skip to content

Rename DrawCommandSpan to CanvasEffectSpan and remove UpdateAppearance (#56705)#56705

Closed
andrewdacenko wants to merge 2 commits into
facebook:mainfrom
andrewdacenko:export-D97399655
Closed

Rename DrawCommandSpan to CanvasEffectSpan and remove UpdateAppearance (#56705)#56705
andrewdacenko wants to merge 2 commits into
facebook:mainfrom
andrewdacenko:export-D97399655

Conversation

@andrewdacenko
Copy link
Copy Markdown
Contributor

@andrewdacenko andrewdacenko commented May 6, 2026

Summary:

Changelog: [Internal]

Renames DrawCommandSpan to CanvasEffectSpan for consistency with the new
AnimatedEffectSpan, and removes the UpdateAppearance interface.

UpdateAppearance is a marker interface that tells Android's text layout system
the span affects text appearance (triggering re-measurement). Since
CanvasEffectSpan only draws on top of text during PreparedLayoutTextView's
draw pass and never modifies paint state or text measurement, implementing
UpdateAppearance was incorrect — the same reasoning applied when designing
AnimatedEffectSpan without it.

Reviewed By: mdvacca

Differential Revision: D97399655

Summary:
Adds `AnimatedEffectSpan`, a new span type for animated effects drawn on top
of text in `PreparedLayoutTextView`. Unlike `DrawCommandSpan` which provides
static `onPreDraw`/`onDraw` hooks, `AnimatedEffectSpan` supports animation via
a `requestAnimationFrame`-style API where the span receives a time delta each
frame and returns whether it wants another frame.

Key design decisions:
- Independent from `DrawCommandSpan` — does not subclass it
- Extends `StatefulSpan` — animated effects hold per-view mutable state
  (e.g. particle positions) that must be cloned when layouts are shared
- Does not implement `UpdateAppearance` — animated effects don't affect text measurement or paint state
- Annotated `UnstableReactNativeAPI` — callers must opt in
- Zero overhead for non-animated text: delta computation and frame scheduling only happen when animated spans exist
- Frame timing resets on visibility changes and view recycling to prevent delta spikes

Differential Revision: D97399151
@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 May 6, 2026
@facebook-github-tools facebook-github-tools Bot added p: Facebook Partner: Facebook Partner labels May 6, 2026
@meta-codesync
Copy link
Copy Markdown

meta-codesync Bot commented May 6, 2026

@andrewdacenko has exported this pull request. If you are a Meta employee, you can view the originating Diff in D97399655.

facebook#56705)

Summary:
Pull Request resolved: facebook#56705

Changelog: [Internal]

Renames `DrawCommandSpan` to `CanvasEffectSpan` for consistency with the new
`AnimatedEffectSpan`, and removes the `UpdateAppearance` interface.

`UpdateAppearance` is a marker interface that tells Android's text layout system
the span affects text appearance (triggering re-measurement). Since
`CanvasEffectSpan` only draws on top of text during `PreparedLayoutTextView`'s
draw pass and never modifies paint state or text measurement, implementing
`UpdateAppearance` was incorrect — the same reasoning applied when designing
`AnimatedEffectSpan` without it.

Reviewed By: mdvacca

Differential Revision: D97399655
@meta-codesync meta-codesync Bot changed the title Rename DrawCommandSpan to CanvasEffectSpan and remove UpdateAppearance Rename DrawCommandSpan to CanvasEffectSpan and remove UpdateAppearance (#56705) May 6, 2026
@meta-codesync meta-codesync Bot closed this in 7ae9b66 May 6, 2026
@facebook-github-tools facebook-github-tools Bot added the Merged This PR has been merged. label May 6, 2026
@react-native-bot
Copy link
Copy Markdown
Collaborator

This pull request was successfully merged by @andrewdacenko in 7ae9b66

When will my fix make it into a release? | How to file a pick request?

@meta-codesync
Copy link
Copy Markdown

meta-codesync Bot commented May 6, 2026

This pull request has been merged in 7ae9b66.

quantizor added a commit to quantizor/react-native that referenced this pull request May 11, 2026
Three CI breakages were introduced by changes that landed on `main`
between the original PR push and now:

1. PR facebook#56705 renamed `DrawCommandSpan` to `CanvasEffectSpan` and dropped
   the `ReactSpan` / `UpdateAppearance` interfaces from the base class.
   `ReactUnderlineSpan` and `ReactStrikethroughSpan` were extending the
   old name; rename them and re-declare `ReactSpan` so they remain
   valid `SetSpanOperation` arguments. `ReactTextView.onDraw` updated
   to import the new name.

2. Adding `Wavy` to `facebook::react::TextDecorationStyle` (this PR)
   left `RCTNSUnderlineStyleFromTextDecorationStyle` non-exhaustive,
   tripping `-Werror,-Wreturn-type` on iOS builds. Add a `Wavy` case
   that falls back to a solid underline (the actual wavy rendering
   ships in companion PR facebook#56769).

3. `validate_cxx_api_snapshots` flagged the missing `Wavy` entry in
   all six snapshots under `scripts/cxx-api/api-snapshots/`.
   Regenerate.

No behavior change beyond what was already in the feature commit; this
is purely "rebase the implementation onto current `main`."
quantizor added a commit to quantizor/react-native that referenced this pull request May 11, 2026
Upstream facebook#56705 renamed DrawCommandSpan and dropped its `ReactSpan` marker; re-add the interface on the underline/strikethrough subclasses so `SetSpanOperation` still accepts them.
quantizor added a commit to quantizor/react-native that referenced this pull request May 11, 2026
Three CI breakages were introduced by changes that landed on `main`
between the original PR push and now:

1. PR facebook#56705 renamed `DrawCommandSpan` to `CanvasEffectSpan` and dropped
   the `ReactSpan` / `UpdateAppearance` interfaces from the base class.
   `ReactUnderlineSpan` and `ReactStrikethroughSpan` were extending the
   old name; rename them and re-declare `ReactSpan` so they remain
   valid `SetSpanOperation` arguments. `ReactTextView.onDraw` updated
   to import the new name.

2. Adding `Wavy` to `facebook::react::TextDecorationStyle` (this PR)
   left `RCTNSUnderlineStyleFromTextDecorationStyle` non-exhaustive,
   tripping `-Werror,-Wreturn-type` on iOS builds. Add a `Wavy` case
   that falls back to a solid underline (the actual wavy rendering
   ships in companion PR facebook#56769).

3. `validate_cxx_api_snapshots` flagged the missing `Wavy` entry in
   all six snapshots under `scripts/cxx-api/api-snapshots/`.
   Regenerate.

No behavior change beyond what was already in the feature commit; this
is purely "rebase the implementation onto current `main`."
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. fb-exported Merged This PR has been merged. meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants