Skip to content
Draft
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
File renamed without changes.
118 changes: 0 additions & 118 deletions src/Popover/index.jsx

This file was deleted.

119 changes: 119 additions & 0 deletions src/Popover/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import React from 'react';
import classNames from 'classnames';
import BasePopover from 'react-bootstrap/Popover';
import BasePopoverTitle from 'react-bootstrap/PopoverTitle';
import BasePopoverContent from 'react-bootstrap/PopoverContent';
import { ArrowProps } from 'react-bootstrap/esm/Overlay';

type PlacementVariant = 'auto' | 'top' | 'bottom' | 'left' | 'right';

interface PopoverProps {
/** An html id attribute, necessary for accessibility. */
id: string;
/**
* Sets the direction the Popover is positioned towards.
*
* This is generally provided by the `Overlay` component positioning the popover.
*/
placement?: PlacementVariant;
/**
* When this prop is set, it creates a `Popover` with
* a `Popover.Title` inside passing the children directly to it.
*/
title?: string;
/**
* An `Overlay` injected set of props for positioning the popover arrow.
*
* This is generally provided by the `Overlay` component positioning the popover.
*/
arrowProps?: ArrowProps;
/**
* When this prop is set, it creates a `Popover` with
* a `Popover.Content` inside passing the children directly to it.
*/
content?: boolean;
/** A `Popper.js` config object passed to the the underlying popper instance. */
popper?: Record<string, any>;
/** Whether the `Overlay` is shown. */
show?: boolean;
/** Specifies the content of the `Overlay` */
children?: React.ReactNode;
/** Specifies class name to append to the base element */
className?: string;
/** The visual style of the `Overlay` */
variant?: string;
/** Specifies the base element */
as?: React.ElementType;
/** Overrides underlying component base CSS class name */
bsPrefix?: string;
}

interface PopoverSubcomponentProps {
/** Specifies the base element */
as?: React.ElementType;
/** Overrides underlying component base CSS class name */
bsPrefix?: string;
/** Specifies class name to append to the base element */
className?: string;
/** Specifies the content of the component */
children?: React.ReactNode;
}

const Popover = React.forwardRef<HTMLDivElement, PopoverProps>(({
children,
variant,
placement = 'right',
title,
arrowProps,
content,
popper,
show,
className,
...props
}, ref) => (
<BasePopover
{...props}
placement={placement}
title={title}
arrowProps={arrowProps}
content={content}
popper={popper}
show={show}
className={classNames({ [`popover-${variant}`]: !!variant }, className)}
ref={ref}
>
{children}
</BasePopover>
));

function PopoverTitle({
as = 'div',
bsPrefix = 'popover-header',
...props
}: PopoverSubcomponentProps) {
return <BasePopoverTitle as={as} bsPrefix={bsPrefix} {...props} />;
}

function PopoverContent({
as = 'div',
bsPrefix = 'popover-body',
...props
}: PopoverSubcomponentProps) {
return <BasePopoverContent as={as} bsPrefix={bsPrefix} {...props} />;
}

Popover.displayName = 'Popover';
PopoverTitle.displayName = 'Popover.Title';
PopoverContent.displayName = 'Popover.Content';

// Create the compound component with proper typing
const PopoverWithSubcomponents = Object.assign(Popover, {
Title: PopoverTitle,
Content: PopoverContent,
}) as typeof Popover & {
Title: typeof PopoverTitle;
Content: typeof PopoverContent;
};

export { PopoverTitle, PopoverContent };
export default PopoverWithSubcomponents;
3 changes: 1 addition & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export { default as ModalContext } from './Modal/ModalContext';
export { default as ModalDialog } from './Modal/ModalDialog';
export { default as ModalLayer } from './Modal/ModalLayer';
export { default as Overlay, OverlayTrigger } from './Overlay';
export { default as Popover, PopoverTitle, PopoverContent } from './Popover';
export { default as Portal } from './Modal/Portal';
export { default as Spinner } from './Spinner';
export { default as Stack } from './Stack';
Expand Down Expand Up @@ -146,8 +147,6 @@ export {
// @ts-ignore: has yet to be converted to TypeScript
} from './Pagination';
// @ts-ignore: has yet to be converted to TypeScript
export { default as Popover, PopoverTitle, PopoverContent } from './Popover';
// @ts-ignore: has yet to be converted to TypeScript
export { default as ProgressBar } from './ProgressBar';
// @ts-ignore: has yet to be converted to TypeScript
export { default as ProductTour } from './ProductTour';
Expand Down