Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
Add experimental
ResponsiveBlockControl
component #16790Add experimental
ResponsiveBlockControl
component #16790Changes from 34 commits
23807cf
95bfae8
dd64a53
8116762
4ca0fc5
fe7c77d
e051305
9c6e8b2
f2d1bfc
aa1ec5f
eb5e9ba
bec9001
1907640
17eec18
c9c5e08
eb9c5f3
238d541
1af87b9
51b43a6
20a95b4
a64c2cd
9926612
d210cfe
b81e605
8605087
3ac118d
045dd49
b5bfc06
5c9841c
b2bea8c
827bb82
059b5a5
ce3be6f
195aef5
e821dc9
863783c
8ebbd2c
64e719f
e6aad72
48529f7
d72e6af
a46f406
15da1b3
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
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.
We are keeping the responsive mode as a local state, but when the flag is toggled the parent needs to know about this state change, otherwise how is the change going to be persisted?
I think the parent should pass something like isResponsiveMode, and an onIsResponsiveMode change and the parent should be responsible for handling and storing changes.
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.
I've also been wrestling with this one.
You'll note until recently this was controlled by the consuming "parent" component. Then in this commit, I moved it to become component/local state.
This was because it felt odd that the consumer needed to provide a means to toggle the UI. I felt the state of the toggle should be internal (thereby avoiding the need for the user to have to know about this implementation detail) but we should expose a callback to notify when it changes and also a means to set the default state.
Note that currently, I've tried to find the best of both worlds. By default you don't need to handle the toggle manually when utilising the component - it is handled internally and "just works" (this is what I'd expect to happen as a user). However, you can optionally set the boolean
responsiveControlsActive
prop to determine the initial state of the UI (ie: open/closed responsive controls). This allows us to persist an open/closed state between renders and/or editor initialisations. I probably need a decent test case for this scenario.It's simple enough to roll this back to my original implementation (which is what I think you are recommending) but I am concerned about making this component too hard to utilise.
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.
I've revised this a little. Let me know what you think.
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 the consumer passes isResponsiveMode and onIsResponsiveModeChange the consumer is not passing a means to toggle the UI it is passing if the current mode is responsive and a handler to change it. It is not even aware that the mode is changed by using a toggle.
If responsiveControlsActive changes, the component will not reflect that change, this seems problematic is it makes it impossible to apply a change in the flag from a third party plugin if the component is rendered.
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.
To be clear
responsiveControlsActive
- this sets the initial state of the toggle. This allows the consuming component to set the initial mode to responsive or not.onIsResponsiveModeChange
- this is a callback purely to "notify" the consuming component that the responsive mode has changed to the value provided as an argument (ie: on/off). It doesn't do any setting.In addition, there is also the internal state value
isResponsiveMode
. This is used to manage the state of the responsive toggle internally. The consuming component has no means to alter this value except on the initial render where the initial value of the state is set byresponsiveControlsActive
prop.My thinking was that it was too much to ask the consuming component to manage the internal toggle state of the UI. I thought that by managing internally it would make the component easier to use. I recognised that the consuming component would need to be able to set the initial toggle state which is why I went for the
responsiveControlsActive
prop.That said, recent experience has led me to believe that almost all components that involve user input need to be fully controlled components. I think this is what you were driving at and I'm coming around to that idea, even if it makes the component more labourious to consume.
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 it does not do any setting, why we have a need to notify it? I think when there is a responsive mode change, the parent must update its state.
If we had a different padding setting per device (one value for small and one for medium), then the user clicks "Use the same padding on all screen sizes." the parent needs to update the values to remove the different settings for small and medium paddings. Otherwise, we start a disconnection between what the UI says, "Use the same padding on all screen sizes." and what is effectively stored.
So It seems like when there is a toggle on the responsive mode, the parent needs to update something probably block attributes. Depending on these attributes, the parent knows if the flag is true or not. If, during the first render, the parent needs to know if responsiveControlsActive is true or false, why can't on future updates the flag the parent passes also be used? That's the reason I think we don't need a local state the parent knows if the toggle is set or not depending on the attributes.
But right now I also not sure on the direction because we don't have storage for these settings yet. Also, I'm not totally inside the problem, so don't treat this suggestion as a blocker we can continue the current approach. When the component is used in practice it will be easier to understand the current path and if needed we can change as the component is experimental.
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.
Same note here about BEM convention as at: #17846 (comment)
Also:
is-responsive
for the other condition, and for this one, simply omitting it.The second point would actually enable us to simplify this implementation, where currently there is code duplication for
block-editor-responsive-block-control__group
largely because of how this class is assigned. With the above changes, it could become a unified wrapper of: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.
Any idea how this snapshot ended up minified? Makes it impossible to review changes to the component 😞
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.
@tellthemachines It's quite likely that because the test is using a string of HTML for the snapshot, it doesn't know how to make sense of the string as markup of elements to break across lines, vs. say a React element tree. I'd agree though that it sort of defeats the purpose of a snapshot if a future maintainer is unable to assess whether changes in the snapshot are sensible.
I'm not sure exactly what our current configuration will support for those snapshots, but I'd wonder if it could be using the DOM element or if we could adapt somehow for the React element to be used. Otherwise, we may ought to avoid using the snapshot altogether and instead assert directly against specific values we're expecting in the markup.