Skip to content

[Bug]: headless renderTooltip silently discards state.arrowClassName #36650

Description

Component

Tooltip

Package version

@fluentui/react-headless-components-preview 0.2.5

React version

18.3.1

Environment

node v22.12.0
@fluentui/react-headless-components-preview 0.2.5

Current Behavior

components/Tooltip/renderTooltip.tsx:19 renders the arrow element as:

<div ref={state.arrowRef} data-arrow="" />

with no className. arrowClassName is nonetheless public state:

  • @fluentui/react-tooltip's Tooltip.types.ts:153 declares it;
  • its published react-tooltip.api.md:61 carries it;
  • Griffel's own renderTooltip.tsx:21 applies it;
  • useTooltipStyles.styles.ts:73 is what sets it.

The headless copy of the renderer simply omits it. A consumer or styling layer that sets
state.arrowClassName has the value silently discarded — no error, no warning, no console
message, just an unstyled arrow.

Expected Behavior

renderTooltip applies state.arrowClassName to the arrow element, as the Griffel renderer it was
copied from does and as the published type contract promises.

Reproduction

Set state.arrowClassName from a custom styles hook (or any wrapper that mutates tooltip state)
and inspect the rendered [data-arrow] element: the class is absent from the DOM while present in
state.

Steps to reproduce

  1. Wrap useTooltip and assign state.arrowClassName = 'my-arrow'.
  2. Render the tooltip and open it.
  3. Inspect the [data-arrow] element — it has no class attribute.

Discovery context

Found during pixel-level verification of a styling layer built over
@fluentui/react-headless-components-preview: the tooltip arrow rendered unstyled, and the class
was present in state but absent from the DOM. Because the field is declared, published, and applied
by the Griffel renderer, the omission reads as a transcription slip in the headless copy rather than
a deliberate narrowing — but it is worth a maintainer confirming that, since the alternative
(dropping arrowClassName from the headless surface entirely) would be an equally coherent
resolution and is the one decision only the team can make.

Proposed fix

Apply the field:

<div ref={state.arrowRef} className={state.arrowClassName} data-arrow="" />

One line. Additive to nothing and breaking nothing — the field was previously inert, so no existing
render output changes unless a consumer was already setting a value that was being thrown away.

A working implementation is included in PR #[WINDMOD-PR-NUMBER] (commit a2f2bc30ba); happy to
split it into a standalone PR against this issue.

Suggested severity

Medium - Has workaround (a consumer can style the arrow through [data-arrow] instead, which is
what the discarded class was competing with).

Are you willing to submit a PR to fix?

yes

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions