fix the filter plugin menu size and location issue (#23075)

This commit is contained in:
Alan Ren
2023-05-10 12:05:00 -07:00
committed by GitHub
parent a2c30b0df8
commit d5ece618cc
2 changed files with 31 additions and 21 deletions

View File

@@ -101,7 +101,8 @@
padding: 4px;
z-index: 100000;
cursor: default;
display: inline-block;
display: flex;
flex-direction: column;
margin: 0;
position: absolute;
}
@@ -118,10 +119,14 @@
background: none repeat scroll 0 0 #000000;
}
.slick-header-menu-image-button-container {
flex: 0 0 auto;
}
.slick-header-menu a.monaco-button.monaco-text-button {
width: 60px;
margin: 6px 6px 6px 6px;
padding: 4px;
margin: 5px;
padding: 2px;
}
.slick-header-menu .searchbox-row
@@ -130,6 +135,7 @@
align-items: center;
padding-left: 5px;
margin-top: 5px;
flex: 0 0 auto;
}
.slick-header-menu .searchbox-row .select-all-checkbox
@@ -168,7 +174,6 @@
{
border: 1px solid #BFBDBD;
font-size: 8pt;
height: 250px;
margin-top: 6px;
overflow: hidden;
padding: 1px;
@@ -176,6 +181,7 @@
align-content: flex-start;
display: flex;
flex-direction: column;
flex: 1 1 auto;
}
.slick-header-menu .filter .filter-option {
@@ -188,6 +194,7 @@
display: flex;
flex-direction: row;
width: 100%;
flex: 0 0 auto;
}
.slick-header-menu .filter-menu-button {

View File

@@ -84,6 +84,7 @@ export class HeaderFilter<T extends Slick.SlickData> {
private disposableStore = new DisposableStore();
private columnButtonMapping: Map<string, HTMLElement> = new Map<string, HTMLElement>();
private previouslyFocusedElement: HTMLElement;
private listContainer?: HTMLElement;
constructor(private readonly contextViewProvider: IContextViewProvider, private readonly notificationProvider?: NotificationProvider, private readonly options: ITableFilterOptions = DefaultTableFilterOptions) {
}
@@ -180,7 +181,7 @@ export class HeaderFilter<T extends Slick.SlickData> {
}
private createButtonMenuItem(title: string, command: HeaderFilterCommands, iconClass: string): Button {
const buttonContainer = append(this.menu, $(''));
const buttonContainer = append(this.menu, $('.slick-header-menu-image-button-container'));
const button = new Button(buttonContainer);
button.icon = { id: `slick-header-menuicon ${iconClass}` };
button.label = title;
@@ -278,8 +279,8 @@ export class HeaderFilter<T extends Slick.SlickData> {
this.filteredListData = this.listData;
const filter = append(this.menu, $('.filter'));
this.list = new List<TableFilterListElement>('TableFilter', filter, new TableFilterListDelegate(), [new TableFilterListRenderer()], {
this.listContainer = append(this.menu, $('.filter'));
this.list = new List<TableFilterListElement>('TableFilter', this.listContainer, new TableFilterListDelegate(), [new TableFilterListRenderer()], {
multipleSelectionSupport: false,
keyboardSupport: true,
mouseSupport: true,
@@ -347,29 +348,26 @@ export class HeaderFilter<T extends Slick.SlickData> {
}
this.previouslyFocusedElement = document.activeElement as HTMLElement;
await this.createFilterMenu(filterButton);
// Get the absolute coordinates of the filter button
const offset = jQuery(filterButton).offset();
// Calculate the position of menu item
let menuleft = offset.left - this.menu.offsetWidth + filterButton.offsetWidth;
let menutop = offset.top + filterButton.offsetHeight;
// Make sure the entire menu is on screen.
// If there is not enough vertical space under the filter button, we will move up the menu.
// If the left of the menu is off screen (negative value), we will show the menu next to the left edge of window.
// Try to fit the menu in the screen.
// We don't really consider the case when there is not enough space to show the entire menu since in that case the application is not usable already.
if (menutop + this.menu.offsetHeight > window.innerHeight) {
menutop = window.innerHeight - this.menu.offsetHeight;
}
menuleft = menuleft > 0 ? menuleft : 0;
const offset = jQuery(filterButton).offset();
// If there is not enough vertical space under the filter button, we will move up the menu.
const menuTop = offset.top + this.menu.offsetHeight <= window.innerHeight ? offset.top : window.innerHeight - this.menu.offsetHeight;
// Make sure the menu is on the screen horizontally.
const menuLeft = offset.left + filterButton.offsetWidth + this.menu.offsetWidth <= window.innerWidth ? offset.left + filterButton.offsetWidth : window.innerWidth - this.menu.offsetWidth;
this.contextViewProvider.showContextView({
getAnchor: () => {
return {
x: menuleft,
y: menutop
x: menuLeft,
y: menuTop
};
},
render: (container: HTMLElement) => {
container.appendChild(this.menu);
// Set the list size to its container size so that scrolling works correctly..
this.list.layout(this.listContainer.clientHeight);
return {
dispose: () => {
this.disposeMenu();
@@ -401,6 +399,11 @@ export class HeaderFilter<T extends Slick.SlickData> {
// first add it to the document so that we can get the actual size of the menu
// later, it will be added to the correct container
this.menu = append(document.body, $('.slick-header-menu'));
const MenuVerticalPadding = 10;
const MenuBarHeight = 30;
const DefaultMenuHeight = 350;
// Make sure the menu can fit in the screen.
this.menu.style.height = `${Math.min(DefaultMenuHeight, window.innerHeight - MenuBarHeight) - MenuVerticalPadding}px`;
this.sortAscButton = this.createButtonMenuItem(localize('table.sortAscending', "Sort Ascending"), 'sort-asc', 'ascending');
this.sortDescButton = this.createButtonMenuItem(localize('table.sortDescending', "Sort Descending"), 'sort-desc', 'descending');