kibana/packages/kbn-resizable-layout
Davis McPhee e54bf7a0fe
[ResizableLayout] Remove onResizeEnd stable callback workaround (#176030)
## Summary

This PR reverts the `onResizeEnd` stable callback workaround introduced
in #174955 to account for an EUI bug now that
https://github.com/elastic/eui/pull/7468 has been merged and Kibana was
upgraded to v92.2.1 in #175849.

### 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
- [ ] [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
- [ ] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
- [ ] 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)
2024-02-01 09:46:26 -04:00
..
src [ResizableLayout] Remove onResizeEnd stable callback workaround (#176030) 2024-02-01 09:46:26 -04:00
index.ts [Discover] Add resize support to the Discover field list sidebar (#167066) 2023-09-27 21:52:25 -03:00
jest.config.js [Discover] Add resize support to the Discover field list sidebar (#167066) 2023-09-27 21:52:25 -03:00
kibana.jsonc [Discover] Add resize support to the Discover field list sidebar (#167066) 2023-09-27 21:52:25 -03:00
package.json flag packages without side effects (#173351) 2023-12-19 02:46:39 -07:00
README.md [Discover] Add resize support to the Discover field list sidebar (#167066) 2023-09-27 21:52:25 -03:00
tsconfig.json [Discover] Add resize support to the Discover field list sidebar (#167066) 2023-09-27 21:52:25 -03:00
types.ts [Discover] Add resize support to the Discover field list sidebar (#167066) 2023-09-27 21:52:25 -03:00

@kbn/resizable-layout

A component for creating resizable layouts containing a fixed width panel and a flexible panel, with support for horizontal and vertical layouts.

Example

Note

For advanced usage see the example plugin.

import { useIsWithinBreakpoints } from '@elastic/eui';
import { css } from '@emotion/react';
import {
  ResizableLayout,
  ResizableLayoutDirection,
  ResizableLayoutMode,
} from '@kbn/resizable-layout';
import React, { useRef, useState } from 'react';
// Using react-reverse-portal is recommended for complex/heavy layouts to prevent
// re-mounting panel components when the layout switches from resizable to static
import { createHtmlPortalNode, InPortal, OutPortal } from 'react-reverse-portal';

export const ResizablePage = () => {
  const [fixedPanelSize, setFixedPanelSize] = useState(500);
  const [container, setContainer] = useState<HTMLDivElement | null>(null);
  const [fixedPanelNode] = useState(() =>
    createHtmlPortalNode({ attributes: { class: 'eui-fullHeight' } })
  );
  const [flexPanelNode] = useState(() =>
    createHtmlPortalNode({ attributes: { class: 'eui-fullHeight' } })
  );

  const isMobile = useIsWithinBreakpoints(['xs']);
  const layoutMode = isMobile ? ResizableLayoutMode.Static : ResizableLayoutMode.Resizable;
  const layoutDirection = isMobile
    ? ResizableLayoutDirection.Vertical
    : ResizableLayoutDirection.Horizontal;

  const fullWidthAndHeightCss = css`
    position: relative;
    width: 100%;
    height: 100%;
  `;
  const panelBaseCss = css`
    ${fullWidthAndHeightCss}
    padding: 20px;
  `;
  const fixedPanelCss = css`
    ${panelBaseCss}
    background-color: rgb(255 0 0 / 30%);
  `;
  const flexPanelCss = css`
    ${panelBaseCss}
    background-color: rgb(0 0 255 / 30%);
  `;

  return (
    <div ref={setContainer} css={fullWidthAndHeightCss}>
      <InPortal node={fixedPanelNode}>
        <div css={fixedPanelCss}>
          This is the fixed width panel. It will remain the same size when resizing the window until
          the flexible panel reaches its minimum size.
        </div>
      </InPortal>
      <InPortal node={flexPanelNode}>
        <div css={flexPanelCss}>
          This is the flexible width panel. It will resize as the window resizes until it reaches
          its minimum size.
        </div>
      </InPortal>
      <ResizableLayout
        mode={layoutMode}
        direction={layoutDirection}
        container={container}
        fixedPanelSize={fixedPanelSize}
        minFixedPanelSize={300}
        minFlexPanelSize={500}
        fixedPanel={<OutPortal node={fixedPanelNode} />}
        flexPanel={<OutPortal node={flexPanelNode} />}
        onFixedPanelSizeChange={setFixedPanelSize}
      />
    </div>
  );
};