-
Notifications
You must be signed in to change notification settings - Fork 28.4k
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
Selectbox breaks when there's not enough space to render #55750
Comments
@joaomoreno Just for my curiosity, I assume you forced the use of the custom select box on the Mac platform? |
I have fixed the calculations and added logic to not open the drop-down at all if there is insufficient room below or above. I do need a recommendation on the final part: I can't figure out a best practice to hide/close the base contextview for the sequence where the drop-down is already open , window or region is resized, Global layout is called eventually getting to the contextview. If I attempt to hide from within the layout call Code crashes since the delegate is destroyed within the layout call. Doing a CSS hide within the delegate layout causes a blur event where I currently do a hide . This sequence only works if the blur event occurs after the layout returns. I don't think this can be guaranteed so I don't like it is a solution. I looked at the feedback code to see what it does but I cannot find any parallel. The ability to Close a contextview from within the layout method or rather the delegate , would seem to be useful but currently not implemented? Thanks |
@joaomoreno can maybe advice on that question around the context view given his recent stake in that widget. |
@cleidigh Can you show me the spot where you'd attempt to hide the context view during "Global layout"? |
Below is the beginning part of the delegate layout function for the contextview based After some experimenting, I have a pretty basic fix but, it requires a change to contextview I also include the patch at the end. I posted a WIP PR with this working approach. If you agree with the fix, let me know when I should merge (for July or August)? selectBoxCustom.ts private layoutSelectDropDown(preLayoutPosition?: boolean): boolean {
// Layout ContextView drop down select list and container
// Have to manage our vertical overflow, sizing, position below or above
// Position has to be determined and set prior to contextView instantiation
console.debug('Layout '+ preLayoutPosition);
if (this.selectList) {
const selectPosition = dom.getDomNodePagePosition(this.selectElement);
const styles = getComputedStyle(this.selectElement);
const verticalPadding = parseFloat(styles.getPropertyValue('--dropdown-padding-top')) + parseFloat(styles.getPropertyValue('--dropdown-padding-bottom'));
let maxSelectDropDownHeightBelow = 0;
maxSelectDropDownHeightBelow = (window.innerHeight - selectPosition.top - selectPosition.height - this.selectBoxOptions.minBottomMargin);
const maxSelectDropDownHeightAbove = (selectPosition.top - SelectBoxList.DEFAULT_DROPDOWN_MINIMUM_TOP_MARGIN);
this.selectList.layout();
let listHeight = this.selectList.contentHeight;
const minRequiredDropDownHeight = listHeight + verticalPadding;
if ( (maxSelectDropDownHeightBelow + maxSelectDropDownHeightAbove) < this.getHeight() + verticalPadding) {
// If at least one option cannot be shown, don't open the drop-down or hide/remove if open
if (this._isVisible) {
// We must be doing a re-layout, hide if we don't fit
// Approach 1: ContextView.hide - fails when ContextView.doLayout called
this.hideSelectDropDown(true);
// Above approach will work with minimal change in ContextView.layout
// See following code block
// Approach 2: CSS hide triggers this.selectList.onDidBlur which destroys ContextView
// as long as blur occurs after ContextView.layout, hide/remove call succeeds
// I don't think this can be guaranteed, but I have not seen it fail
// dom.toggleClass(this.selectDropDownContainer, 'visible', false);
// Approach 3: Focus back on parent select, causes immediate blur
// and hide before layout returns, always fails
// This would also be the failure mode for approach 2
// this.selectElement.focus();
}
return false;
}
contextview.ts patch: Added delegate existence check private doLayout(): void {
// Check that we still have a delegate - this.delegate.layout may have hidden
if (!this.isVisible()) {
return;
}
// Get anchor
let anchor = this.delegate.getAnchor();
|
@cleidigh If I understand correctly, you simply chose not to open the widget in case there is no available space. But the widget supports scrollbars... it should open correctly... |
@joaomoreno The patch I proposed allows the delegate layout to determine if there is space available and close the contextV if necessary. Since the check is the same if canReLayout === false I don't see any problem taking this approach. |
Actually, my original issue is not about resizing while the box is open, but rather about opening the box while there's not enough space for it to render. Check the GIF. |
@joaomoreno Original issue is solved by first patch to selectBoxCustom.ts above preventing opening if insufficient space to render. Second issue (and second fix) was identified while fixing the first. DropDown should close if already open, insufficient space to render on DOM re-layout. Should I create a separate issue/PR fix for the second "SelectBox should close on DOM re-layout if insufficient space to render" ? |
Let me go back to my point: the widget uses a list which supports scrollbars. So, shouldn't we still open it, instead of preventing it from opening, since the scrollbars will take care of the content overflow? |
@joaomoreno As long as we can show one option below or above if there are more options the scrollbars will be visible. I will clean up the PR so there's no extraneous stuff or debug output so the two patches are not muddied Update: Found another edge condition under settings editor: select gets moved out of viewport |
No Configurations
select box, all is goodThe text was updated successfully, but these errors were encountered: