-
Notifications
You must be signed in to change notification settings - Fork 4.7k
ValidatedToggleControl: Fix validation timing with callback ref #75095
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
ValidatedToggleControl: Fix validation timing with callback ref #75095
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
Size Change: +15 B (0%) Total Size: 3 MB
ℹ️ View Unchanged
|
aduth
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we add some test coverage for the bug?
| const validityTargetRef = useRef< HTMLInputElement >( null ); | ||
| const mergedRefs = useMergeRefs( [ forwardedRef, validityTargetRef ] ); | ||
|
|
||
| const validityTargetRef = useRef< HTMLInputElement | null >( null ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the reason for this change? And similarly in the setRequiredRef argument typings below, would it ever actually be passed null, or could it be HTMLInputElement ?
| }, [ required ] ); | ||
| // so we need to set it manually. Using a callback ref ensures `required` is set | ||
| // synchronously when the element mounts, before any validation effects run. | ||
| const setRequiredRef = useCallback( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be a useCallback, or could it just be a plain function?
What?
Closes: #72321
This PR implements the last item of the linked issue around DataForms layout validation.
Why?
ValidatedToggleControlwas setting the required attribute on the underlying input via a useEffect. WhenreportValidity()was called (e.g., when a card form expands), the effect hadn't run yet, so the input didn't have therequiredattribute. Withoutrequired, an unchecked checkbox is considered valid by the browser, so no invalid event fired and no error indicator/message appeared.How?
Replace the useEffect with a callback ref. The callback ref sets required synchronously when the element mounts, ensuring it's in place before any validation effects run.
Possible alternative approach
We could make
ToggleControlpass rest props down toFormToggle(similar toTextControletc..). This would allowrequiredto flow through naturally via ControlWithError's cloneElement. Should we implement that? --cc @WordPress/gutenberg-componentsTesting Instructions
?path=/story/dataviews-dataform--validation&args=layout:card-collapsible) compare trunk and this PR (npm run storybook:dev) by going toBoolean fieldsand collapse the card2 validation issuesbadge, but when opening the card again you can see both validation messages at the inputs, only in this PR (see the videos below).Before
Screen.Recording.2026-01-30.at.5.08.05.PM.mov
After
Screen.Recording.2026-01-30.at.5.06.48.PM.mov