-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Make Placeholder component "element-query-like" responsive. #18745
Conversation
packages/components/package.json
Outdated
@@ -44,6 +44,7 @@ | |||
"mousetrap": "^1.6.2", | |||
"re-resizable": "^6.0.0", | |||
"react-dates": "^17.1.1", | |||
"react-resize-aware": "^3.0.0-beta.7", |
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.
Relying on a beta probably isn't ideal, but their method of measuring DOM changes is superior to other packages like react-use-dimensions
because it will trigger an update even when content changes outside of a render()
cycle. Maybe react-use-dimensions
is enough for this use case 🤷♂
Edit: With a polyfill, https://www.npmjs.com/package/@rehooks/component-size could work
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.
Apart from window resizing situations (and we know only devs and designers do that, right? 😂 ) is there any real need to update outside of render? If not, react-use-dimensions
seems perfect for what we need. I'd be reluctant to go the component-size
route because that polyfill for resize-observer is massive 🙀
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.
Apart from window resizing situations (and we know only devs and designers do that, right? 😂 ) is there any real need to update outside of render?
The update-on-resize is nice, but definitely something we can live without. Worst case, seems like we could apply a transition: width 0.2s ease;
and at least have the resizing happen in a way that looks less jarring than an instant snap. 👍 👍
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.
Its not just window resizing that might cause the dimensions to change. If the width of another element grows or shrinks it might change dimensions of this element without this component having been re-rendered. The use of the iframe
is a neat way of detecting these layout changes (roughly, when the iframe
dimensions change it fires the resize event on the iframe
window).
Given the multi-column layouts in the above screenshots, I think this case is probably something that we need to account for?
The polyfill is definitely huge! Can't wait for a native implementation that works in all browsers! Maybe we can offer the library author some assistance to get it out of beta
.
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.
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'll reach out to the developer and see how we might be able to help.
Edit: Or we could refactor to use v2
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.
@jasmussen The author has released a new version for us! Try bumping the version to ^3.0.0
.
As you can see from the deepest nesting level for the image, even more work is necessary, but this is a good start that improves the situation. Likely for the additional work, it might be worth looking at that in light of the new efforts ongoing in #18667. |
@@ -1,15 +1,15 @@ | |||
.components-placeholder { | |||
position: relative; |
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.
This is required to position and size the resizeListener
correctly.
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.
That comment might good in code.
Tried to see if some other web builders use similar placeholders. Wix, Weebly, and Squarespace pre-fill in placeholders with demo content or fake images, instead of opting for showing buttons like we do, so they aren't much help. Does any other CMS use block placeholders like we do? Notion works similarly to us, but has similar responsive problems on the desktop app. Anyone have the mobile app and can check how placeholders work there? |
Mailchimp has a block placeholder that is pretty similar to the WordPress interface. Mailchimp uses a single button for replacing an image rather than options for URL, media library, and direct upload. Personally, I think it would work well if the buttons had the same width/max-width and the text was centered on the button. I think this might add some continuity and possibly make them more accessible for mobile users. |
LivingDocs uses a square cross which is very classic Desktop Publishing-like, but with no buttons. I think the element query nature, of which this PR is just a very first early attempt, is the key way to improve this, as it allows us to optimize for both large and small contexts. The thing is, the placeholder or "setup state" for the block is, to many blocks, the best UI to show next steps, when there's space. Take the Cover block, it feels like it's using the color swatches in a really nice way, letting you quickly pick a color and get moving! |
I like the shift to left-aligned text. It feels slightly cleaner and easier to read to me. At the smallest breakpoint, I wonder if the placeholder could be reduced to just a single button that says "Add image…" or "Add media…" or something like that, with no placeholder title above. Would that reduce accessibility? Also, should there be an attempt to make the full placeholder description available at the smaller breakpoints somehow? Perhaps an info icon that opens a pop-up containing the description? |
It seems like it should be fine. The block name, even if a placeholder, will be announced as such, and when you tab into the "Add..." button it's behavior should be clear. Elements that are |
What's missing here? As the conversation continues in #18800, it could make sense to merge this as a first step on the path. |
565ffa8
to
0c2cac0
Compare
Rebased and gave it a good squash. |
8b41c29
to
734d155
Compare
Thank you @jameslnewell ! I bumped in f26db0c#diff-fcafbf9322186d9a2998fd8c67903791R49. I also gave this a good rebase and a squash to simplify a final review. Let me know if things look as they should! |
7904999
to
e484608
Compare
It looks like the test failure is legitimate:
It's probably because in the initial version of this PR, the resize-aware was used to simply not output the description node below the 320px breakpoint, but I moved that to be CSS classes with |
@jasmussen I'll look at the tests. |
I removed the "instructions" hiding unit test because it assumed the hiding was done in JS but it's done in CSS and it's harder to test that way. |
1 similar comment
I removed the "instructions" hiding unit test because it assumed the hiding was done in JS but it's done in CSS and it's harder to test that way. |
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.
Nice PR
Thank you Riad, I'll merge when the checks pass. Props @jameslnewell. |
'components-placeholder', | ||
( width >= 320 ? 'is-large' : '' ), | ||
( width >= 160 && width < 320 ? 'is-medium' : '' ), | ||
( width < 160 ? 'is-small' : '' ), |
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.
One thing I note here is that in the documentation of react-resize-aware
, it mentions how width
would be null
the first time the component is rendered:
This object contains the
width
andheight
properties, these properties are going to benull
before the component rendered, and will return a number after the component rendered.
https://www.npmjs.com/package/react-resize-aware#api
The "fun" thing about null
is that, in the context of these sorts of comparisons, it's treated the same as zero (related, specification).
So:
let width = null;
console.log( width < 160 );
// true
So we'll always apply the is-small
class on the first render, even if it ends up being that the element will actually occupy a large width.
I guess my question is:
- Must we have at least one of
is-large
,is-medium
, oris-small
, and therefore it would be okay to useis-small
as the default until an accurate value can be determined? - Otherwise, would it be more correct to wait to assign any of these modifier classes until the true width can be determined?
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.
For context, I think this may be contributing to some intermittent failures in the end-to-end tests, where we're trying to click "Try again" when an embed fails, but the placement of the button might be shifting around because it is rendered after the "instructions" which are hidden while is-small
class is applied.
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 opened #19825 for continued discussion.
This change updates the margins of the notice UI added to block placeholders using the `withNotices` mixin. The update was necessary after #18745 which made the content of block placeholders left-aligned.
This change updates the margins of the notice UI added to block placeholders using the `withNotices` mixin. The update was necessary after #18745 which made the content of block placeholders left-aligned.
This PR is courtesy of @jameslnewell who created the initial work in master...jameslnewell:element-queries. I added some additional commits but did not have the necessary access to James' repository, so I pushed it to origin instead. Let there be no doubt, props: @jameslnewell.
What this PR does, is make the
<Placeholder />
component responsive using a custom form of element queries.Before:
After:
The above two screenshots also show why normal responsiveness is not sufficient. The Placeholder component is UI that needs to adapt to various nesting scenarios and dimensions.
To make that happen, I created 3 classes:
size-lg
(size large) to the Placeholder component.size-md
(size medium)size-sm
(size small)For the time being, this solves a problem with the Placeholder component. However we have many other UI elements that can benefit from responsive improvements, so I would love to hear your thoughts on how we can refactor these utility classes to be perhaps more automated or generic or at the very least easy to apply beyond just this Placeholder component.
Design-wise I leveraged those utility classes to reduce the UI as the component grows smaller, including hiding descriptions and icons when there isn't space. I simply removed the Upload icon — it does not feel like it adds value but in fact adds visual clutter instead. Additionally, I left-aligned the text, Placeholder labels, and buttons. This most literally anchors the content in a way that really helps reduce the visual appearance when more than one placeholder is visible on the page at the same time, which is going to be increasingly likely as templates grow in strength!
Your thoughts are very welcome.