UNPKG

@liveblocks/react-ui

Version:

A set of React pre-built components for the Liveblocks products. Liveblocks is the all-in-one toolkit to build collaborative products like Figma, Notion, and more.

124 lines (121 loc) 4.05 kB
import { jsx } from 'react/jsx-runtime'; import { Slot } from '@radix-ui/react-slot'; import { createContext, forwardRef, useId, useContext, useRef, useEffect, useImperativeHandle } from 'react'; import { useControllableState } from '../../utils/use-controllable-state.js'; const COLLAPSIBLE_ROOT_NAME = "CollapsibleRoot"; const COLLAPSIBLE_TRIGGER_NAME = "CollapsibleTrigger"; const COLLAPSIBLE_CONTENT_NAME = "CollapsibleContent"; const CollapsibleContext = createContext(null); const CollapsibleRoot = forwardRef( ({ open: controlledOpen, onOpenChange: controlledOnOpenChange, defaultOpen, disabled = false, asChild, ...props }, forwardedRef) => { const [isOpen, onOpenChange] = useControllableState( defaultOpen ?? true, controlledOpen, controlledOnOpenChange ); const Component = asChild ? Slot : "div"; const id = useId(); return /* @__PURE__ */ jsx(CollapsibleContext.Provider, { value: { open: isOpen, onOpenChange, disabled, contentId: id }, children: /* @__PURE__ */ jsx(Component, { ...props, ref: forwardedRef, "data-state": isOpen ? "open" : "closed", "data-disabled": disabled ? "" : void 0 }) }); } ); const CollapsibleTrigger = forwardRef( ({ onClick, asChild, ...props }, forwardedRef) => { const Component = asChild ? Slot : "button"; const context = useContext(CollapsibleContext); if (!context) { throw new Error("Collapsible.Root is missing from the React tree."); } const { open, disabled, contentId, onOpenChange } = context; return /* @__PURE__ */ jsx(Component, { ...props, ref: forwardedRef, type: "button", "aria-controls": contentId, "aria-expanded": open || false, "data-state": open ? "open" : "closed", "data-disabled": disabled ? "" : void 0, disabled, onClick: (event) => { onClick?.(event); if (event.defaultPrevented) return; if (disabled) return; onOpenChange(!open); } }); } ); const CollapsibleContent = forwardRef( ({ asChild, ...props }, forwardedRef) => { const Component = asChild ? Slot : "div"; const context = useContext(CollapsibleContext); const divRef = useRef(null); if (!context) { throw new Error("Collapsible.Root is missing from the React tree."); } const { open, onOpenChange, disabled, contentId } = context; useEffect(() => { const element = divRef.current; if (element === null) return; const isHiddenUntilFoundSupported = "onbeforematch" in document.body; if (!isHiddenUntilFoundSupported) return; function handleBeforeMatch() { onOpenChange(true); } element.addEventListener("beforematch", handleBeforeMatch); return () => { element.removeEventListener("beforematch", handleBeforeMatch); }; }, [onOpenChange]); useEffect(() => { const element = divRef.current; if (element === null) return; if (open) return; const isHiddenUntilFoundSupported = "onbeforematch" in document.body; if (!isHiddenUntilFoundSupported) return; element.setAttribute("hidden", "until-found"); return () => { element.removeAttribute("hidden"); }; }, [open]); useImperativeHandle(forwardedRef, () => { return divRef.current; }, []); return /* @__PURE__ */ jsx(Component, { ...props, ref: divRef, "data-state": open ? "open" : "closed", "data-disabled": disabled ? "" : void 0, id: contentId, hidden: !open }); } ); if (process.env.NODE_ENV !== "production") { CollapsibleContent.displayName = COLLAPSIBLE_CONTENT_NAME; CollapsibleRoot.displayName = COLLAPSIBLE_ROOT_NAME; CollapsibleTrigger.displayName = COLLAPSIBLE_TRIGGER_NAME; } export { CollapsibleContent as Content, CollapsibleRoot as Root, CollapsibleTrigger as Trigger }; //# sourceMappingURL=index.js.map