@yamada-ui/react
Version:
React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion
99 lines (95 loc) • 3.62 kB
JavaScript
"use client";
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
const require_utils_index = require('../../utils/index.cjs');
const require_environment_provider = require('../../core/system/environment-provider.cjs');
const require_system_provider = require('../../core/system/system-provider.cjs');
let react = require("react");
react = require_rolldown_runtime.__toESM(react);
//#region src/hooks/use-breakpoint/use-breakpoint.ts
/**
* `useBreakpoint` is a custom hook that returns the current breakpoint.
* This hook monitors changes in the window size and returns the appropriate value.
*
* @see https://yamada-ui.com/docs/hooks/use-breakpoint
*/
const useBreakpoint = () => {
const animationFrameId = (0, react.useRef)(0);
const { breakpoints, config } = require_system_provider.useSystem();
const { getWindow } = require_environment_provider.useEnvironment();
const { containerRef, direction = "down", identifier = "@media screen" } = config.breakpoint ?? {};
const hasContainer = !!containerRef;
const queries = (0, react.useMemo)(() => {
return breakpoints.queries.map(({ breakpoint, maxW, minMaxQuery, minW }) => {
const searchValue = identifier === "@media screen" ? "@media screen and " : `${identifier} `;
return {
breakpoint,
maxW,
minW,
query: minMaxQuery?.replace(searchValue, "") ?? ""
};
});
}, [breakpoints, identifier]);
const hasQueries = !!queries.length;
const getBreakpoint = (0, react.useCallback)((width) => {
if ((0, require_utils_index.utils_exports.isUndefined)(width)) {
const win = getWindow();
if (hasContainer || !hasQueries) return "base";
for (const { breakpoint, query } of queries) if ((win?.matchMedia(query))?.matches) return breakpoint;
} else for (const { breakpoint, maxW, minW } of queries) if (direction !== "up") {
if ((minW ?? 0) <= width) return breakpoint;
} else if (width <= (maxW ?? Infinity)) return breakpoint;
return "base";
}, [
direction,
getWindow,
hasContainer,
hasQueries,
queries
]);
const breakpointRef = (0, react.useRef)(getBreakpoint());
const subscribe = (0, react.useCallback)((listener) => {
if (!hasContainer || !hasQueries) {
const observer = queries.map(({ breakpoint, query }) => {
const mql = getWindow()?.matchMedia(query);
const onChange = (e) => {
if (e.matches) breakpointRef.current = breakpoint;
listener();
};
mql?.addEventListener("change", onChange);
return () => {
mql?.removeEventListener("change", onChange);
};
});
return () => {
observer.forEach((unobserve) => unobserve());
};
} else if ((0, require_utils_index.utils_exports.createdDom)()) {
const observer = new ResizeObserver(([entry]) => {
if (!entry) return;
cancelAnimationFrame(animationFrameId.current);
const { width } = entry.contentRect;
breakpointRef.current = getBreakpoint(width);
animationFrameId.current = requestAnimationFrame(listener);
});
if (containerRef.current) observer.observe(containerRef.current);
return () => {
observer.disconnect();
if (process.env.NODE_ENV !== "test") cancelAnimationFrame(animationFrameId.current);
};
} else return require_utils_index.utils_exports.noop;
}, [
containerRef,
getBreakpoint,
getWindow,
hasContainer,
hasQueries,
queries
]);
const getSnapshot = (0, react.useCallback)(() => {
return breakpointRef.current;
}, []);
return (0, react.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
};
//#endregion
exports.useBreakpoint = useBreakpoint;
//# sourceMappingURL=use-breakpoint.cjs.map