From cd143d7b1949fc3efe878206137fe3ab4771055c Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Fri, 22 Nov 2024 13:02:35 +0100 Subject: [PATCH] separate subscriptions --- packages/kbn-grid-layout/grid/grid_panel.tsx | 193 ++++++++++--------- 1 file changed, 107 insertions(+), 86 deletions(-) diff --git a/packages/kbn-grid-layout/grid/grid_panel.tsx b/packages/kbn-grid-layout/grid/grid_panel.tsx index ebe02f6ae1dcb..aa9e500e63318 100644 --- a/packages/kbn-grid-layout/grid/grid_panel.tsx +++ b/packages/kbn-grid-layout/grid/grid_panel.tsx @@ -61,105 +61,126 @@ export const GridPanel = forwardRef< gridLayoutStateManager.activePanel$, gridLayoutStateManager.gridLayout$, gridLayoutStateManager.runtimeSettings$, - gridLayoutStateManager.expandedPanelId$, - gridLayoutStateManager.isMobileView$, ]) .pipe(skip(1)) // skip the first emit because the `initialStyles` will take care of it - .subscribe( - ([activePanel, gridLayout, runtimeSettings, expandedPanelId, isMobileView]) => { - const ref = gridLayoutStateManager.panelRefs.current[rowIndex][panelId]; - const allPanels = gridLayout[rowIndex].panels; - const panel = allPanels[panelId]; - if (!ref || !panel) return; + .subscribe(([activePanel, gridLayout, runtimeSettings]) => { + const ref = gridLayoutStateManager.panelRefs.current[rowIndex][panelId]; + const allPanels = gridLayout[rowIndex].panels; + const panel = allPanels[panelId]; + if (!ref || !panel) return; - if (expandedPanelId) { - if (expandedPanelId === panelId) { - // Stretch the expanded panel to occupy the remaining available space in the viewport. - ref.style.display = 'block'; - ref.style.position = `absolute`; - ref.style.top = `0`; - ref.style.left = `0`; - ref.style.width = `100%`; - ref.style.height = `100%`; - return; - } else { - ref.style.display = 'none'; - } + const currentInteractionEvent = gridLayoutStateManager.interactionEvent$.getValue(); + if (panelId === activePanel?.id) { + // if the current panel is active, give it fixed positioning depending on the interaction event + const { position: draggingPosition } = activePanel; + + ref.style.zIndex = `${euiThemeVars.euiZModal}`; + if (currentInteractionEvent?.type === 'resize') { + // if the current panel is being resized, ensure it is not shrunk past the size of a single cell + ref.style.width = `${Math.max( + draggingPosition.right - draggingPosition.left, + runtimeSettings.columnPixelWidth + )}px`; + ref.style.height = `${Math.max( + draggingPosition.bottom - draggingPosition.top, + runtimeSettings.rowHeight + )}px`; + + // undo any "lock to grid" styles **except** for the top left corner, which stays locked + ref.style.gridColumnStart = `${panel.column + 1}`; + ref.style.gridRowStart = `${panel.row + 1}`; + ref.style.gridColumnEnd = ``; + ref.style.gridRowEnd = ``; } else { - ref.style.display = ``; - ref.style.position = ``; - } + // if the current panel is being dragged, render it with a fixed position + size + ref.style.position = `fixed`; + ref.style.left = `${draggingPosition.left}px`; + ref.style.top = `${draggingPosition.top}px`; + ref.style.width = `${draggingPosition.right - draggingPosition.left}px`; + ref.style.height = `${draggingPosition.bottom - draggingPosition.top}px`; - if (isMobileView) { - const sortedKeys = getKeysInOrder(gridLayout[rowIndex]); - const currentPanelPosition = sortedKeys.indexOf(panelId); - const sortedKeysBefore = sortedKeys.slice(0, currentPanelPosition); - const responsiveGridRowStart = sortedKeysBefore.reduce( - (acc, key) => acc + allPanels[key].height, - 1 - ); - ref.style.gridColumnStart = `1`; - ref.style.gridColumnEnd = `-1`; - ref.style.gridRowStart = `${responsiveGridRowStart}`; - ref.style.gridRowEnd = `${responsiveGridRowStart + panel.height}`; - // we shouldn't allow interactions on mobile view so we can return early - return; + // undo any "lock to grid" styles + ref.style.gridColumnStart = ``; + ref.style.gridRowStart = ``; + ref.style.gridColumnEnd = ``; + ref.style.gridRowEnd = ``; } + } else { + ref.style.zIndex = '0'; - const currentInteractionEvent = gridLayoutStateManager.interactionEvent$.getValue(); - if (panelId === activePanel?.id) { - // if the current panel is active, give it fixed positioning depending on the interaction event - const { position: draggingPosition } = activePanel; + // if the panel is not being dragged and/or resized, undo any fixed position styles + ref.style.position = ''; + ref.style.left = ``; + ref.style.top = ``; + ref.style.width = ``; + ref.style.height = ``; - ref.style.zIndex = `${euiThemeVars.euiZModal}`; - if (currentInteractionEvent?.type === 'resize') { - // if the current panel is being resized, ensure it is not shrunk past the size of a single cell - ref.style.width = `${Math.max( - draggingPosition.right - draggingPosition.left, - runtimeSettings.columnPixelWidth - )}px`; - ref.style.height = `${Math.max( - draggingPosition.bottom - draggingPosition.top, - runtimeSettings.rowHeight - )}px`; - - // undo any "lock to grid" styles **except** for the top left corner, which stays locked - ref.style.gridColumnStart = `${panel.column + 1}`; - ref.style.gridRowStart = `${panel.row + 1}`; - ref.style.gridColumnEnd = ``; - ref.style.gridRowEnd = ``; - } else { - // if the current panel is being dragged, render it with a fixed position + size - ref.style.position = `fixed`; - ref.style.left = `${draggingPosition.left}px`; - ref.style.top = `${draggingPosition.top}px`; - ref.style.width = `${draggingPosition.right - draggingPosition.left}px`; - ref.style.height = `${draggingPosition.bottom - draggingPosition.top}px`; + // and render the panel locked to the grid + ref.style.gridColumnStart = `${panel.column + 1}`; + ref.style.gridColumnEnd = `${panel.column + 1 + panel.width}`; + ref.style.gridRowStart = `${panel.row + 1}`; + ref.style.gridRowEnd = `${panel.row + 1 + panel.height}`; + } + }); - // undo any "lock to grid" styles - ref.style.gridColumnStart = ``; - ref.style.gridRowStart = ``; - ref.style.gridColumnEnd = ``; - ref.style.gridRowEnd = ``; - } - } else { - ref.style.zIndex = '0'; + return () => { + styleSubscription.unsubscribe(); + }; + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); - // if the panel is not being dragged and/or resized, undo any fixed position styles - ref.style.position = ''; - ref.style.left = ``; - ref.style.top = ``; - ref.style.width = ``; - ref.style.height = ``; + useEffect( + () => { + /** Update the styles of the panel via a subscription to prevent re-renders */ + const styleSubscription = combineLatest([ + gridLayoutStateManager.gridLayout$, + gridLayoutStateManager.expandedPanelId$, + gridLayoutStateManager.isMobileView$, + ]) + .pipe(skip(1)) // skip the first emit because the `initialStyles` will take care of it + .subscribe(([gridLayout, expandedPanelId, isMobileView]) => { + const ref = gridLayoutStateManager.panelRefs.current[rowIndex][panelId]; + const allPanels = gridLayout[rowIndex].panels; + const panel = allPanels[panelId]; + if (!ref || !panel) return; - // and render the panel locked to the grid - ref.style.gridColumnStart = `${panel.column + 1}`; - ref.style.gridColumnEnd = `${panel.column + 1 + panel.width}`; - ref.style.gridRowStart = `${panel.row + 1}`; - ref.style.gridRowEnd = `${panel.row + 1 + panel.height}`; + if (expandedPanelId) { + if (expandedPanelId === panelId) { + // Stretch the expanded panel to occupy the remaining available space in the viewport. + ref.style.display = 'block'; + ref.style.position = `absolute`; + ref.style.top = `0`; + ref.style.left = `0`; + ref.style.width = `100%`; + ref.style.height = `100%`; + return; + } else { + ref.style.display = 'none'; + return; } + } else { + ref.style.display = ``; + ref.style.position = ``; + } + + if (isMobileView) { + const sortedKeys = getKeysInOrder(gridLayout[rowIndex]); + const currentPanelPosition = sortedKeys.indexOf(panelId); + const sortedKeysBefore = sortedKeys.slice(0, currentPanelPosition); + const responsiveGridRowStart = sortedKeysBefore.reduce( + (acc, key) => acc + allPanels[key].height, + 1 + ); + ref.style.gridColumnStart = `1`; + ref.style.gridColumnEnd = `-1`; + ref.style.gridRowStart = `${responsiveGridRowStart}`; + ref.style.gridRowEnd = `${responsiveGridRowStart + panel.height}`; + // we shouldn't allow interactions on mobile view so we can return early + return; } - ); + }); return () => { styleSubscription.unsubscribe();