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
mousedownon the document and fires the callback when the click target is inside none of the passed refs. - Unattached refs (with a
nullcurrent 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
Refs to the elements that count as "inside". Clicks within any of them do not trigger the callback.
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): booleanThe 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): voidLocks 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.