[Unified Histogram] Update Unified Histogram to use EuiResizableContainer onResizeStart and onResizeEnd callbacks (#148699)

## Summary

This PR updates `panels_resizable` to use the new `onResizeStart` and
`onResizeEnd` callbacks on `EuiResizableContainer` instead of
implementing a custom solution.

Resolved #140542.

### Checklist

- [ ] ~Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)~
- [ ]
~[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials~
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [ ] ~Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard
accessibility](https://webaim.org/techniques/keyboard/))~
- [ ] ~Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))~
- [ ] ~If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)~
- [ ] ~This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))~
- [ ] ~This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)~

### For maintainers

- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

Co-authored-by: Julia Rechkunova <julia.rechkunova@elastic.co>
This commit is contained in:
Davis McPhee 2023-01-16 16:26:54 -04:00 committed by GitHub
parent 2cb2fe8a3b
commit 801fed27dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 76 additions and 81 deletions

View file

@ -176,22 +176,19 @@ describe('Panels resizable', () => {
const attachTo = document.createElement('div');
document.body.appendChild(attachTo);
const component = mountComponent({ attachTo });
const wrapper = component.find('[data-test-subj="unifiedHistogramResizableContainerWrapper"]');
const getContainer = () =>
component.find('[data-test-subj="unifiedHistogramResizableContainer"]').at(0);
const resizeButton = component.find('button[data-test-subj="unifiedHistogramResizableButton"]');
const resizeButtonInner = component.find(
'[data-test-subj="unifiedHistogramResizableButtonInner"]'
);
const mouseEvent = {
pageX: 0,
pageY: 0,
clientX: 0,
clientY: 0,
};
resizeButtonInner.simulate('mousedown', mouseEvent);
resizeButton.simulate('mousedown', mouseEvent);
act(() => {
const onResizeStart = getContainer().prop('onResizeStart') as Function;
onResizeStart('pointer');
});
(resizeButton.getDOMNode() as HTMLElement).focus();
wrapper.simulate('mouseup', mouseEvent);
resizeButton.simulate('click', mouseEvent);
forceRender(component);
act(() => {
const onResizeEnd = getContainer().prop('onResizeEnd') as Function;
onResizeEnd();
});
expect(resizeButton.getDOMNode()).toHaveFocus();
await waitFor(() => {
expect(resizeButton.getDOMNode()).not.toHaveFocus();

View file

@ -12,6 +12,7 @@ import {
useGeneratedHtmlId,
useResizeObserver,
} from '@elastic/eui';
import type { ResizeTrigger } from '@elastic/eui/src/components/resizable_container/types';
import { css } from '@emotion/react';
import { isEqual, round } from 'lodash';
import type { ReactElement, RefObject } from 'react';
@ -51,24 +52,23 @@ export const PanelsResizable = ({
// end to toggle the rendering of a transparent overlay which prevents the cancellation.
// EUI issue: https://github.com/elastic/eui/issues/6199
const [resizeWithPortalsHackIsResizing, setResizeWithPortalsHackIsResizing] = useState(false);
const enableResizeWithPortalsHack = () => setResizeWithPortalsHackIsResizing(true);
const disableResizeWithPortalsHack = () => setResizeWithPortalsHackIsResizing(false);
const resizeWithPortalsHackFillCss = css`
const enableResizeWithPortalsHack = useCallback(
() => setResizeWithPortalsHackIsResizing(true),
[]
);
const disableResizeWithPortalsHack = useCallback(
() => setResizeWithPortalsHackIsResizing(false),
[]
);
const resizeWithPortalsHackButtonCss = css`
z-index: 3;
`;
const resizeWithPortalsHackOverlayCss = css`
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
`;
const resizeWithPortalsHackButtonCss = css`
z-index: 3;
`;
const resizeWithPortalsHackButtonInnerCss = css`
${resizeWithPortalsHackFillCss}
z-index: 1;
`;
const resizeWithPortalsHackOverlayCss = css`
${resizeWithPortalsHackFillCss}
z-index: 2;
`;
@ -133,11 +133,26 @@ export const PanelsResizable = ({
}
}, [containerHeight, minMainPanelHeight, minTopPanelHeight, panelSizes, topPanelHeight]);
const onResizeEnd = () => {
const onResizeStart = useCallback(
(trigger: ResizeTrigger) => {
if (trigger !== 'pointer') {
return;
}
enableResizeWithPortalsHack();
},
[enableResizeWithPortalsHack]
);
const onResizeEnd = useCallback(() => {
if (!resizeWithPortalsHackIsResizing) {
return;
}
// We don't want the resize button to retain focus after the resize is complete,
// but EuiResizableContainer will force focus it onClick. To work around this we
// use setTimeout to wait until after onClick has been called before blurring.
if (resizeWithPortalsHackIsResizing && document.activeElement instanceof HTMLElement) {
if (document.activeElement instanceof HTMLElement) {
const button = document.activeElement;
setTimeout(() => {
button.blur();
@ -145,7 +160,7 @@ export const PanelsResizable = ({
}
disableResizeWithPortalsHack();
};
}, [disableResizeWithPortalsHack, resizeWithPortalsHackIsResizing]);
const { euiTheme } = useEuiTheme();
const buttonCss = css`
@ -156,57 +171,40 @@ export const PanelsResizable = ({
`;
return (
<div
className="eui-fullHeight"
onMouseUp={onResizeEnd}
onMouseLeave={onResizeEnd}
onTouchEnd={onResizeEnd}
data-test-subj="unifiedHistogramResizableContainerWrapper"
<EuiResizableContainer
className={className}
direction="vertical"
onPanelWidthChange={onPanelSizeChange}
onResizeStart={onResizeStart}
onResizeEnd={onResizeEnd}
data-test-subj="unifiedHistogramResizableContainer"
>
<EuiResizableContainer
className={className}
direction="vertical"
onPanelWidthChange={onPanelSizeChange}
data-test-subj="unifiedHistogramResizableContainer"
>
{(EuiResizablePanel, EuiResizableButton) => (
<>
<EuiResizablePanel
id={topPanelId}
minSize={`${minTopPanelHeight}px`}
size={panelSizes.topPanelSize}
paddingSize="none"
data-test-subj="unifiedHistogramResizablePanelTop"
>
{topPanel}
</EuiResizablePanel>
<EuiResizableButton
css={[resizeWithPortalsHackButtonCss, buttonCss]}
data-test-subj="unifiedHistogramResizableButton"
>
<span
onMouseDown={enableResizeWithPortalsHack}
onTouchStart={enableResizeWithPortalsHack}
css={resizeWithPortalsHackButtonInnerCss}
data-test-subj="unifiedHistogramResizableButtonInner"
/>
</EuiResizableButton>
<EuiResizablePanel
minSize={`${minMainPanelHeight}px`}
size={panelSizes.mainPanelSize}
paddingSize="none"
data-test-subj="unifiedHistogramResizablePanelMain"
>
{mainPanel}
</EuiResizablePanel>
{resizeWithPortalsHackIsResizing ? (
<div css={resizeWithPortalsHackOverlayCss} />
) : (
<></>
)}
</>
)}
</EuiResizableContainer>
</div>
{(EuiResizablePanel, EuiResizableButton) => (
<>
<EuiResizablePanel
id={topPanelId}
minSize={`${minTopPanelHeight}px`}
size={panelSizes.topPanelSize}
paddingSize="none"
data-test-subj="unifiedHistogramResizablePanelTop"
>
{topPanel}
</EuiResizablePanel>
<EuiResizableButton
css={[resizeWithPortalsHackButtonCss, buttonCss]}
data-test-subj="unifiedHistogramResizableButton"
/>
<EuiResizablePanel
minSize={`${minMainPanelHeight}px`}
size={panelSizes.mainPanelSize}
paddingSize="none"
data-test-subj="unifiedHistogramResizablePanelMain"
>
{mainPanel}
</EuiResizablePanel>
{resizeWithPortalsHackIsResizing ? <div css={resizeWithPortalsHackOverlayCss} /> : <></>}
</>
)}
</EuiResizableContainer>
);
};