Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EuiFlyoutResizable] Add resizable flyout #7439

Merged
merged 7 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelogs/upcoming/7439.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Added a new `EuiFlyoutResizable` component
46 changes: 46 additions & 0 deletions src-docs/src/views/flyout/flyout_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
EuiFlyoutBody,
EuiFlyoutHeader,
EuiFlyoutFooter,
EuiFlyoutResizable,
EuiCallOut,
EuiLink,
} from '../../../../src/components';
Expand Down Expand Up @@ -37,6 +38,9 @@ const flyoutWithBannerSource = require('!!raw-loader!./flyout_banner');
import FlyoutPush from './flyout_push';
const flyoutPushSource = require('!!raw-loader!./flyout_push');

import FlyoutResizable from './flyout_resizable';
const flyoutResizableSource = require('!!raw-loader!./flyout_resizable');

const flyOutSnippet = `<EuiFlyout onClose={closeFlyout}>
<EuiFlyoutHeader hasBorder aria-labelledby={flyoutHeadingId}>
<EuiTitle>
Expand Down Expand Up @@ -144,6 +148,18 @@ const flyoutPushedSnippet = `<EuiFlyout type="push" onClose={closeFlyout}>
</EuiFlyout>
`;

const flyoutResizableSnippet = `<EuiFlyoutResizable onClose={closeFlyout} maxWidth={1000} minWidth={300}>
<EuiFlyoutHeader hasBorder aria-labelledby={flyoutHeadingId}>
<EuiTitle>
<h2 id={flyoutHeadingId}>Flyout title</h2>
</EuiTitle>
</EuiFlyoutHeader>
<EuiFlyoutBody>
<!-- Flyout content -->
</EuiFlyoutBody>
</EuiFlyout>
`;

export const FlyoutExample = {
title: 'Flyout',
sections: [
Expand Down Expand Up @@ -384,5 +400,35 @@ export const FlyoutExample = {
demo: <FlyoutMaxWidth />,
props: { EuiFlyout },
},
{
title: 'Resizable flyouts',
source: [
{
type: GuideSectionTypes.JS,
code: flyoutResizableSource,
},
],
text: (
<>
<p>
You can use <strong>EuiFlyoutResizable</strong> to render a flyout
that users can drag with their mouse or use arrow keys to resize.
This may be useful for scenarios where the space the user needs can
be unpredictable, if content is dynamic. Resizable flyouts allow
users to adjust content to better fit their individual screens and
workflows.
</p>
<p>
We strongly recommend setting reasonable numerical{' '}
<EuiCode>minWidth</EuiCode> and <EuiCode>maxWidth</EuiCode> props
based on the flyout content and page content that you <em>can</em>{' '}
predict.
</p>
</>
),
snippet: flyoutResizableSnippet,
demo: <FlyoutResizable />,
props: { EuiFlyoutResizable },
},
],
};
89 changes: 89 additions & 0 deletions src-docs/src/views/flyout/flyout_resizable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import React, { useState } from 'react';

import {
EuiFlyoutResizable,
EuiFlyoutProps,
EuiFlyoutBody,
EuiFlyoutHeader,
EuiButton,
EuiButtonGroup,
EuiText,
EuiTitle,
EuiSpacer,
} from '../../../../src/components';

import { useGeneratedHtmlId } from '../../../../src/services';

export default () => {
const [isFlyoutVisible, setIsFlyoutVisible] = useState(false);
const [flyoutType, setFlyoutType] = useState('overlay');
const [flyoutSide, setFlyoutSide] = useState('right');

const flyoutTitleId = useGeneratedHtmlId({
prefix: 'simpleFlyoutTitle',
});

let flyout;

if (isFlyoutVisible) {
flyout = (
<EuiFlyoutResizable
type={flyoutType as EuiFlyoutProps['type']}
side={flyoutSide as EuiFlyoutProps['side']}
onClose={() => setIsFlyoutVisible(false)}
aria-labelledby={flyoutTitleId}
>
<EuiFlyoutHeader hasBorder>
<EuiTitle size="m">
<h2 id={flyoutTitleId}>A resizable flyout</h2>
</EuiTitle>
</EuiFlyoutHeader>
<EuiFlyoutBody>
<EuiText>
<p>
This flyout is resizable by both mouse drag and arrow keys (when
the resizable edge is focused). Both push and overlay flyouts can
be resizable, on either side.
</p>
</EuiText>
<EuiSpacer />
<EuiTitle size="xxs">
<h3>Flyout type</h3>
</EuiTitle>
<EuiSpacer size="s" />
<EuiButtonGroup
legend="Flyout type"
options={[
{ id: 'overlay', label: 'Overlay' },
{ id: 'push', label: 'Push' },
]}
idSelected={flyoutType}
onChange={(id) => setFlyoutType(id)}
/>
<EuiSpacer />
<EuiTitle size="xxs">
<h3>Flyout side</h3>
</EuiTitle>
<EuiButtonGroup
legend="Flyout side"
options={[
{ id: 'right', label: 'Right' },
{ id: 'left', label: 'Left' },
]}
idSelected={flyoutSide}
onChange={(id) => setFlyoutSide(id)}
/>
</EuiFlyoutBody>
</EuiFlyoutResizable>
);
}

return (
<>
<EuiButton onClick={() => setIsFlyoutVisible(true)}>
Show resizable flyout
</EuiButton>
{flyout}
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
exports[`EuiCollapsibleNavBeta renders 1`] = `
<body
class="euiBody--hasFlyout"
style="padding-left: 0px;"
style="padding-inline-start: 0px;"
>
<div>
<div
Expand Down Expand Up @@ -56,7 +56,7 @@ exports[`EuiCollapsibleNavBeta renders 1`] = `
exports[`EuiCollapsibleNavBeta renders initialIsCollapsed 1`] = `
<body
class="euiBody--hasFlyout"
style="padding-left: 0px;"
style="padding-inline-start: 0px;"
>
<div>
<div
Expand Down
8 changes: 4 additions & 4 deletions src/components/flyout/flyout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,9 @@ export const EuiFlyout = forwardRef(
*/
if (isPushed) {
if (side === 'right') {
document.body.style.paddingRight = `${dimensions.width}px`;
document.body.style.paddingInlineEnd = `${dimensions.width}px`;
} else if (side === 'left') {
document.body.style.paddingLeft = `${dimensions.width}px`;
document.body.style.paddingInlineStart = `${dimensions.width}px`;
}
}

Expand All @@ -237,9 +237,9 @@ export const EuiFlyout = forwardRef(

if (isPushed) {
if (side === 'right') {
document.body.style.paddingRight = '';
document.body.style.paddingInlineEnd = '';
} else if (side === 'left') {
document.body.style.paddingLeft = '';
document.body.style.paddingInlineStart = '';
}
}
};
Expand Down
Loading
Loading