@itwin/itwinui-react
Version:
A react component library for iTwinUI
191 lines (190 loc) • 7.25 kB
TypeScript
import * as React from 'react';
import { FloatingFocusManager } from '@floating-ui/react';
import type { Placement, UseFloatingOptions, UseHoverProps, UseClickProps, UseFocusProps, UseDismissProps } from '@floating-ui/react';
import type { PolymorphicForwardRefComponent } from '../../utils/index.js';
import type { PortalProps } from '../../utils/components/Portal.js';
type PopoverOptions = {
/**
* Placement of the popover content.
* @default 'bottom-start'
*/
placement?: Placement;
/**
* Controlled flag for whether the popover is visible.
*/
visible?: boolean;
/**
* Callback invoked every time the popover visibility *changes* (uncontrolled mode) or should *change*
* (controlled mode) as a result of internal logic.
*
* Should be used alongside `visible` prop.
*/
onVisibleChange?: (visible: boolean) => void;
/**
* If true, the popover will close when clicking outside it.
*
* @default true
*/
closeOnOutsideClick?: boolean;
/**
* Middleware options.
*
* By default, `flip`, `shift`, `size`, and `hide` are enabled.
*
* If the floating content gets hidden even when it shouldn't (e.g. some custom styles interfering with the trigger's
* hide detection) consider disabling the `hide` middleware.
*
* @see https://floating-ui.com/docs/middleware
*/
middleware?: {
offset?: number;
flip?: boolean;
shift?: boolean;
size?: boolean | {
/**
* Override the maximum height of the popover. Must be a CSS-compatible value.
* @default "400px"
*/
maxHeight?: string;
};
autoPlacement?: boolean;
hide?: boolean;
inline?: boolean;
};
};
type PopoverInternalProps = {
/**
* autoUpdate options that recalculates position
* to ensure the floating element remains anchored
* to its reference element, such as when scrolling
* and resizing the screen
*
* https://floating-ui.com/docs/autoUpdate#options
*/
autoUpdateOptions?: {
ancestorScroll?: boolean;
ancestorResize?: boolean;
elementResize?: boolean;
/**
* Use this if you want popover to follow moving trigger element
*/
animationFrame?: boolean;
layoutShift?: boolean;
};
/**
* By default, only the click and dismiss interactions/triggers are enabled.
* Explicitly pass `false` to disable the defaults.
*
* Pass a boolean or an object to enable/disable any of the supported interactions.
* The passed objects can be used to override the default props that the Popover sets for an interaction/trigger.
*
* @example
* const popover = usePopover({
* interactions: {
* click: false,
* focus: true,
* hover: { move: false },
* }
* // …
* });
*/
interactions?: {
click?: boolean | Omit<UseClickProps, 'enabled'>;
dismiss?: boolean | Omit<UseDismissProps, 'enabled'>;
hover?: boolean | Omit<UseHoverProps, 'enabled'>;
focus?: boolean | Omit<UseFocusProps, 'enabled'>;
};
role?: 'dialog' | 'menu' | 'listbox';
/**
* Whether the popover should match the width of the trigger.
*/
matchWidth?: boolean;
} & Omit<UseFloatingOptions, 'middleware' | 'placement'>;
type InitialFocus = React.ComponentPropsWithoutRef<typeof FloatingFocusManager>['initialFocus'];
/** Stores the current open/closed state of the popover. */
export declare const PopoverOpenContext: React.Context<boolean | undefined>;
/**
* Stores the initialFocus of the popover.
*
* E.g. Popover's descendants can disable the popover's initialFocus to prevent conflicts with its own focus management.
*/
export declare const PopoverInitialFocusContext: React.Context<{
setInitialFocus: React.Dispatch<React.SetStateAction<InitialFocus>>;
} | undefined>;
export declare const usePopover: (options: PopoverOptions & PopoverInternalProps) => {
placement: Placement;
strategy: import("@floating-ui/utils").Strategy;
middlewareData: import("@floating-ui/core").MiddlewareData;
x: number;
y: number;
isPositioned: boolean;
update: () => void;
floatingStyles: React.CSSProperties;
refs: {
reference: React.MutableRefObject<import("@floating-ui/react-dom").ReferenceType | null>;
floating: React.MutableRefObject<HTMLElement | null>;
setReference: (node: import("@floating-ui/react-dom").ReferenceType | null) => void;
setFloating: (node: HTMLElement | null) => void;
} & import("@floating-ui/react").ExtendedRefs<import("@floating-ui/react").ReferenceType>;
elements: {
reference: import("@floating-ui/react-dom").ReferenceType | null;
floating: HTMLElement | null;
} & import("@floating-ui/react").ExtendedElements<import("@floating-ui/react").ReferenceType>;
context: {
placement: Placement;
strategy: import("@floating-ui/utils").Strategy;
x: number;
y: number;
middlewareData: import("@floating-ui/core").MiddlewareData;
isPositioned: boolean;
update: () => void;
floatingStyles: React.CSSProperties;
open: boolean;
onOpenChange: (open: boolean, event?: Event, reason?: import("@floating-ui/react").OpenChangeReason) => void;
events: import("@floating-ui/react").FloatingEvents;
dataRef: React.MutableRefObject<import("@floating-ui/react").ContextData>;
nodeId: string | undefined;
floatingId: string | undefined;
refs: import("@floating-ui/react").ExtendedRefs<import("@floating-ui/react").ReferenceType>;
elements: import("@floating-ui/react").ExtendedElements<import("@floating-ui/react").ReferenceType>;
};
open: boolean;
onOpenChange: (value: boolean) => void;
getReferenceProps: (userProps?: React.HTMLProps<HTMLElement>) => Record<string, unknown>;
getFloatingProps: (userProps?: React.HTMLProps<HTMLElement>) => Record<string, unknown>;
};
type PopoverPublicProps = {
/**
* Content displayed inside the popover.
*/
content?: React.ReactNode;
/**
* Element that triggers the popover. Should usually be a button.
*/
children?: React.ReactNode;
/**
* Whether the popover adds recommended CSS (background-color, box-shadow, etc.) to itself.
*
* @default false
*/
applyBackground?: boolean;
/**
* This is used to position the popover relative to a different element than the trigger.
*
* Recommended to use state to store this element, rather than a ref.
*/
positionReference?: HTMLElement;
} & PortalProps & PopoverOptions;
/**
* A utility component to help with positioning of floating content relative to a trigger.
* Built on top of [`floating-ui`](https://floating-ui.com/).
*
* @see https://itwinui.bentley.com/docs/popover
*
* @example
* <Popover content='This is a popover'>
* <Button>Show popover</Button>
* </Popover>
*/
export declare const Popover: PolymorphicForwardRefComponent<"div", PopoverPublicProps>;
export {};