Skip to content

DateSegment is not always associated with the field label #9675

@beckerei

Description

@beckerei

Provide a general summary of the issue here

We experience quite a few flaky e2e tests at the moment, resulting from Playwright not finding certain elements.

They can be reproduced by running them multiple times, it's hard to reproduce them in isolation.

We use our own componets on react-aria-components, using SSR/streaming with nextjs.

🤔 Expected Behavior?

DateSegements are correctly associated via aria-labelledby to the id of the Field label.

😯 Current Behavior

Sometimes the field label has a different id as the one referenced within the DateSegements.

I took two dom snapshots from the component and strip the classnames etc from them.

Working
You can see the id react-aria-_R_4eqlubsnubsnql9fivbH4_ is from the label and referenced 5 times including all segments.

<div data-rac="">
   <span id="react-aria-_R_4eqlubsnubsnql9fivbH4_">Label</span>
   <div data-react-aria-pressable="true" id="react-aria-_R_4eqlubsnubsnql9fivbH3_" aria-labelledby="react-aria-_R_4eqlubsnubsnql9fivbH4_" role="group" data-rac="">
      <div>
         <div id="react-aria-_R_4eqlubsnubsnql9fivbH2_" role="presentation" data-react-aria-pressable="true" style="unicode-bidi:isolate" data-rac=""><span role="spinbutton" aria-valuenow="1" aria-valuetext="Empty" aria-valuemin="1" aria-valuemax="12" id="react-aria-_R_2qkseqlubsnubsnql9fivb_" aria-label="month, " aria-labelledby="react-aria-_R_2qkseqlubsnubsnql9fivb_ react-aria-_R_4eqlubsnubsnql9fivbH4_" data-placeholder="true" contenteditable="true" spellcheck="false" autocorrect="off" enterkeyhint="next" inputmode="numeric" tabindex="0" style="caret-color:transparent" data-rac="" data-type="month">mm</span><span aria-hidden="true" class="" data-rac="" data-type="literal">/</span><span __playwright_target__="call@412" role="spinbutton" aria-valuenow="1" aria-valuetext="Empty" aria-valuemin="1" aria-valuemax="31" id="react-aria-_R_6qkseqlubsnubsnql9fivb_" aria-label="day, " aria-labelledby="react-aria-_R_6qkseqlubsnubsnql9fivb_ react-aria-_R_4eqlubsnubsnql9fivbH4_" data-placeholder="true" contenteditable="true" spellcheck="false" autocorrect="off" enterkeyhint="next" inputmode="numeric" tabindex="0" style="caret-color: transparent;" data-rac="" data-type="day">dd</span><span aria-hidden="true" class="" data-rac="" data-type="literal">/</span><span role="spinbutton" aria-valuenow="2024" aria-valuetext="Empty" aria-valuemin="1" aria-valuemax="9999" id="react-aria-_R_aqkseqlubsnubsnql9fivb_" aria-label="year, " aria-labelledby="react-aria-_R_aqkseqlubsnubsnql9fivb_ react-aria-_R_4eqlubsnubsnql9fivbH4_" data-placeholder="true" contenteditable="true" spellcheck="false" autocorrect="off" enterkeyhint="next" inputmode="numeric" tabindex="0" style="caret-color:transparent" data-rac="" data-type="year">yyyy</span></div>
         <input type="text" hidden="" class="" data-rac="" name="startDate" value="" title="">
      </div>
      <button id="react-aria-_R_4eqlubsnubsnql9fivb_" data-rac="" type="button" tabindex="0" data-react-aria-pressable="true" aria-label="Calendar" aria-labelledby="react-aria-_R_4eqlubsnubsnql9fivb_ react-aria-_R_4eqlubsnubsnql9fivbH4_" aria-haspopup="dialog" aria-expanded="false">
         icon
      </button>
   </div>
</div>

Not working

Funnily enough the same id react-aria-_R_4eqlubsnubsnql9fivbH4_ is assigned to the label, but not reference in the segments. Instead the segments are associated with id react-aria-_R_13mlfiv5viv5ul9fivbH4_ which does not exist (does also not exist in the surrounding document)

<div data-rac="">
   <span id="react-aria-_R_4eqlubsnubsnql9fivbH4_">Label</span>
   <div data-react-aria-pressable="true" id="react-aria-_R_4eqlubsnubsnql9fivbH3_" aria-labelledby="react-aria-_R_4eqlubsnubsnql9fivbH4_" role="group" data-rac="">
      <div>
         <div id="react-aria-_R_4eqlubsnubsnql9fivbH2_" role="presentation" data-react-aria-pressable="true" style="unicode-bidi:isolate" data-rac=""><span role="spinbutton" aria-valuenow="1" aria-valuetext="Empty" aria-valuemin="1" aria-valuemax="12" id="react-aria-_R_2qkseqlubsnubsnql9fivb_" aria-label="month, " aria-labelledby="react-aria-_R_ml73mlfiv5viv5ul9fivb_ react-aria-_R_13mlfiv5viv5ul9fivbH4_" data-placeholder="true" contenteditable="true" spellcheck="false" autocorrect="off" enterkeyhint="next" inputmode="numeric" tabindex="0" style="caret-color:transparent"  data-rac="" data-type="month">mm</span><span aria-hidden="true" class="" data-rac="" data-type="literal">/</span><span role="spinbutton" aria-valuenow="1" aria-valuetext="Empty" aria-valuemin="1" aria-valuemax="31" id="react-aria-_R_6qkseqlubsnubsnql9fivb_" aria-label="day, " aria-labelledby="react-aria-_R_1ml73mlfiv5viv5ul9fivb_ react-aria-_R_13mlfiv5viv5ul9fivbH4_" data-placeholder="true" contenteditable="true" spellcheck="false" autocorrect="off" enterkeyhint="next" inputmode="numeric" tabindex="0" style="caret-color:transparent" data-rac="" data-type="day">dd</span><span aria-hidden="true" class="" data-rac="" data-type="literal">/</span><span role="spinbutton" aria-valuenow="2024" aria-valuetext="Empty" aria-valuemin="1" aria-valuemax="9999" id="react-aria-_R_aqkseqlubsnubsnql9fivb_" aria-label="year, " aria-labelledby="react-aria-_R_2ml73mlfiv5viv5ul9fivb_ react-aria-_R_13mlfiv5viv5ul9fivbH4_" data-placeholder="true" contenteditable="true" spellcheck="false" autocorrect="off" enterkeyhint="next" inputmode="numeric" tabindex="0" style="caret-color:transparent" data-rac="" data-type="year">yyyy</span></div>
         <input type="text" hidden="" class="" data-rac="" name="startDate" value="" title="">
      </div>
      <button id="react-aria-_R_4eqlubsnubsnql9fivb_" data-rac="" type="button" tabindex="0" data-react-aria-pressable="true" aria-label="Calendar" aria-labelledby="react-aria-_R_4eqlubsnubsnql9fivb_ react-aria-_R_4eqlubsnubsnql9fivbH4_" aria-haspopup="dialog" aria-expanded="false">
        icon
      </button>
   </div>
</div>

💁 Possible Solution

I assume that this is a problem with the global hookData weakmap which is used to share exactly this state inside of useDateField via hookData.set. useDateSegment reads via hookData.get from this global weakmap.

But looks like the content is different. It may be related to SSR, but I can't say for sure.

I'm interested to learn why you opted for the global weakmap instead of sharing this via context which should solve the out of sync IDs.

🔦 Context

It's hard to tell if this has real world impact of this is just something that happens occasionally within our playwright tests.
I never encountered the problem whe working with our application, but I'm not an impaired users - so not relying on aria associations. The average user will not notice the problem

🖥️ Steps to Reproduce

Hard to isolate the problem.

Version

react-aria-components@1.15.0

What browsers are you seeing the problem on?

Chrome

If other, please specify.

Chromium/Playwright

What operating system are you using?

MacOS, Ubuntu (CI)

🧢 Your Company/Team

No response

🕷 Tracking Issue

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions