-
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
BlockPreview: add __experimentalOnReady property #17242
Conversation
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.
Hi @retrofox, thank you for your contribution things look good I just left some minor comments.
I guess onRead will be useful in some situations but I'm not imagining many possible use cases right now, could you elaborate on the concrete use case for onReady and why it is needed?
setPreviewScale( containerElementRect.width / viewportWidth ); | ||
const scale = containerElementRect.width / viewportWidth; | ||
setPreviewScale( scale ); | ||
onReady( { scale, ref: previewRef } ); |
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'm not sure if we should be passing refs via an event handler it seems to be uncommon, can't we use the normal way of passing references in React? e.g., in this case, BlockPreview may have an optional __experimental ScaledPreviewRef property that is passed to ScaledBlockPreview component which then forwards the ref.
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'm not understanding this feedback, Jorge :-/
can't we use the normal way of passing references in React?
The reference is gotten just here, in this component, and the callback passes the reference as an argument as a chance to get keep working in the preview process if it's needed.
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.
Sounds Good 👌 Let me update the PR.
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.
Sorry, I think I completely misunderstood the conversation here:
I'm not sure if we should be passing refs via an event handler
It's just another data passed by the callback. The reference is already defined by the Block preview component to be able to compute sizes in order to adjust the scale factor to apply to the preview block.
We could avoid passing the reference if you think it isn't useful.
What we should not do it is create the reference out of the component. It should take over this task.
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.
allow the possibility of the BlockPreview user to pass its own reference, so the event does not need to pass it.
The ScaledBlockPreview
component needs to create its own ref in order to allow it access to the DOM of the elements that form the preview because several calculations are required for scaling and positioning...etc.
It looks like you are suggesting we allow the consumer of BlockPreview
to optionally pass down a ref
which in turn would be passed down to ScaledBlockPreview
and ultimately used as the ref here? I guess you could then either utilise the ref provided by the consumer or have one created internally by ScaledBlockPreview
although I'm not clear on what use case this would serve.
Thanks @jorgefilipecosta for your comments. Really appreciate it.
Specifically in our case what we need is to know the scale factor to apply it to other elements/components which are next to the blocks previewed with the |
73fc6b5
to
d96f345
Compare
a71db9a
to
a858784
Compare
setPreviewScale( containerElementRect.width / viewportWidth ); | ||
const scale = containerElementRect.width / viewportWidth; | ||
setPreviewScale( scale ); | ||
onReady( { scale, ref: previewRef } ); |
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.
Now we don't need to pass the ref in the event anymore right?
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.
Added a comment here (edited as well, sorry)
#17242 (comment)
a858784
to
1bb0ccf
Compare
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.
Thanks for working on this @retrofox! This looks go be a good idea. I had a similar thought when I was knee-deep in this component. Not being able to easily tell when the preview is "ready" was a major flaw.
Some minor tweaks here.
@jorgefilipecosta I feel like this entire component has become a lot more complex but we have no test coverage for it. Do you have concerns about this? If so how could one go about writing sane tests for this?
```es6 | ||
|
||
<BlockPreview | ||
__experimentalOnReady={ ( { scale } ) => console.log( `Current preview scale: ${ scale }` ) |
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.
It would be good to show all the values available to the callback (ie: not just scale
).
__experimentalOnReady( { | ||
scale, | ||
position: { x: offsetX * scale, y: offsetY }, | ||
ref: previewRef, |
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.
Have you considered using a more descriptive term rather than ref
? What is ref
to the user? Might we consider previewContainerRef
as this is actually what the ref is "attached" to? Just a thought...
} else { | ||
const containerElementRect = containerElement.getBoundingClientRect(); | ||
setPreviewScale( containerElementRect.width / viewportWidth ); | ||
const scale = containerElementRect.width / viewportWidth; |
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.
How come this code got added? Why was it added and what does it do? Doesn't seem directly connected to having a callback.
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.
Yes, it does. I've declared the scale
constant in order to use it two lines below when it calls the callback.
__experimentalOnReady( { scale, ref: previewRef } );
0043103
to
c550113
Compare
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.
Thank you for the iterations @retrofox. This PR seems mostly ready I just left some minor comments.
@@ -18,7 +18,15 @@ import BlockEditorProvider from '../provider'; | |||
import BlockList from '../block-list'; | |||
import { getBlockPreviewContainerDOMNode } from '../../utils/dom'; | |||
|
|||
function ScaledBlockPreview( { blocks, viewportWidth } ) { | |||
const getOnlineStyles = ( scale, x, y, isReady, width ) => ( { |
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.
getOnlineStyles = getInlineStyles?
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.
🤦♂
* `scale`: the scale factor | ||
* `position`: offsets position (x, y) | ||
* `previewContainerRef`: DOM element reference | ||
* `styles`: Online styles applied to the preview container |
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.
Did you mean "Inline styles applied.."?
Should the property be called inlineStyles instead of styles to be more specific?
@@ -98,7 +112,7 @@ function ScaledBlockPreview( { blocks, viewportWidth } ) { | |||
); | |||
} | |||
|
|||
export function BlockPreview( { blocks, viewportWidth = 700, settings } ) { | |||
export function BlockPreview( { blocks, viewportWidth = 700, settings, __experimentalOnReady = noop, __experimentalDelay = 100 } ) { |
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.
The delay we have is for the addition of scaling right? Maybe we can call the prop __experimentalScallingDelay to be more specific I guess ideally the name would refer to what is being delayed.
I think we should also document this prop together with __experimentalOnReady.
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.
with only one l
;-)
* **Type** `Int` | ||
* **Default** `100ms` | ||
|
||
It defines the delay before to start to calc the scale factor and position of the preview block. |
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.
How about
Defines a delay to be applied before calculating the scale factor and position of the preview block.
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.
Thank you for the iterations @retrofox, I tested the new props and they seem to work as expected. The code also looks good 👍
Thank you! really appreciate your help reviewing and developing the code. 🙇 |
Hi @retrofox, was there an alternative to __experimentalOnReady found? If not, should the PR be rebased and merged? |
8d6ccbe
to
cf377c3
Compare
Hi @jorgefilipecosta, I'm not aware of an alternative to this approach. PR is already rebased. |
The docs say to use run `npm run lint:fix` to automatically fix some issues, that doesn't exist, it should be `npm run lint-js:fix`
ff2d0bc
to
ff67c2a
Compare
Size Change: +136 B (0%) Total Size: 864 kB
ℹ️ View Unchanged
|
Description
This PR adds a new property called __experimentalOnReady to the
<BlockPreview />
component, which allows us to know the exact moment when the preview is ready, providing useful data such as the scale factor applied, position and the reference to the DOM element.It worths to mention that the whole process of previewing contemplates some tricks, pretty common when it needs to interact with the real DOM tree btw, such as adding a timeout (100ms), which sometimes makes it unpredictable and prone to fall in some race conditions if you aren't being careful.
Also, it adds the
__experimentalScalingDelay_
in order to allow set explicitly the delay to take before to start to compute the scale factor. The default value is100ms
.How it works?
How has this been tested?
To test it you can tide a function to this property and confirm that it's called once the preview has been performed, for instance:
Chrome dev console:
Checklist: