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

[EuiBreadcrumbs] Add popoverContent and popoverProps #7031

Merged
merged 8 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
80 changes: 78 additions & 2 deletions src-docs/src/views/breadcrumbs/breadcrumbs_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import { Link } from 'react-router-dom';

import { GuideSectionTypes } from '../../components';

import { EuiBreadcrumbs, EuiCode, EuiText } from '../../../../src/components';
import {
EuiBreadcrumbs,
EuiCode,
EuiText,
EuiCallOut,
} from '../../../../src/components';
import { BreadcrumbProps, BreadcrumbResponsiveMaxCount } from './props';

import { breadcrumbsConfig } from './playground';
Expand All @@ -22,12 +27,14 @@ import TruncateSingle from './truncate_single';
const truncateSingleSource = require('!!raw-loader!./truncate_single');

import Max from './max';
import { EuiCallOut } from '../../../../src/components/call_out';
const maxSource = require('!!raw-loader!./max');

import Color from './color';
const colorSource = require('!!raw-loader!./color');

import PopoverContent from './popover_content';
const popoverContentSource = require('!!raw-loader!./popover_content');

const props = {
EuiBreadcrumbs,
EuiBreadcrumb: BreadcrumbProps,
Expand Down Expand Up @@ -244,6 +251,75 @@ export const BreadcrumbsExample = {
],
demo: <ResponsiveCustom />,
},
{
title: 'Popover content',
text: (
<>
<p>
If you want a breadcrumb that toggles a popover, e.g. for an account
switcher, you can use the <EuiCode>popoverContent</EuiCode> prop for
this purpose. <strong>EuiBreadcrumbs</strong> will automatically
handle rendering a popover indicator and popover accessibility best
practies for you. We recommend using components such as{' '}
<Link to="/navigation/context-menu">
<strong>EuiContextMenu</strong>
</Link>{' '}
or{' '}
<Link to="/display/list-group">
<strong>EuiListGroup</strong>
</Link>{' '}
for displaying popover options, or potentially{' '}
<Link to="/forms/selectable">
<strong>EuiSelectable</strong>
</Link>{' '}
if you have many items that require filtering.
</p>
<p>
You may also pass <EuiCode>popoverProps</EuiCode> with almost any
prop that{' '}
<Link to="/layout/popover">
<strong>EuiPopover</strong>
</Link>{' '}
accepts, such as customizing <EuiCode>panelPaddingSize</EuiCode> or{' '}
<EuiCode>anchorPosition</EuiCode>. However, props that affect
popover state such as <EuiCode>closePopover</EuiCode>,{' '}
<EuiCode>isOpen</EuiCode>, and <EuiCode>button</EuiCode> are not
accepted as they are controlled automatically by{' '}
<strong>EuiBreadcrumbs</strong>.
</p>
<EuiCallOut
color="warning"
iconType="accessibility"
title={
<>
Please note that creating a breadcrumb with a popover will
nullify any passed <EuiCode>href</EuiCode> or{' '}
<EuiCode>onClick</EuiCode> behavior, as the <em>only</em>{' '}
interaction the breadcrumb should have at that point is the
popover toggle.
</>
}
></EuiCallOut>
</>
),
props,
demo: <PopoverContent />,
snippet: `<EuiBreadcrumbs
breadcrumbs={[
{
text: 'My account',
popoverContent: <AccountSwitcher />,
popoverProps: { panelPaddingSize: 's' },
}
]}
/>`,
source: [
{
type: GuideSectionTypes.TSX,
code: popoverContentSource,
},
],
},
{
title: 'Color for emphasis',
text: (
Expand Down
112 changes: 112 additions & 0 deletions src-docs/src/views/breadcrumbs/popover_content.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import React, { useState } from 'react';

import {
EuiBreadcrumbs,
EuiBreadcrumb,
EuiPopoverTitle,
EuiPopoverFooter,
EuiContextMenuPanel,
EuiSelectable,
EuiSelectableOption,
EuiAvatar,
EuiButton,
EuiContextMenuItem,
} from '../../../../src';

export default () => {
const [spaces, setSpaces] = useState<EuiSelectableOption[]>([
{
label: 'My space',
checked: 'on',
prepend: <EuiAvatar type="space" size="s" name="My space" />,
},
{
label: "Jim's space",
prepend: <EuiAvatar type="space" size="s" name="Jim" />,
},
{
label: "Pam's space",
prepend: <EuiAvatar type="space" size="s" name="Pam" />,
},
{
label: "Michael's space",
prepend: <EuiAvatar type="space" size="s" name="Michael" />,
},
{
label: "Dwight's space",
prepend: <EuiAvatar type="space" size="s" name="Dwight" />,
},
]);

const breadcrumbs: EuiBreadcrumb[] = [
{
text: 'My deployment',
popoverContent: (
<>
<EuiPopoverTitle paddingSize="s">Select a deployment</EuiPopoverTitle>
<EuiContextMenuPanel
size="s"
items={[
<EuiContextMenuItem
key="A"
href="#"
onClick={(e) => e.preventDefault()}
>
Go to Deployment A
</EuiContextMenuItem>,
<EuiContextMenuItem
key="B"
href="#"
onClick={(e) => e.preventDefault()}
>
Go to Deployment B
</EuiContextMenuItem>,
<EuiContextMenuItem
key="C"
href="#"
onClick={(e) => e.preventDefault()}
>
Go to all deployments
</EuiContextMenuItem>,
]}
/>
</>
),
popoverProps: { panelPaddingSize: 'none' },
},
{
text: 'My space',
popoverContent: (
<EuiSelectable
singleSelection
options={spaces}
onChange={(newOptions) => setSpaces(newOptions)}
searchable
searchProps={{ placeholder: 'Filter spaces', compressed: true }}
aria-label="Space switcher"
emptyMessage="No spaces available"
noMatchesMessage="No spaces found"
>
{(list, search) => (
<>
<EuiPopoverTitle paddingSize="s">Select a space</EuiPopoverTitle>
<EuiPopoverTitle paddingSize="s">{search}</EuiPopoverTitle>
{list}
<EuiPopoverFooter paddingSize="s">
<EuiButton fullWidth size="s" iconType="gear">
Manage all spaces
</EuiButton>
</EuiPopoverFooter>
</>
)}
</EuiSelectable>
),
popoverProps: { panelPaddingSize: 'none' },
},
{
text: 'Home',
},
];

return <EuiBreadcrumbs breadcrumbs={breadcrumbs} />;
};
107 changes: 107 additions & 0 deletions src/components/breadcrumbs/__snapshots__/breadcrumb.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`EuiBreadcrumbContent renders breadcrumbs with \`popoverContent\` with popovers 1`] = `
<body>
<div>
<div
class="euiPopover euiPopover-isOpen emotion-euiPopover"
data-test-subj="popover"
>
<div
class="euiPopover__anchor css-16vtueo-render"
>
<button
class="euiLink euiBreadcrumb__content emotion-euiLink-subdued-euiBreadcrumb__content-page"
data-test-subj="popoverToggle"
title="Toggles a popover - Clicking this button will toggle a popover dialog."
type="button"
>
Toggles a popover

<span
data-euiicon-type="arrowDown"
>
- Clicking this button will toggle a popover dialog.
</span>
</button>
</div>
</div>
</div>
<div
data-euiportal="true"
>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="0"
/>
<div
data-focus-lock-disabled="false"
>
<div
aria-describedby="generated-id"
aria-live="off"
aria-modal="true"
class="euiPanel euiPanel--plain euiPanel--paddingMedium euiPopover__panel emotion-euiPanel-grow-m-m-plain-euiPopover__panel-isOpen-bottom"
data-autofocus="true"
data-popover-open="true"
data-popover-panel="true"
role="dialog"
style="top: 16px; left: -22px; z-index: 2000;"
tabindex="0"
>
<div
class="euiPopover__arrow emotion-euiPopoverArrow-bottom"
data-popover-arrow="bottom"
style="left: 10px; top: 0px;"
/>
<p
class="emotion-euiScreenReaderOnly"
id="generated-id"
>
You are in a dialog. Press Escape, or tap/click outside the dialog to close.
</p>
<div>
Hello popover world
</div>
</div>
</div>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="0"
/>
</div>
</body>
`;

exports[`EuiBreadcrumbContent renders interactive breadcrumbs with href or onClick 1`] = `
<div>
<a
class="euiLink euiBreadcrumb__content emotion-euiLink-subdued-euiBreadcrumb__content-page"
href="#"
rel="noreferrer"
title="Link"
>
Link
</a>
<button
class="euiLink euiBreadcrumb__content emotion-euiLink-subdued-euiBreadcrumb__content-page"
title="Button"
type="button"
>
Button
</button>
</div>
`;

exports[`EuiBreadcrumbContent renders plain uninteractive breadcrumb text 1`] = `
<div>
<span
class="euiBreadcrumb__content emotion-euiBreadcrumb__content-page-euiTextColor-subdued"
title="Text"
>
Text
</span>
</div>
`;
Loading
Loading