Skip to content

Commit

Permalink
LG-3592: SearchResultsMenu popoverProps; footerSlot prop (#1986)
Browse files Browse the repository at this point in the history
* add resolution

* changeset

* rename prop
  • Loading branch information
spark33 authored Sep 19, 2023
1 parent 637089d commit f669836
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 53 deletions.
5 changes: 5 additions & 0 deletions .changeset/fuzzy-roses-heal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@leafygreen-ui/search-input': minor
---

SearchResultMenu now supports a footer slot prop for children rendered under the list of search results. Popover props are also now correctly passed to the Popover component.
128 changes: 76 additions & 52 deletions packages/search-input/src/SearchResultsMenu/SearchResultsMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,60 +26,84 @@ const MAX_MENU_HEIGHT = 256;
export const SearchResultsMenu = React.forwardRef<
HTMLUListElement,
SearchResultsMenuProps
>(({ children, open = false, refEl }: SearchResultsMenuProps, ref) => {
const { theme } = useDarkMode();
const { state } = useSearchInputContext();
>(
(
{
children,
open = false,
refEl,
usePortal,
portalClassName,
portalContainer,
scrollContainer,
footerSlot,
...rest
}: SearchResultsMenuProps,
ref,
) => {
const { theme } = useDarkMode();
const { state } = useSearchInputContext();

const menuWidth = useMemo(
() => refEl.current?.clientWidth ?? 0,
// eslint-disable-next-line react-hooks/exhaustive-deps
[refEl, open],
);
const menuWidth = useMemo(
() => refEl.current?.clientWidth ?? 0,
// eslint-disable-next-line react-hooks/exhaustive-deps
[refEl, open],
);

/** The max height of the menu element */
const availableSpace = useAvailableSpace(refEl);
const maxHeightValue = !isUndefined(availableSpace)
? `${Math.min(availableSpace, MAX_MENU_HEIGHT)}px`
: 'unset';
/** The max height of the menu element */
const availableSpace = useAvailableSpace(refEl);
const maxHeightValue = !isUndefined(availableSpace)
? `${Math.min(availableSpace, MAX_MENU_HEIGHT)}px`
: 'unset';

return (
<Popover
data-testid="lg-search-input-popover"
spacing={spacing[2]}
active={open}
align="bottom"
justify="start"
className={cx(
searchResultsMenuStyles,
searchResultsMenuThemeStyles[theme],
css`
width: ${menuWidth}px;
min-width: ${menuWidth}px;
`,
)}
refEl={refEl}
>
{state === 'loading' ? (
<LoadingOption />
) : (
<ul
role="listbox"
aria-live="polite"
aria-relevant="additions removals"
aria-expanded={open}
ref={ref}
className={cx(
searchResultsListStyles,
css`
max-height: ${maxHeightValue};
`,
)}
>
{React.Children.count(children) ? children : <EmptyOption />}
</ul>
)}
</Popover>
);
});
return (
// @ts-ignore `portalClassName`, `portalContainer` and `scrollContainer` are only passed in when `usePortal` is true.
<Popover
data-testid="lg-search-input-popover"
spacing={spacing[2]}
active={open}
align="bottom"
justify="start"
className={cx(
searchResultsMenuStyles,
searchResultsMenuThemeStyles[theme],
css`
width: ${menuWidth}px;
min-width: ${menuWidth}px;
`,
)}
refEl={refEl}
usePortal={usePortal}
portalClassName={usePortal ? portalClassName : undefined}
portalContainer={usePortal ? portalContainer : null}
scrollContainer={usePortal ? scrollContainer : null}
>
{state === 'loading' ? (
<LoadingOption />
) : (
<>
<ul
role="listbox"
aria-live="polite"
aria-relevant="additions removals"
aria-expanded={open}
ref={ref}
className={cx(
searchResultsListStyles,
css`
max-height: ${maxHeightValue};
`,
)}
{...rest}
>
{React.Children.count(children) ? children : <EmptyOption />}
</ul>
{footerSlot}
</>
)}
</Popover>
);
},
);

SearchResultsMenu.displayName = 'SearchResultsMenu';
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { ReactElement } from 'react';

import { HTMLElementProps } from '@leafygreen-ui/lib';
import { PortalControlProps } from '@leafygreen-ui/popover';
Expand All @@ -7,4 +7,5 @@ export type SearchResultsMenuProps = HTMLElementProps<'ul', HTMLUListElement> &
PortalControlProps & {
refEl: React.RefObject<HTMLElement>;
open?: boolean;
footerSlot?: ReactElement;
};

0 comments on commit f669836

Please sign in to comment.