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

LG-4445: add renderMode and top layer #2482

Merged
merged 6 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
4 changes: 2 additions & 2 deletions chat/input-bar/src/InputBar/InputBar.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { FormEvent, ReactElement } from 'react';
import { TextareaAutosizeProps } from 'react-textarea-autosize';

import { DarkModeProps, HTMLElementProps } from '@leafygreen-ui/lib';
import { PortalControlProps } from '@leafygreen-ui/popover';
import { PopoverRenderModeProps } from '@leafygreen-ui/popover';

export type InputBarProps = HTMLElementProps<'form'> &
DarkModeProps & {
Expand Down Expand Up @@ -48,7 +48,7 @@ export type InputBarProps = HTMLElementProps<'form'> &
/**
* Props passed to the Popover that renders the suggested promps.
*/
dropdownProps?: PortalControlProps;
dropdownProps?: Omit<PopoverRenderModeProps, 'renderMode'>;
};

export type { TextareaAutosizeProps };
4 changes: 2 additions & 2 deletions packages/combobox/src/Combobox/Combobox.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { ReactNode } from 'react';

import { type ChipProps } from '@leafygreen-ui/chip';
import { Either, HTMLElementProps } from '@leafygreen-ui/lib';
import { PortalControlProps } from '@leafygreen-ui/popover';
import { PopoverRenderModeProps } from '@leafygreen-ui/popover';

import {
ComboboxSize,
Expand Down Expand Up @@ -60,7 +60,7 @@ type PartialChipProps = Pick<
>;

export type BaseComboboxProps = Omit<HTMLElementProps<'div'>, 'onChange'> &
PortalControlProps &
PopoverRenderModeProps &
PartialChipProps & {
/**
* Defines the Combobox Options by passing children. Must be `ComboboxOption` or `ComboboxGroup`
Expand Down
4 changes: 2 additions & 2 deletions packages/combobox/src/ComboboxMenu/ComboboxMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useAvailableSpace, useForwardedRef } from '@leafygreen-ui/hooks';
import Icon from '@leafygreen-ui/icon';
import { useDarkMode } from '@leafygreen-ui/leafygreen-provider';
import { palette } from '@leafygreen-ui/palette';
import Popover, { PortalControlProps } from '@leafygreen-ui/popover';
import Popover, { PopoverRenderModeProps } from '@leafygreen-ui/popover';
import { Error } from '@leafygreen-ui/typography';

import { ComboboxProps } from '../Combobox';
Expand All @@ -30,7 +30,7 @@ type ComboboxMenuProps = {
id: string;
labelId: string;
menuWidth: number;
} & PortalControlProps &
} & PopoverRenderModeProps &
Pick<
ComboboxProps<any>,
| 'searchLoadingMessage'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { HTMLElementProps } from '@leafygreen-ui/lib';
import { PopoverProps } from '@leafygreen-ui/popover';
import { PortalControlProps } from '@leafygreen-ui/popover';

export type DatePickerMenuProps = PortalControlProps &
Omit<PopoverProps, 'children'> &
export type DatePickerMenuProps = Omit<
PopoverProps,
'children' | 'renderMode' | 'usePortal'
> &
HTMLElementProps<'div'>;
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ import Popover, { PopoverProps } from '@leafygreen-ui/popover';

import { menuStyles } from './MenuWrapper.styles';

export type MenuWrapperProps = PopoverProps & HTMLElementProps<'div'>;
export type MenuWrapperProps = Omit<
PopoverProps,
'dismissMode' | 'onToggle' | 'renderMode'
> &
HTMLElementProps<'div'>;

/**
* A simple styled popover component
Expand All @@ -24,6 +28,7 @@ export const MenuWrapper = forwardRef<HTMLDivElement, MenuWrapperProps>(
ref={fwdRef}
className={cx(menuStyles[theme], className)}
{...props}
usePortal
>
{/*
* Prevents the opening and closing state of a select dropdown from propagating up
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@ import { AutoComplete, DatePickerState } from './types';

export type ModifiedPopoverProps = Omit<
PopoverProps,
'usePortal' | 'refEl' | 'children' | 'className' | 'active' | 'onClick'
| 'usePortal'
| 'refEl'
| 'children'
| 'className'
| 'active'
| 'onClick'
| 'renderMode'
>;

export type BaseDatePickerProps = {
Expand Down
1 change: 1 addition & 0 deletions packages/guide-cue/src/GuideCue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ function GuideCue({
adjustOnMutation={true}
popoverZIndex={popoverZIndex}
{...sharedProps}
usePortal={true}
>
{/* The beacon is using the popover component to position itself */}
<div
Expand Down
1 change: 1 addition & 0 deletions packages/guide-cue/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type ModifiedTooltipProps = Omit<
| 'refEl'
| 'darkMode'
| 'initialOpen'
| 'renderMode'
>;

interface StandaloneProps {
Expand Down
7 changes: 5 additions & 2 deletions packages/leafygreen-provider/src/LeafyGreenContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ function LeafyGreenProvider({
['portalContainer', 'scrollContainer'].includes(key),
),
);
const popoverContextContainerValues =
const { portalContainer, scrollContainer } =
popoverPortalContainerProp ?? inheritedPopoverContextContainers;

return (
Expand All @@ -74,7 +74,10 @@ function LeafyGreenProvider({
setDarkMode={setDarkMode}
>
<OverlayProvider>
<PopoverProvider {...popoverContextContainerValues}>
<PopoverProvider
portalContainer={portalContainer}
scrollContainer={scrollContainer}
>
{children}
</PopoverProvider>
</OverlayProvider>
Expand Down
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shaneeza What was the initial reasoning for having PopoverContext live in leafygreen-provider instead of within the popover package?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw, I did try moving PopoverContext into the popover package while I was consolidating PortalContext and PopoverContext. Since the consolidated PopoverProvider is included in the global LG provider and the @leafygreen-ui/leafygreen-provider, we can't move PopoverContext into popover without introducing a circular dependency

Original file line number Diff line number Diff line change
Expand Up @@ -15,68 +15,117 @@ type TransitionLifecycleCallbacks = Pick<
'onEnter' | 'onEntering' | 'onEntered' | 'onExit' | 'onExiting' | 'onExited'
>;

type PortalControlProps =
| {
/**
* Specifies that the popover content should be rendered at the end of the DOM,
* rather than in the DOM tree.
*
* default: `true`
*/
usePortal?: true;

/**
* When usePortal is `true`, specifies a class name to apply to the root element of the portal.
*/
portalClassName?: string;

/**
* When usePortal is `true`, specifies an element to portal within. The default behavior is to generate a div at the end of the document to render within.
*/
portalContainer?: HTMLElement | null;

/**
* A ref for the portal element
*/
portalRef?: React.MutableRefObject<HTMLElement | null>;

/**
* When usePortal is `true`, specifies the scrollable element to position relative to.
*/
scrollContainer?: HTMLElement | null;
}
| {
/**
* Specifies that the popover content should be rendered at the end of the DOM,
* rather than in the DOM tree.
*
* default: `true`
*/
usePortal: false;

/**
* When usePortal is `true`, specifies a class name to apply to the root element of the portal.
*/
portalClassName?: undefined;

/**
* When usePortal is `true`, specifies an element to portal within. The default behavior is to generate a div at the end of the document to render within.
*/
portalContainer?: null;

/**
* A ref for the portal element
*/
portalRef?: undefined;

/**
* When usePortal is `true`, specifies the scrollable element to position relative to.
*/
scrollContainer?: null;
};
export const DismissMode = {
Auto: 'auto',
Manual: 'manual',
} as const;
export type DismissMode = (typeof DismissMode)[keyof typeof DismissMode];

/** Local implementation of web-native `ToggleEvent` until we use typescript v5 */
export interface ToggleEvent extends Event {
type: 'toggle';
newState: 'open' | 'closed';
oldState: 'open' | 'closed';
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these types should all live in the popover package

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are they duplicated here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a comment at the top of the file about this. The types can't be shared/imported because of a circular dependency between @leafygreen-ui/leafygreen-provider and @leafygreen-ui/popover


/** @deprecated - use {@link RenderTopLayerProps} */
interface RenderInlineProps {
/**
* Popover element will render inline with the reference element
*/
renderMode: 'inline';

/** Not used in this `renderMode` */
dismissMode?: never;

/** Not used in this `renderMode` */
onToggle?: never;

/** Not used in this `renderMode` */
portalClassName?: never;

/** Not used in this `renderMode` */
portalContainer?: never;

/** Not used in this `renderMode` */
portalRef?: never;

/** Not used in this `renderMode` */
scrollContainer?: never;
}

/** @deprecated - use {@link RenderTopLayerProps} */
interface RenderPortalProps {
/**
* Popover element will render in a provided `portalContainer` or in a new div appended to the body
*/
renderMode?: 'portal';

/** Not used in this `renderMode` */
dismissMode?: never;

/** Not used in this `renderMode` */
onToggle?: never;

/**
* Specifies a class name to apply to the portal element
*/
portalClassName?: string;

/**
* Specifies an element to portal within. If not provided, a div is generated at the end of the body
*/
portalContainer?: HTMLElement | null;

/**
* Passes a ref to forward to the portal element
*/
portalRef?: React.MutableRefObject<HTMLElement | null>;

/**
* Specifies the scrollable element to position relative to
*/
scrollContainer?: HTMLElement | null;
}

interface RenderTopLayerProps {
/**
* Popover element will render in the top layer
*/
renderMode?: 'top-layer';

/**
* Options to control how the popover element is dismissed
* - `'auto'` will automatically handle dismissal on backdrop click or key press, ensuring only one popover is visible at a time
* - `'manual'` will require that the consumer handle dismissal manually
*/
dismissMode?: DismissMode;

/**
* A callback function that is called when the popover is toggled
*/
onToggle?: (e: ToggleEvent) => void;

/** Not used in this `renderMode` */
portalClassName?: never;

/** Not used in this `renderMode` */
portalContainer?: never;

/** Not used in this `renderMode` */
portalRef?: never;

/** Not used in this `renderMode` */
scrollContainer?: never;
}

export type PopoverRenderModeProps =
| RenderInlineProps
| RenderPortalProps
| RenderTopLayerProps;

export type PopoverProviderProps = TransitionLifecycleCallbacks &
PortalControlProps & {
PopoverRenderModeProps & {
/**
* Specifies the amount of spacing (in pixels) between the trigger element and the Popover content.
*
Expand Down
2 changes: 2 additions & 0 deletions packages/leafygreen-provider/src/PopoverContext/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ export {
usePopoverContext,
} from './PopoverContext';
export {
DismissMode,
type PopoverContextType,
type PopoverProviderProps,
type ToggleEvent,
} from './PopoverContext.types';
2 changes: 2 additions & 0 deletions packages/leafygreen-provider/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ export {
useOverlayContext,
} from './OverlayContext';
export {
DismissMode,
PopoverContext,
type PopoverContextType,
PopoverProvider,
type PopoverProviderProps,
type ToggleEvent,
usePopoverContext,
} from './PopoverContext';
export { useBaseFontSize } from './TypographyContext';
Expand Down
4 changes: 2 additions & 2 deletions packages/number-input/src/UnitSelect/UnitSelect.types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {
PopoverProps as ImportedPopoverProps,
PortalControlProps,
PopoverRenderModeProps,
} from '@leafygreen-ui/popover';

import { Size, UnitOption } from '../NumberInput/NumberInput.types';

export type PopoverProps = PortalControlProps &
export type PopoverProps = PopoverRenderModeProps &
Pick<ImportedPopoverProps, 'popoverZIndex'>;

export type UnitSelectProps = {
Expand Down
Loading
Loading