mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 10:40:07 -04:00
[Collapsable panels] Refactor forward refs (#208360)
## Summary This PR fixes a few very small issues: 1. Removes this warning via setting explicity `touchstart` passive. I read that `touchstart` is passive by default, but apparently it varies between browsers. <img width="1053" alt="Screenshot 2025-01-27 at 14 04 26" src="https://github.com/user-attachments/assets/0d641575-df6c-429c-a731-e9f41dc9ec65" /> 2. Removes the `containerRef` that we stopped using, but didn't remove the variable. 3. Sets the refs for `rowRefs` and `panelRefs` inside the component instead of passing `forwardRefs` and passing it on parent components. Unless I am missing something, there's no reason for adding this complexity. Plus `forwardRef` is deprecated in React 19 so it's good to remove now :) 4. Adds `max-height: 100vh` for expanded version of gridHeightSmoother. We need that, since setting it to 100% right now will not always work properly if parent won't set up its height. The problem is very visible in our example app with Lens datatable, (uses EuiDataGrid underneath). When we maximize the datatable panel, it will grow forever and cause a lot of console errors about Resize Observers.
This commit is contained in:
parent
3e0fd1f82e
commit
00d822d88a
5 changed files with 309 additions and 306 deletions
|
@ -60,6 +60,7 @@ export const GridHeightSmoother = ({
|
|||
|
||||
&:has(.kbnGridPanel--expanded) {
|
||||
min-height: 100% !important;
|
||||
max-height: 100vh; // fallback in case if the parent doesn't set the height correctly
|
||||
position: relative;
|
||||
transition: none;
|
||||
}
|
||||
|
|
|
@ -145,9 +145,6 @@ export const GridLayout = ({
|
|||
rowIndex={rowIndex}
|
||||
renderPanelContents={renderPanelContents}
|
||||
gridLayoutStateManager={gridLayoutStateManager}
|
||||
ref={(element: HTMLDivElement | null) =>
|
||||
(gridLayoutStateManager.rowRefs.current[rowIndex] = element)
|
||||
}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -41,7 +41,7 @@ export const DragHandle = React.forwardRef<
|
|||
for (const handle of dragHandles) {
|
||||
if (handle === null) return;
|
||||
handle.addEventListener('mousedown', startInteraction, { passive: true });
|
||||
handle.addEventListener('touchstart', startInteraction);
|
||||
handle.addEventListener('touchstart', startInteraction, { passive: true });
|
||||
handle.style.touchAction = 'none';
|
||||
}
|
||||
removeEventListenersRef.current = () => {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import React, { forwardRef, useEffect, useMemo, useState } from 'react';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { combineLatest, skip } from 'rxjs';
|
||||
|
||||
import { useEuiTheme } from '@elastic/eui';
|
||||
|
@ -27,8 +27,12 @@ export interface GridPanelProps {
|
|||
gridLayoutStateManager: GridLayoutStateManager;
|
||||
}
|
||||
|
||||
export const GridPanel = forwardRef<HTMLDivElement, GridPanelProps>(
|
||||
({ panelId, rowIndex, renderPanelContents, gridLayoutStateManager }, panelRef) => {
|
||||
export const GridPanel = ({
|
||||
panelId,
|
||||
rowIndex,
|
||||
renderPanelContents,
|
||||
gridLayoutStateManager,
|
||||
}: GridPanelProps) => {
|
||||
const [dragHandleApi, setDragHandleApi] = useState<DragHandleApi | null>(null);
|
||||
const { euiTheme } = useEuiTheme();
|
||||
|
||||
|
@ -161,7 +165,16 @@ export const GridPanel = forwardRef<HTMLDivElement, GridPanelProps>(
|
|||
}, [panelId, renderPanelContents, dragHandleApi]);
|
||||
|
||||
return (
|
||||
<div ref={panelRef} css={initialStyles} className="kbnGridPanel">
|
||||
<div
|
||||
ref={(element) => {
|
||||
if (!gridLayoutStateManager.panelRefs.current[rowIndex]) {
|
||||
gridLayoutStateManager.panelRefs.current[rowIndex] = {};
|
||||
}
|
||||
gridLayoutStateManager.panelRefs.current[rowIndex][panelId] = element;
|
||||
}}
|
||||
css={initialStyles}
|
||||
className="kbnGridPanel"
|
||||
>
|
||||
<DragHandle
|
||||
ref={setDragHandleApi}
|
||||
gridLayoutStateManager={gridLayoutStateManager}
|
||||
|
@ -176,5 +189,4 @@ export const GridPanel = forwardRef<HTMLDivElement, GridPanelProps>(
|
|||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import { cloneDeep } from 'lodash';
|
||||
import React, { forwardRef, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { map, pairwise, skip, combineLatest } from 'rxjs';
|
||||
import { css } from '@emotion/react';
|
||||
|
||||
|
@ -27,8 +27,11 @@ export interface GridRowProps {
|
|||
gridLayoutStateManager: GridLayoutStateManager;
|
||||
}
|
||||
|
||||
export const GridRow = forwardRef<HTMLDivElement, GridRowProps>(
|
||||
({ rowIndex, renderPanelContents, gridLayoutStateManager }, gridRef) => {
|
||||
export const GridRow = ({
|
||||
rowIndex,
|
||||
renderPanelContents,
|
||||
gridLayoutStateManager,
|
||||
}: GridRowProps) => {
|
||||
const currentRow = gridLayoutStateManager.gridLayout$.value[rowIndex];
|
||||
|
||||
const [panelIds, setPanelIds] = useState<string[]>(Object.keys(currentRow.panels));
|
||||
|
@ -38,8 +41,6 @@ export const GridRow = forwardRef<HTMLDivElement, GridRowProps>(
|
|||
const [rowTitle, setRowTitle] = useState<string>(currentRow.title);
|
||||
const [isCollapsed, setIsCollapsed] = useState<boolean>(currentRow.isCollapsed);
|
||||
|
||||
const rowContainer = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
/** Set initial styles based on state at mount to prevent styles from "blipping" */
|
||||
const initialStyles = useMemo(() => {
|
||||
const { columnCount } = gridLayoutStateManager.runtimeSettings$.getValue();
|
||||
|
@ -114,14 +115,12 @@ export const GridRow = forwardRef<HTMLDivElement, GridRowProps>(
|
|||
* the order of rendered panels need to be aligned with how they are displayed in the grid for accessibility
|
||||
* reasons (screen readers and focus management).
|
||||
*/
|
||||
const gridLayoutSubscription = gridLayoutStateManager.gridLayout$.subscribe(
|
||||
(gridLayout) => {
|
||||
const gridLayoutSubscription = gridLayoutStateManager.gridLayout$.subscribe((gridLayout) => {
|
||||
const newPanelIdsInOrder = getKeysInOrder(gridLayout[rowIndex].panels);
|
||||
if (panelIdsInOrder.join() !== newPanelIdsInOrder.join()) {
|
||||
setPanelIdsInOrder(newPanelIdsInOrder);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
return () => {
|
||||
interactionStyleSubscription.unsubscribe();
|
||||
|
@ -147,12 +146,6 @@ export const GridRow = forwardRef<HTMLDivElement, GridRowProps>(
|
|||
rowIndex={rowIndex}
|
||||
gridLayoutStateManager={gridLayoutStateManager}
|
||||
renderPanelContents={renderPanelContents}
|
||||
ref={(element) => {
|
||||
if (!gridLayoutStateManager.panelRefs.current[rowIndex]) {
|
||||
gridLayoutStateManager.panelRefs.current[rowIndex] = {};
|
||||
}
|
||||
gridLayoutStateManager.panelRefs.current[rowIndex][panelId] = element;
|
||||
}}
|
||||
/>
|
||||
),
|
||||
}),
|
||||
|
@ -162,7 +155,6 @@ export const GridRow = forwardRef<HTMLDivElement, GridRowProps>(
|
|||
|
||||
return (
|
||||
<div
|
||||
ref={rowContainer}
|
||||
css={css`
|
||||
height: 100%;
|
||||
`}
|
||||
|
@ -182,7 +174,9 @@ export const GridRow = forwardRef<HTMLDivElement, GridRowProps>(
|
|||
{!isCollapsed && (
|
||||
<div
|
||||
className={'kbnGridRow'}
|
||||
ref={gridRef}
|
||||
ref={(element: HTMLDivElement | null) =>
|
||||
(gridLayoutStateManager.rowRefs.current[rowIndex] = element)
|
||||
}
|
||||
css={css`
|
||||
height: 100%;
|
||||
display: grid;
|
||||
|
@ -199,5 +193,4 @@ export const GridRow = forwardRef<HTMLDivElement, GridRowProps>(
|
|||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue