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

View File

@@ -84,6 +84,7 @@ export class HeaderFilter<T extends Slick.SlickData> {
private disposableStore = new DisposableStore(); private disposableStore = new DisposableStore();
private columnButtonMapping: Map<string, HTMLElement> = new Map<string, HTMLElement>(); private columnButtonMapping: Map<string, HTMLElement> = new Map<string, HTMLElement>();
private previouslyFocusedElement: HTMLElement; private previouslyFocusedElement: HTMLElement;
private listContainer?: HTMLElement;
constructor(private readonly contextViewProvider: IContextViewProvider, private readonly notificationProvider?: NotificationProvider, private readonly options: ITableFilterOptions = DefaultTableFilterOptions) { 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 { 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); const button = new Button(buttonContainer);
button.icon = { id: `slick-header-menuicon ${iconClass}` }; button.icon = { id: `slick-header-menuicon ${iconClass}` };
button.label = title; button.label = title;
@@ -278,8 +279,8 @@ export class HeaderFilter<T extends Slick.SlickData> {
this.filteredListData = this.listData; this.filteredListData = this.listData;
const filter = append(this.menu, $('.filter')); this.listContainer = append(this.menu, $('.filter'));
this.list = new List<TableFilterListElement>('TableFilter', filter, new TableFilterListDelegate(), [new TableFilterListRenderer()], { this.list = new List<TableFilterListElement>('TableFilter', this.listContainer, new TableFilterListDelegate(), [new TableFilterListRenderer()], {
multipleSelectionSupport: false, multipleSelectionSupport: false,
keyboardSupport: true, keyboardSupport: true,
mouseSupport: true, mouseSupport: true,
@@ -347,29 +348,26 @@ export class HeaderFilter<T extends Slick.SlickData> {
} }
this.previouslyFocusedElement = document.activeElement as HTMLElement; this.previouslyFocusedElement = document.activeElement as HTMLElement;
await this.createFilterMenu(filterButton); await this.createFilterMenu(filterButton);
// Get the absolute coordinates of the filter button // Try to fit the menu in the screen.
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.
// 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. // 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; const offset = jQuery(filterButton).offset();
} // If there is not enough vertical space under the filter button, we will move up the menu.
menuleft = menuleft > 0 ? menuleft : 0; 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({ this.contextViewProvider.showContextView({
getAnchor: () => { getAnchor: () => {
return { return {
x: menuleft, x: menuLeft,
y: menutop y: menuTop
}; };
}, },
render: (container: HTMLElement) => { render: (container: HTMLElement) => {
container.appendChild(this.menu); container.appendChild(this.menu);
// Set the list size to its container size so that scrolling works correctly..
this.list.layout(this.listContainer.clientHeight);
return { return {
dispose: () => { dispose: () => {
this.disposeMenu(); 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 // 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 // later, it will be added to the correct container
this.menu = append(document.body, $('.slick-header-menu')); 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.sortAscButton = this.createButtonMenuItem(localize('table.sortAscending', "Sort Ascending"), 'sort-asc', 'ascending');
this.sortDescButton = this.createButtonMenuItem(localize('table.sortDescending', "Sort Descending"), 'sort-desc', 'descending'); this.sortDescButton = this.createButtonMenuItem(localize('table.sortDescending', "Sort Descending"), 'sort-desc', 'descending');