Documentation index for AI agents (llms.txt). Markdown versions of every page are available by appending .md to the page URL. The full corpus is at /llms-full.txt.

Hooks

Cherry exports utility hooks alongside its components.

useOnClickOutside

Calls a callback when a click lands outside all of the given elements. Useful for dismissing menus, popovers, and other floating UI. Cherry's own Modal uses it to close on outside clicks.

useOnClickOutside(refs: RefObject<HTMLElement | null>[], cb: () => void): void
"use client";
import React, { useRef, useState } from "react";
import { useOnClickOutside, Button } from "cherry-styled-components";

export default function Menu() {
  const [open, setOpen] = useState(false);
  const menuRef = useRef(null);
  const buttonRef = useRef(null);

  useOnClickOutside([menuRef, buttonRef], () => setOpen(false));

  return (
    <>
      <Button ref={buttonRef} onClick={() => setOpen(!open)}>
        Menu
      </Button>
      {open && <div ref={menuRef}>...</div>}
    </>
  );
}

Behavior details:

  • Listens for mousedown on the document and fires the callback when the click target is inside none of the passed refs.
  • Unattached refs (with a null current value) are ignored: a click counts as outside unless it lands inside a currently mounted ref target.
  • The document listener is subscribed once per mount. You can safely pass inline arrays and inline callbacks; the hook keeps the latest values in a ref instead of re-subscribing on every render.

Parameters

refsRefObject<HTMLElement | null>[]required

Refs to the elements that count as "inside". Clicks within any of them do not trigger the callback.

cb() => voidrequired

Callback invoked when a click lands outside all ref targets.

useMediaQuery

Subscribes to a CSS media query and returns whether it currently matches. Returns false on the server and during the first client render so hydration matches, then re-renders with the real match.

useMediaQuery(query: string): boolean
"use client";
import { useMediaQuery } from "cherry-styled-components";

export default function Layout({ children }) {
  const prefersReducedMotion = useMediaQuery(
    "(prefers-reduced-motion: reduce)",
  );
  // ...
}

Pass a full media query string, e.g. "(max-width: 991px)".

useBelowBreakpoint

True while the viewport is narrower than the named Cherry breakpoint (xs, sm, md, lg, xl, xxl, xxxl) - the inverse of the mq() helper's min-width query. Use it for behavior that has to change below a breakpoint; for styling, stay with mq() in CSS.

useBelowBreakpoint(size: keyof Breakpoints): boolean

The chat kit's ChatPanel uses it to turn the desktop drawer into a full-screen modal below lg.

useLockBodyScroll

Freezes body scrolling while the flag is true - the hook behind modal overlays like Modal and the modal states of ChatPanel.

useLockBodyScroll(isLocked: boolean): void

Locks are reference-counted, so overlapping overlays compose: the body is only released once the last holder lets go, and a pre-existing inline overflow style on <body> is restored afterwards.