fix(components): guard styled button rgba() against React 19 defaultProps removal#23319
Conversation
|
@enricobattocchi Please be aware that following packages have been abandoned and are not actively maintained anymore:
Please consider using the other packages instead. |
Coverage Report for CI Build 0Warning No base build found for commit Coverage: 34.873%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsRequires a base build to compare against. How to fix this → Coverage Stats💛 - Coveralls |
There was a problem hiding this comment.
Pull request overview
This PR updates @yoast/components button styling to prevent React 19’s automatic JSX runtime (which no longer applies defaultProps for function/forwardRef components) from passing undefined into rgba(), which can throw and crash rendering.
Changes:
- Added
|| colors.$color_*fallbacks insidergba()interpolations forBaseButtonfocus/active/base shadows. - Added a similar
rgba()fallback forLinkButton’s box-shadow color. - Added
rgba()fallbacks forIconButtonBasepressed/unpressed box-shadow colors, plus explanatory inline comments.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| packages/components/src/buttons/Button.js | Adds rgba() fallbacks (and rationale comment) to avoid crashes when default color props become undefined under React 19 automatic runtime. |
| packages/components/src/buttons/LinkButton.js | Adds a rgba() fallback for boxShadowColor to avoid rgba(undefined) crashes. |
| packages/components/src/IconButtonBase.js | Adds rgba() fallbacks for pressed/unpressed box-shadow colors to prevent crashes when upstream defaultProps are not applied. |
b427e34 to
9ec60f9
Compare
|
@enricobattocchi Please be aware that following packages have been abandoned and are not actively maintained anymore:
Please consider using the other packages instead. |
9ec60f9 to
a7e3bbe
Compare
|
@enricobattocchi Please be aware that following packages have been abandoned and are not actively maintained anymore:
Please consider using the other packages instead. |
a7e3bbe to
58248cf
Compare
|
@enricobattocchi Please be aware that following packages have been abandoned and are not actively maintained anymore:
Please consider using the other packages instead. |
…ct 19 React 19's automatic JSX runtime no longer applies defaultProps to function/forwardRef components (styled components included). The @yoast/components styled buttons relied on defaultProps for their colours (interpolated into rgba(), which throws on undefined) and for BaseButton's type (a typeless <button> defaults to submit and can submit surrounding forms). BaseButton and LinkButton apply their defaults through a styled-components .attrs callback on the outermost style layer, so they reach every inner hover/focus/active interpolation and stay correct per component (e.g. LinkButton keeps its own activeBorderColor) on both JSX runtimes. IconButtonToggle merges its colour defaults in-component (a plain object spread) so they survive the automatic runtime and its rendered styling stays intact. defaultProps is kept on each for classic consumers. IconButtonBase is left untouched: its colours come from IconButtonToggle, its only consumer, which now always passes defined values. Adds a regression test that neutralises each component's defaultProps (mirroring the automatic runtime): BaseButton/LinkButton must still render and keep type=button, and IconButtonToggle must produce identical styled output, guarding its merged default colours against regressions. Verified on a React 19.2.4 site (Gutenberg 23.3-RC1) with all three React-19 PRs applied: the editor content-analysis eye toggles render fully styled (box-shadow rgba resolved, no parseToRgb throw) and the console is clean. Relates to Yoast/reserved-tasks#1252 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
58248cf to
aed72d1
Compare
|
@enricobattocchi Please be aware that following packages have been abandoned and are not actively maintained anymore:
Please consider using the other packages instead. |
31cc456
into
feature/fix-gutenberg-23.3
Context
React 19 (Gutenberg 23.3 / WordPress 7.1) stops applying
defaultPropsto function andforwardRefcomponents when the element is created through the automatic JSX runtime (jsx()); the classiccreateElementruntime still applies them. Several@yoast/componentsstyled buttons (Button/BaseButton,LinkButton, and theIconButtonToggleeye/highlight toggle) interpolatergba( props.<color> ), and those colours are supplied only bydefaultProps. When an automatic-runtime consumer (Free'spackages/js) renders one of these buttons, the default colours drop toundefined,rgba(undefined)throws in polished'sparseToRgb, and the surrounding subtree crashes.Verified live on a React 19.2.4 site (Gutenberg 23.3-RC1) with all three React-19 readiness PRs applied: the block-editor content-analysis "Highlight this result in the text" eye toggles (
IconButtonToggle, rendered viapackages/js'Results.js) render fully styled, with thebox-shadowrgba()resolved to a real colour and noparseToRgbthrow, and the console is clean.BaseButton/LinkButtonsurfaces (Workouts, Free admin screens) likewise render cleanly.Part of the React 19 readiness work tracked in Yoast/reserved-tasks#235.
Summary
This PR can be summarized in the following changelog entry:
Relevant technical choices:
BaseButtonandLinkButtonapply their own defaults through a styled-components.attrscallback, routed through the outermostaddBaseStylelayer so the defaults reach every inner hover/focus/active interpolation on both JSX runtimes. This keeps each button's own defaults correct on React 19 (e.g.LinkButtonkeeps its ownactiveBorderColorandBaseButtonkeepstype="button"), which a single shared fallback could not.IconButtonTogglemerges its colour defaults in-component (a plain{ ...defaults, ...props }spread) so they survive the automatic runtime and its rendered styling stays intact, rather than relying ondefaultProps.defaultPropsis kept on each component for classic-runtime consumers; the.attrs/in-component merge is what makes them safe on the automatic runtime.IconButtonBaseis intentionally left untouched: it has no defaults of its own and its colours are always passed by its only consumer,IconButtonToggle, which now supplies defined values.Test instructions
Test instructions for the acceptance test before the PR gets merged
Requires a React-19 environment (the Gutenberg 23.3+ plugin active, or WordPress 7.1) with Yoast SEO active. Test with the browser console open.
hex notation/Cannot read properties of undefinederrors. Before this fix they threw inparseToRgband crashed the analysis subtree.BaseButton/LinkButtonshould render and the console should stay clean.Relevant test scenarios
The bug is a render/console crash, only observable on a React 19 build (Gutenberg 23.3+), so test with the console open in the block editor.
Test instructions for QA when the code is in the RC
QA tests on the Gutenberg 23.3-RC1 (React 19) build, following the acceptance test steps above.
Impact check
This PR affects the following parts of the plugin, which may require extra testing:
@yoast/componentsButton/LinkButton/IconButtonTogglethrough the automatic JSX runtime (Freepackages/js: the content-analysis result toggles and the Workouts screens). No effect on React 18 or classic-runtime consumers (the other add-ons).Other environments
Documentation
.attrsdefault mechanism onBaseButton/LinkButtonand the in-component default merge onIconButtonToggle.Quality assurance
tests/buttonReact19Test.jsrendersBaseButton/LinkButton/IconButtonTogglewithdefaultPropsneutralised (mirroring the automatic runtime) and asserts they still render, thatBaseButtonkeepstype="button", and thatIconButtonToggleproduces identical styled output.grunt build:imagesand committed the results, if my PR introduces or edits images or SVGs.Innovation
Refs Yoast/reserved-tasks#235, Yoast/reserved-tasks#231
Fixes Yoast/reserved-tasks#1253
🤖 Generated with Claude Code