-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Disabled
: preserve input values when toggling the isDisabled
prop
#43508
Conversation
isDisabled
is changed.isDisabled
is changed.
isDisabled
is changed.Disabled
: preserve input values when toggling the isDisabled
prop
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.
Code changes are looking good!
Interesting fix, I guess that using a div
instead of a styled.div
helps React's reconciliation and doesn't re-render the children input
elements, throwing away their values (cc @mirka )
Could you also add a unit test, please?
Thank you!
@ciampo Certainly a unit test is needed. I will add it. |
9456046
to
264a92d
Compare
expect( getInput() ).toHaveValue( 'This is input.' ); | ||
expect( getContentEditable() ).toHaveTextContent( | ||
'This is contentEditable.' | ||
); |
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.
If an instance previously obtained by screen.getByRole( 'textbox' )
is used, rerender
is not reflected, so a new instance is obtained.
@ciampo Thanks for reviewing! Sorry for the delay in responding. I have committed the fixed version. |
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.
LGTM 🚀
I've got one more suggestion to make this fix less hacky:
Let's make the fix more explicit by refactoring that `div` inside a separate component
diff --git a/packages/components/src/disabled/index.tsx b/packages/components/src/disabled/index.tsx
index bcdbf4ba48..dcaef3e173 100644
--- a/packages/components/src/disabled/index.tsx
+++ b/packages/components/src/disabled/index.tsx
@@ -1,8 +1,13 @@
+/**
+ * External dependencies
+ */
+import type { TdHTMLAttributes, HTMLProps } from 'react';
+
/**
* WordPress dependencies
*/
import { useDisabled } from '@wordpress/compose';
-import { createContext } from '@wordpress/element';
+import { createContext, forwardRef } from '@wordpress/element';
/**
* Internal dependencies
@@ -15,6 +20,15 @@ import { useCx } from '../utils';
const Context = createContext< boolean >( false );
const { Consumer, Provider } = Context;
+// Extracting this ContentWrapper component in order to make it more explicit
+// the same 'ContentWrapper' component is needed so that React can reconcile
+// the dom correctly when switching between disabled/non-disabled (instead
+// of thrashing the previous DOM and therefore losing the form fields values).
+const ContentWrapper = forwardRef<
+ HTMLDivElement,
+ HTMLProps< HTMLDivElement >
+>( ( props, ref ) => <div { ...props } ref={ ref } /> );
+
/**
* `Disabled` is a component which disables descendant tabbable elements and prevents pointer interaction.
*
@@ -56,14 +70,14 @@ function Disabled( {
if ( ! isDisabled ) {
return (
<Provider value={ false }>
- <div>{ children }</div>
+ <ContentWrapper>{ children }</ContentWrapper>
</Provider>
);
}
return (
<Provider value={ true }>
- <div
+ <ContentWrapper
ref={ ref }
className={ cx(
disabledStyles,
@@ -73,7 +87,7 @@ function Disabled( {
{ ...props }
>
{ children }
- </div>
+ </ContentWrapper>
</Provider>
);
}
What?
There is a bug in the
Disabled
component where changingisDisabled
resets the form value. This has been fixed.Why?
#42708 (review)
How?
Testing Instructions
npm run storybook:dev
isDisabled
prop tofalse
in controls.isDisabled
prop totrue
in controls.Screenshots or screencast
2022-08-23.18.17.36.mov