Skip to content

[DOM] Treat hidden as overloaded boolean to support hidden="until-found"#35784

Open
veeceey wants to merge 1 commit intofacebook:mainfrom
veeceey:fix/hidden-until-found-support
Open

[DOM] Treat hidden as overloaded boolean to support hidden="until-found"#35784
veeceey wants to merge 1 commit intofacebook:mainfrom
veeceey:fix/hidden-until-found-support

Conversation

@veeceey
Copy link

@veeceey veeceey commented Feb 15, 2026

Summary

The hidden HTML attribute was being treated as a plain boolean in React's DOM handling. This meant that any truthy value (including strings like "until-found") was always coerced to an empty string attribute (hidden=""). This prevented using the hidden="until-found" feature that enables content to be searchable by the browser's find-in-page while remaining visually hidden.

This PR reclassifies hidden from a boolean attribute to an overloaded boolean (same category as capture and download), so that:

  • hidden={true} renders hidden="" (unchanged)
  • hidden={false} removes the attribute (unchanged)
  • hidden="until-found" now correctly renders hidden="until-found"

The hidden="until-found" value is now supported across all major browsers:

  • Chrome 102+ (June 2022)
  • Firefox 139+ (June 2025)
  • Safari 26.2+ (December 2025)
  • Part of Interop 2025 targets

Changes:

  • Client-side rendering (ReactDOMComponent.js): moved hidden from the boolean to the overloaded boolean switch case in both setProp and diffHydratedGenericElement
  • Server-side rendering (ReactFizzConfigDOM.js): moved hidden from boolean to overloaded boolean in pushAttribute, updated writeStyleResourceAttributeInJS and writeStyleResourceAttributeInAttr to preserve string values
  • Validation (ReactDOMUnknownPropertyHook.js): removed hidden from the boolean warning list so string values don't trigger false warnings
  • Flow types (ReactFiberConfigDOM.js): updated hidden type from boolean to boolean | string

How did you test this change?

Ran the full test suites for all affected test files:

  • ReactDOMComponent-test.js - 167 passed
  • ReactDOMServerIntegrationAttributes-test.js - 555 passed
  • ReactDOMFizzServer-test.js - 156 passed

Added new tests verifying hidden={true}, hidden={false}, and hidden="until-found" behavior for both client and server rendering.

Fixes #24740

…found"

The hidden attribute was treated as a plain boolean, which meant any
truthy value was coerced to an empty string. This prevented using the
hidden="until-found" value that is now supported in all major browsers
(Chrome 102+, Firefox 139+, Safari 26.2+).

Move hidden from the boolean attribute list to the overloaded boolean
list (alongside capture and download), so that:
- hidden={true} renders as hidden=""
- hidden={false} removes the attribute
- hidden="until-found" renders as hidden="until-found"

Fixes facebook#24740
@meta-cla
Copy link

meta-cla bot commented Feb 15, 2026

Hi @veeceey!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

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.

Bug: hidden attribute does not accept string values

1 participant