Manages state for overlay triggers in React Spectrum applications, providing methods to control overlay visibility
npx @tessl/cli install tessl/npm-react-stately--overlays@3.6.0React Stately Overlays provides state management for overlay triggers in React applications. It's part of Adobe's React Spectrum ecosystem and follows the library's architectural pattern of separating state logic from UI implementation. The package exports a single hook that manages the open/closed state of overlays like popovers, tooltips, modals, and dropdowns.
npm install @react-stately/overlaysimport { useOverlayTriggerState } from "@react-stately/overlays";
import type { OverlayTriggerProps, OverlayTriggerState } from "@react-stately/overlays";For CommonJS:
const { useOverlayTriggerState } = require("@react-stately/overlays");import React from "react";
import { useOverlayTriggerState } from "@react-stately/overlays";
function PopoverTrigger() {
// Uncontrolled usage
const state = useOverlayTriggerState({
defaultOpen: false,
onOpenChange: (isOpen) => console.log('Overlay is now:', isOpen ? 'open' : 'closed')
});
return (
<div>
<button onClick={state.toggle}>
{state.isOpen ? 'Close' : 'Open'} Popover
</button>
{state.isOpen && (
<div className="popover">
<p>Popover content</p>
<button onClick={state.close}>Close</button>
</div>
)}
</div>
);
}
// Controlled usage
function ControlledOverlay() {
const [isOpen, setIsOpen] = React.useState(false);
const state = useOverlayTriggerState({
isOpen,
onOpenChange: setIsOpen
});
return (
<div>
<button onClick={state.toggle}>Toggle Modal</button>
{state.isOpen && (
<div className="modal">
<p>Modal content</p>
<button onClick={state.close}>Close</button>
</div>
)}
</div>
);
}React Stately Overlays follows React Spectrum's separation of concerns pattern:
useCallback, controlled state)Manages state for an overlay trigger, tracking whether the overlay is open and providing methods to control its visibility.
/**
* Manages state for an overlay trigger. Tracks whether the overlay is open, and provides
* methods to toggle this state.
*/
function useOverlayTriggerState(props: OverlayTriggerProps): OverlayTriggerState;
interface OverlayTriggerProps {
/** Whether the overlay is open by default (controlled). */
isOpen?: boolean;
/** Whether the overlay is open by default (uncontrolled). */
defaultOpen?: boolean;
/** Handler that is called when the overlay's open state changes. */
onOpenChange?: (isOpen: boolean) => void;
}
interface OverlayTriggerState {
/** Whether the overlay is currently open. */
readonly isOpen: boolean;
/** Sets whether the overlay is open. */
setOpen(isOpen: boolean): void;
/** Opens the overlay. */
open(): void;
/** Closes the overlay. */
close(): void;
/** Toggles the overlay's visibility. */
toggle(): void;
}Usage Patterns:
// Uncontrolled - manages its own state
const state = useOverlayTriggerState({
defaultOpen: false,
onOpenChange: (isOpen) => {
// Optional callback when state changes
console.log('Overlay state changed:', isOpen);
}
});
// Controlled - state managed externally
const [isModalOpen, setIsModalOpen] = React.useState(false);
const modalState = useOverlayTriggerState({
isOpen: isModalOpen,
onOpenChange: setIsModalOpen
});
// Access state and methods
console.log(state.isOpen); // current open/closed state
state.open(); // programmatically open
state.close(); // programmatically close
state.toggle(); // toggle current state
state.setOpen(true); // set specific stateThe hook uses React's useControlledState utility internally to handle both controlled and uncontrolled modes seamlessly, and useCallback to ensure stable function references for optimal performance.