Skip to content

Commit

Permalink
feat: sticky footer section for dropdown (#889)
Browse files Browse the repository at this point in the history
  • Loading branch information
nataliepina authored Dec 1, 2022
1 parent 2d3342b commit 5bbd80e
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 14 deletions.
63 changes: 49 additions & 14 deletions packages/dropdownMenu/components/DropdownMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react";
import { cx } from "@emotion/css";
import { css, cx } from "@emotion/css";
import Downshift, { ControllerStateAndHelpers } from "downshift";
import { Dropdownable } from "../../dropdownable";
import { border, buttonReset, display } from "../../shared/styles/styleUtils";
Expand All @@ -8,6 +8,42 @@ import PopoverListItem from "../../popover/components/PopoverListItem";
import { DropdownSectionProps } from "./DropdownSection";
import { DropdownMenuItemProps } from "./DropdownMenuItem";
import { Direction } from "../../dropdownable/components/Dropdownable";
import {
spaceM,
themeBgPrimary
} from "../../design-tokens/build/js/designTokens";

const stickyFooter = css`
background-color: ${themeBgPrimary};
position: sticky;
bottom: 0;
left: 0;
right: 0;
padding: 2px 0;
width: 100%;
&::before {
content: " ";
top: -17px;
width: inherit;
height: ${spaceM};
position: absolute;
background: linear-gradient(transparent, ${themeBgPrimary});
}
`;

const SectionWrapper = ({ children, footer = false, sectionIndex }) => {
return (
<div
key={`dropdown-${sectionIndex}`}
className={cx(
{ [border("top")]: sectionIndex !== 0 },
{ [stickyFooter]: footer }
)}
>
{children}
</div>
);
};

export interface DropdownMenuProps {
/**
Expand Down Expand Up @@ -95,7 +131,7 @@ const DropdownMenu = (props: DropdownMenuProps) => {
}>(
(acc, item, sectionIndex) => {
const { sections = [] } = acc;
const { children } = item.props;
const { children, footer } = item.props;
const menuItems = React.Children.toArray(
children
) as React.ReactElement[];
Expand All @@ -120,7 +156,16 @@ const DropdownMenu = (props: DropdownMenuProps) => {
});

return {
sections: [...sections, childrenWithKeys],
sections: [
...sections,
<SectionWrapper
footer={footer}
key={`dropdown-${sectionIndex}`}
sectionIndex={sectionIndex}
>
{childrenWithKeys}
</SectionWrapper>
],
menuItemIndex: acc.menuItemIndex
};
},
Expand Down Expand Up @@ -156,17 +201,7 @@ const DropdownMenu = (props: DropdownMenuProps) => {
{ suppressRefError: true }
)}
>
{getDropdownContents(
highlightedIndex,
getItemProps
).sections.map((sectionContent, i) => (
<div
key={`dropdown-${i}`}
className={cx({ [border("top")]: i !== 0 })}
>
{sectionContent}
</div>
))}
{getDropdownContents(highlightedIndex, getItemProps).sections}
</PopoverBox>
}
disablePortal={disablePortal}
Expand Down
4 changes: 4 additions & 0 deletions packages/dropdownMenu/components/DropdownSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ export interface DropdownSectionProps {
children:
| React.ReactElement<DropdownMenuItemProps>
| Array<React.ReactElement<DropdownMenuItemProps>>;
/**
* Allows one section to be a sticky footer within the dropdown
*/
footer?: boolean;
}

const DropdownSection = ({ children }: DropdownSectionProps) => <>{children}</>;
Expand Down
98 changes: 98 additions & 0 deletions packages/dropdownMenu/stories/Dropdown.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { grafanaLogo, kibanaLogo, kubernetesLogo } from "./avatarImgs";
import PrimaryDropdownButton from "../../button/components/PrimaryDropdownButton";
import { DropdownMenuProps } from "../components/DropdownMenu";
import { Direction } from "../../dropdownable/components/Dropdownable";
import { ProductIcons } from "../../icons/dist/product-icons-enum";

export default {
title: "Overlays/DropdownMenu",
Expand Down Expand Up @@ -286,3 +287,100 @@ export const WithIconsAndAvatarsPositionEnd = args => (
</DropdownSection>
</DropdownMenu>
);

export const WithFooterSection = args => (
<DropdownMenu
menuMaxHeight="50vh"
trigger={<PrimaryDropdownButton>Workspaces</PrimaryDropdownButton>}
{...args}
>
<DropdownSection>
<DropdownMenuItem key="workspace1" value="workspace1">
<DropdownMenuItemIcon shape={ProductIcons.Global} />
Global
</DropdownMenuItem>
</DropdownSection>
<DropdownSection>
<DropdownMenuItem key="default-workspace" value="default-workspace">
<DropdownMenuItemIcon shape={ProductIcons.Components} />
Default Workspace
</DropdownMenuItem>
<DropdownMenuItem
key="management-cluster-workspace"
value="management-cluster-workspace"
>
<DropdownMenuItemIcon shape={ProductIcons.Components} />
Management Cluster Workspace
</DropdownMenuItem>
<DropdownMenuItem key="workspace1" value="workspace1">
<DropdownMenuItemIcon shape={ProductIcons.Components} />
Workspace 1
</DropdownMenuItem>
<DropdownMenuItem key="workspace2" value="workspace2">
<DropdownMenuItemIcon shape={ProductIcons.Components} />
Workspace 2
</DropdownMenuItem>
<DropdownMenuItem key="workspace3" value="workspace3">
<DropdownMenuItemIcon shape={ProductIcons.Components} />
Workspace 3
</DropdownMenuItem>
<DropdownMenuItem key="workspace4" value="workspace4">
<DropdownMenuItemIcon shape={ProductIcons.Components} />
Workspace 4
</DropdownMenuItem>
<DropdownMenuItem key="workspace5" value="workspace5">
<DropdownMenuItemIcon shape={ProductIcons.Components} />
Workspace 5
</DropdownMenuItem>
<DropdownMenuItem key="workspace6" value="workspace6">
<DropdownMenuItemIcon shape={ProductIcons.Components} />
Workspace 6
</DropdownMenuItem>
<DropdownMenuItem key="workspace7" value="workspace7">
<DropdownMenuItemIcon shape={ProductIcons.Components} />
Workspace 7
</DropdownMenuItem>
<DropdownMenuItem key="workspace8" value="workspace8">
<DropdownMenuItemIcon shape={ProductIcons.Components} />
Workspace 8
</DropdownMenuItem>
<DropdownMenuItem key="workspace9" value="workspace9">
<DropdownMenuItemIcon shape={ProductIcons.Components} />
Workspace 9
</DropdownMenuItem>
<DropdownMenuItem key="workspace10" value="workspace10">
<DropdownMenuItemIcon shape={ProductIcons.Components} />
Workspace 10
</DropdownMenuItem>
<DropdownMenuItem key="workspace11" value="workspace11">
<DropdownMenuItemIcon shape={ProductIcons.Components} />
Workspace 11
</DropdownMenuItem>
<DropdownMenuItem key="workspace12" value="workspace12">
<DropdownMenuItemIcon shape={ProductIcons.Components} />
Workspace 12
</DropdownMenuItem>
<DropdownMenuItem key="workspace13" value="workspace13">
<DropdownMenuItemIcon shape={ProductIcons.Components} />
Workspace 13
</DropdownMenuItem>
<DropdownMenuItem key="workspace14" value="workspace14">
<DropdownMenuItemIcon shape={ProductIcons.Components} />
Workspace 14
</DropdownMenuItem>
<DropdownMenuItem key="workspace15" value="workspace15">
<DropdownMenuItemIcon shape={ProductIcons.Components} />
Workspace 15
</DropdownMenuItem>
</DropdownSection>

<DropdownSection footer>
<DropdownMenuItem key="create-workspace" value="create-workspace">
Create Workspace
</DropdownMenuItem>
<DropdownMenuItem key="manage-workspaces" value="manage-workspaces">
Manage Workspaces
</DropdownMenuItem>
</DropdownSection>
</DropdownMenu>
);

0 comments on commit 5bbd80e

Please sign in to comment.