Skip to content
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 the balloon to the bottom instead of the top when there isn't much space available. #1192

Closed
wants to merge 6 commits into from

Conversation

mehigh
Copy link
Contributor

@mehigh mehigh commented Jun 15, 2017

Fixes #1004
I increased the minimum height of the overflow wrapper while avoiding adding an unnecessary vertical scrollbar (hence the calc).
Before showing the balloon, the height of the visual editor is checked and switches the position from top to bottom.

@westonruter westonruter changed the title 1004 - Add the balloon to the bottom instead of the top when there isn't much space available. Add the balloon to the bottom instead of the top when there isn't much space available. Jun 15, 2017
@aduth
Copy link
Member

aduth commented Jun 15, 2017

How's that for timing. I just opened #1193 !

Copy link
Member

@aduth aduth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a few coding style issues which are causing the Travis build to fail. I'd suggest either running npm test (or npm run lint) in your terminal before pushing code, or better yet, installing an editor integration which will display issues inline in your code.

@@ -225,7 +225,15 @@ class InserterMenu extends wp.element.Component {
render() {
const { position = 'top', instanceId } = this.props;
const visibleBlocksByCategory = this.getVisibleBlocksByCategory( wp.blocks.getBlockTypes() );
const positionClasses = position.split( ' ' ).map( ( pos ) => `is-${ pos }` );
const visualEditorHeight = document.querySelector( '.editor-visual-editor' ).clientHeight;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally a component would not need to make any assumptions about the presence of any other elements on the page. In this case, it's both a little bit more reasonable because it's at least contained within editor-specific bundle, not a generic component, and because it's a difficult problem to solve (similar to in #1193 where I'd remarked about issue of knowing bounds of editor canvas).

@@ -225,7 +225,15 @@ class InserterMenu extends wp.element.Component {
render() {
const { position = 'top', instanceId } = this.props;
const visibleBlocksByCategory = this.getVisibleBlocksByCategory( wp.blocks.getBlockTypes() );
const positionClasses = position.split( ' ' ).map( ( pos ) => `is-${ pos }` );
const visualEditorHeight = document.querySelector( '.editor-visual-editor' ).clientHeight;
const minimumNeededHeight = 600;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An issue we might run into here is that the height of the inserter is dynamic depending on the viewport. Additionally, this could become difficult to maintain if we wanted to adjust the styling, since we'd similarly need to update component's JavaScript as well (and there's an assumption the unknown future maintainer knows to do this).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aduth then maybe if I looked up the height value using getComputedStyles on the .editor-inserter__content element it would make this solution more flexible?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think so. Or even clientHeight or getClientBoundingRect could work just as well.

It's not possible to do so here in the render though. Since the first time it would be called, there is not an actual DOM node yet (render only returns the React element). Instead, you'd need a combination of ref and componentDidMount (and more, per #1193 (comment)).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went on a different approach ... subtracting from the window height the height of the 3 elements that occupy vertical space around it (the admin bar, the editor header and the icon itself).

@mehigh
Copy link
Contributor Author

mehigh commented Jun 15, 2017

I fixed the linting errors.
I also removed the min-height since it wasn't needed anymore since the overflow was removed little over 2h ago.
I've implemented a dynamic calculation of the needed height to display the balloon above without any overlap, and yes -> since we don't have the element in the DOM at the render moment we can't getComputedStyle.
A next step could be just getting the height of those 3 elements -> the admin bar, the editor bar and the icon itself in the render function to compute the minimum height needed.

@mehigh
Copy link
Contributor Author

mehigh commented Jun 15, 2017

And now the height of the admin bar, the editor header and the button itself are computed on-render and subtracted from the available window height.
I think it's a simple enough solution and doesn't make many assumptions beyond some elements which are always present around the editor.

Hope this helps!

const heightOccupied =
document.getElementById( 'wpadminbar' ).clientHeight +
document.querySelector( '.editor-header' ).clientHeight +
document.querySelector( '.editor-inserter__toggle' ).clientHeight;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I click "Insert" in the editor bar, then click the inserter in post content, what node is returned by the query selector here? On the first render of the inserter in post content, it's actually the toggle from the header bar, which isn't correct.

Another one: If we decided to change the selector here to .editor-inserter__menu, what is the node on the first render? It wouldn't match anything (null) because the element hasn't yet been mounted yet. We're relying on the parent component already having mounted its toggle button, which is not a guarantee and is easy to overlook in refactoring.

I generally try to avoid component DOM querying because of these and other complexities. The render shouldn't assume that anything is present in the DOM, nor that it's the only instance of the component. To my previous comment, if DOM access is needed, it should be done via ref.

@aduth
Copy link
Member

aduth commented Jun 15, 2017

doesn't make many assumptions beyond some elements which are always present around the editor

More accurately, always present at this current point in time. Could lead to some maintenance pain if this were ever to change.

@aduth
Copy link
Member

aduth commented Jun 15, 2017

Closed in favor of the approach in #1193.

@aduth aduth closed this Jun 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants