media-query-debugger
Version:
Advanced responsive debugger and responsive design testing tool with device mockups, media query monitoring, and debugging features for React applications
576 lines (564 loc) • 24.9 kB
JavaScript
"use client";
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
DEFAULT_BREAKPOINTS: () => DEFAULT_BREAKPOINTS,
DEFAULT_DEVICES: () => DEFAULT_DEVICES,
DeviceMockup: () => DeviceMockup,
ErrorBoundary: () => ErrorBoundary,
ResponsiveDebugger: () => ResponsiveDebugger,
cn: () => cn,
useBreakpoint: () => useBreakpoint,
useMediaQuery: () => useMediaQuery,
useViewport: () => useViewport
});
module.exports = __toCommonJS(index_exports);
// src/components/ResponsiveDebugger.tsx
var import_react6 = require("react");
var import_lucide_react3 = require("lucide-react");
// src/hooks/useViewport.ts
var import_react = require("react");
function useViewport() {
const [viewport, setViewport] = (0, import_react.useState)({
width: 0,
height: 0,
aspectRatio: 0,
devicePixelRatio: 1,
orientation: "portrait"
});
(0, import_react.useEffect)(() => {
if (typeof window === "undefined") return;
const updateViewport = () => {
const width = window.innerWidth;
const height = window.innerHeight;
setViewport({
width,
height,
aspectRatio: width / height,
devicePixelRatio: window.devicePixelRatio || 1,
orientation: width > height ? "landscape" : "portrait"
});
};
updateViewport();
window.addEventListener("resize", updateViewport);
window.addEventListener("orientationchange", updateViewport);
return () => {
window.removeEventListener("resize", updateViewport);
window.removeEventListener("orientationchange", updateViewport);
};
}, []);
return viewport;
}
// src/hooks/useBreakpoint.ts
var import_react3 = require("react");
// src/hooks/useMediaQuery.ts
var import_react2 = require("react");
function useMediaQuery(query, options = {}) {
const { defaultMatches = false, matchMedia } = options;
const [matches, setMatches] = (0, import_react2.useState)(defaultMatches);
(0, import_react2.useEffect)(() => {
if (typeof window === "undefined") return;
const mediaQueryList = (matchMedia || window.matchMedia)(query);
const updateMatches = () => setMatches(mediaQueryList.matches);
updateMatches();
if (mediaQueryList.addEventListener) {
mediaQueryList.addEventListener("change", updateMatches);
return () => mediaQueryList.removeEventListener("change", updateMatches);
} else {
mediaQueryList.addListener(updateMatches);
return () => mediaQueryList.removeListener(updateMatches);
}
}, [query, matchMedia]);
return matches;
}
// src/constants/index.ts
var DEFAULT_BREAKPOINTS = {
sm: 640,
md: 768,
lg: 1024,
xl: 1280,
"2xl": 1536
};
var DEFAULT_DEVICES = [
{
name: "iPhone 14 Pro",
width: 393,
height: 852,
category: "mobile",
pixelRatio: 3,
userAgent: "iPhone"
},
{
name: "iPhone SE",
width: 375,
height: 667,
category: "mobile",
pixelRatio: 2,
userAgent: "iPhone"
},
{
name: "Samsung Galaxy S23",
width: 384,
height: 854,
category: "mobile",
pixelRatio: 3,
userAgent: "Android"
},
{
name: "iPad Air",
width: 820,
height: 1180,
category: "tablet",
pixelRatio: 2,
userAgent: "iPad"
},
{
name: "iPad Pro 12.9",
width: 1024,
height: 1366,
category: "tablet",
pixelRatio: 2,
userAgent: "iPad"
},
{
name: "MacBook Air",
width: 1440,
height: 900,
category: "desktop",
pixelRatio: 2,
userAgent: "MacOS"
},
{
name: "MacBook Pro 16",
width: 1728,
height: 1117,
category: "desktop",
pixelRatio: 2,
userAgent: "MacOS"
},
{
name: "Desktop 1080p",
width: 1920,
height: 1080,
category: "desktop",
pixelRatio: 1,
userAgent: "Desktop"
},
{
name: "Desktop 4K",
width: 3840,
height: 2160,
category: "desktop",
pixelRatio: 2,
userAgent: "Desktop"
}
];
var KEYBOARD_SHORTCUTS = {
toggle: "cmd+shift+d",
close: "escape"
};
// src/hooks/useBreakpoint.ts
function useBreakpoint(options = {}) {
const { breakpoints = DEFAULT_BREAKPOINTS, defaultBreakpoint = "xs" } = options;
const [currentBreakpoint, setCurrentBreakpoint] = (0, import_react3.useState)(defaultBreakpoint);
const breakpointQueries = Object.entries(breakpoints).map(([name, width]) => ({
name,
width
}));
const queries = breakpointQueries.map((bp) => useMediaQuery(`(min-width: ${bp.width}px)`));
(0, import_react3.useEffect)(() => {
const matchingBreakpoints = breakpointQueries.filter((bp, index) => queries[index]).sort((a, b) => b.width - a.width);
const newBreakpoint = matchingBreakpoints.length > 0 ? matchingBreakpoints[0].name : defaultBreakpoint;
if (newBreakpoint !== currentBreakpoint) {
setCurrentBreakpoint(newBreakpoint);
}
}, [queries.join(","), currentBreakpoint, defaultBreakpoint]);
return {
current: currentBreakpoint,
breakpoints: breakpointQueries.reduce(
(acc, bp, index) => ({
...acc,
[bp.name]: queries[index]
}),
{}
),
isAbove: (breakpoint) => {
const targetWidth = breakpoints[breakpoint];
if (!targetWidth) return false;
return breakpointQueries.some((bp, index) => bp.width >= targetWidth && queries[index]);
},
isBelow: (breakpoint) => {
const targetWidth = breakpoints[breakpoint];
if (!targetWidth) return false;
return !breakpointQueries.some((bp, index) => bp.width >= targetWidth && queries[index]);
}
};
}
// src/lib/utils.ts
var import_clsx = require("clsx");
var import_tailwind_merge = require("tailwind-merge");
function cn(...inputs) {
return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
}
// src/components/DebuggerPanel.tsx
var import_react4 = require("react");
var import_lucide_react = require("lucide-react");
function DebuggerPanel({
breakpoints,
devices,
viewport,
breakpoint,
theme,
isMinimized,
onMinimize,
onClose
}) {
const [activeTab, setActiveTab] = (0, import_react4.useState)("breakpoints");
return /* @__PURE__ */ React.createElement("div", { className: "w-[420px] max-h-[85vh] overflow-hidden" }, /* @__PURE__ */ React.createElement("div", { className: "bg-slate-900/95 backdrop-blur-xl border border-slate-700/50 shadow-2xl rounded-lg" }, /* @__PURE__ */ React.createElement("div", { className: "p-4 border-b border-slate-700/50" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement("div", { className: "w-8 h-8 rounded-lg bg-gradient-to-r from-blue-600/20 to-purple-600/20 flex items-center justify-center" }, /* @__PURE__ */ React.createElement(import_lucide_react.Monitor, { className: "w-4 h-4 text-blue-400" })), /* @__PURE__ */ React.createElement("h3", { className: "text-lg font-semibold text-slate-100" }, "Breakpoint Debugger")), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React.createElement(
"button",
{
onClick: () => onMinimize(!isMinimized),
className: "w-8 h-8 text-slate-400 hover:text-slate-200 hover:bg-slate-800 rounded flex items-center justify-center transition-colors"
},
isMinimized ? /* @__PURE__ */ React.createElement(import_lucide_react.ChevronUp, { className: "w-4 h-4" }) : /* @__PURE__ */ React.createElement(import_lucide_react.ChevronDown, { className: "w-4 h-4" })
), /* @__PURE__ */ React.createElement(
"button",
{
onClick: onClose,
className: "w-8 h-8 text-slate-400 hover:text-slate-200 hover:bg-slate-800 rounded flex items-center justify-center transition-colors"
},
/* @__PURE__ */ React.createElement(import_lucide_react.X, { className: "w-4 h-4" })
))), /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between pt-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "bg-gradient-to-r from-blue-600/20 to-purple-600/20 border border-blue-500/30 text-blue-300 px-2 py-1 rounded text-sm" }, breakpoint.current.toUpperCase()), /* @__PURE__ */ React.createElement("span", { className: "text-sm font-mono text-slate-400" }, viewport.width, " \xD7 ", viewport.height)), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React.createElement("div", { className: "w-2 h-2 rounded-full bg-green-400 animate-pulse" }), /* @__PURE__ */ React.createElement("span", { className: "text-xs text-slate-400" }, "Live")))), !isMinimized && /* @__PURE__ */ React.createElement("div", { className: "p-0" }, /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-4 bg-slate-800/50 border-b border-slate-700/50" }, [
{ id: "breakpoints", label: "Breakpoints", icon: import_lucide_react.Zap },
{ id: "devices", label: "Devices", icon: import_lucide_react.Smartphone },
{ id: "mockups", label: "Mockups", icon: import_lucide_react.Eye },
{ id: "tools", label: "Tools", icon: import_lucide_react.Settings }
].map((tab) => {
const Icon = tab.icon;
return /* @__PURE__ */ React.createElement(
"button",
{
key: tab.id,
onClick: () => setActiveTab(tab.id),
className: cn(
"flex items-center justify-center gap-1 px-3 py-2 text-xs transition-colors",
activeTab === tab.id ? "bg-slate-700 text-slate-200" : "text-slate-400 hover:text-slate-200 hover:bg-slate-800/50"
)
},
/* @__PURE__ */ React.createElement(Icon, { className: "w-3 h-3" }),
tab.label
);
})), /* @__PURE__ */ React.createElement("div", { className: "max-h-96 overflow-y-auto p-4" }, activeTab === "breakpoints" && /* @__PURE__ */ React.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React.createElement("h4", { className: "text-sm font-medium text-slate-200" }, "Current Breakpoint"), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-1 h-4" }, Object.entries(breakpoints).map(([name, width]) => /* @__PURE__ */ React.createElement(
"div",
{
key: name,
className: cn(
"h-full flex-1 rounded-sm transition-all duration-300",
breakpoint.current === name ? "bg-gradient-to-r from-blue-500 to-purple-500" : "bg-slate-600"
),
title: `${name}: ${width}px`
}
))), /* @__PURE__ */ React.createElement("div", { className: "flex justify-between text-xs text-slate-500" }, /* @__PURE__ */ React.createElement("span", null, "xs"), Object.keys(breakpoints).map((name) => /* @__PURE__ */ React.createElement("span", { key: name }, name)))), /* @__PURE__ */ React.createElement("div", { className: "h-px bg-slate-700/50" }), /* @__PURE__ */ React.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React.createElement("h4", { className: "text-sm font-medium text-slate-200" }, "Media Query Status"), /* @__PURE__ */ React.createElement("div", { className: "space-y-2" }, Object.entries(breakpoints).map(([name, width]) => /* @__PURE__ */ React.createElement("div", { key: name, className: "flex items-center justify-between" }, /* @__PURE__ */ React.createElement("code", { className: "text-xs bg-slate-800/50 text-slate-300 px-2 py-1 rounded border border-slate-700/50" }, "(min-width: ", width, "px)"), /* @__PURE__ */ React.createElement(
"div",
{
className: cn(
"text-xs px-2 py-1 rounded",
breakpoint.breakpoints[name] ? "bg-green-600/20 border border-green-500/30 text-green-300" : "bg-slate-700/50 border border-slate-600/50 text-slate-400"
)
},
breakpoint.breakpoints[name] ? "Active" : "Inactive"
)))))), activeTab === "devices" && /* @__PURE__ */ React.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React.createElement("h4", { className: "text-sm font-medium text-slate-200" }, "Device Presets"), /* @__PURE__ */ React.createElement("div", { className: "grid gap-2" }, devices.map((device) => /* @__PURE__ */ React.createElement(
"div",
{
key: device.name,
className: "flex items-center justify-between p-3 rounded-lg border bg-slate-800/30 border-slate-700/50 hover:bg-slate-800/50 hover:border-slate-600/50 transition-all duration-200"
},
/* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React.createElement(
"div",
{
className: cn(
"w-8 h-8 rounded-lg flex items-center justify-center",
device.category === "mobile" ? "bg-green-600/20" : device.category === "tablet" ? "bg-blue-600/20" : "bg-purple-600/20"
)
},
/* @__PURE__ */ React.createElement(
import_lucide_react.Smartphone,
{
className: cn(
"w-4 h-4",
device.category === "mobile" ? "text-green-400" : device.category === "tablet" ? "text-blue-400" : "text-purple-400"
)
}
)
), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("span", { className: "text-sm font-medium text-slate-200" }, device.name), /* @__PURE__ */ React.createElement("div", { className: "text-xs text-slate-400" }, device.userAgent))),
/* @__PURE__ */ React.createElement("div", { className: "text-right" }, /* @__PURE__ */ React.createElement("span", { className: "text-xs font-mono text-slate-400" }, device.width, "\xD7", device.height), /* @__PURE__ */ React.createElement("div", { className: "text-xs text-slate-500" }, device.pixelRatio, "x DPR"))
))))))));
}
// src/components/ErrorBoundary.tsx
var import_react5 = require("react");
var import_lucide_react2 = require("lucide-react");
var ErrorBoundary = class extends import_react5.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
componentDidCatch(error, errorInfo) {
console.error("Breakpoint Debugger Error:", error, errorInfo);
this.props.onError?.(error, errorInfo);
}
render() {
if (this.state.hasError) {
if (this.props.fallback) {
return this.props.fallback;
}
return /* @__PURE__ */ React.createElement("div", { className: "fixed bottom-6 right-6 z-50 w-96" }, /* @__PURE__ */ React.createElement("div", { className: "bg-red-900/20 border border-red-500/30 backdrop-blur-xl rounded-lg p-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 text-red-400 mb-3" }, /* @__PURE__ */ React.createElement(import_lucide_react2.AlertTriangle, { className: "w-5 h-5" }), /* @__PURE__ */ React.createElement("h3", { className: "font-semibold" }, "Debugger Error")), /* @__PURE__ */ React.createElement("p", { className: "text-sm text-red-300 mb-3" }, "The breakpoint debugger encountered an error. This might be due to browser compatibility or a temporary issue."), /* @__PURE__ */ React.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React.createElement(
"button",
{
onClick: () => this.setState({ hasError: false }),
className: "flex items-center gap-2 px-3 py-1 bg-red-600 hover:bg-red-700 text-white rounded text-sm transition-colors"
},
/* @__PURE__ */ React.createElement(import_lucide_react2.RefreshCw, { className: "w-4 h-4" }),
"Retry"
), /* @__PURE__ */ React.createElement(
"button",
{
onClick: () => window.location.reload(),
className: "px-3 py-1 border border-red-500/30 text-red-400 hover:bg-red-900/20 rounded text-sm transition-colors"
},
"Reload Page"
))));
}
return this.props.children;
}
};
// src/components/ResponsiveDebugger.tsx
function ResponsiveDebugger({
breakpoints = DEFAULT_BREAKPOINTS,
devices = DEFAULT_DEVICES,
position = "bottom-right",
theme = "dark",
defaultOpen = false,
className,
style,
onBreakpointChange,
onViewportChange,
enableKeyboardShortcuts = true,
keyboardShortcuts = KEYBOARD_SHORTCUTS
}) {
const [isOpen, setIsOpen] = (0, import_react6.useState)(defaultOpen);
const [isMinimized, setIsMinimized] = (0, import_react6.useState)(false);
const viewport = useViewport();
const breakpoint = useBreakpoint({ breakpoints });
(0, import_react6.useEffect)(() => {
if (!enableKeyboardShortcuts) return;
const handleKeyDown = (event) => {
const { toggle, close } = keyboardShortcuts;
if (event.key === "Escape" && close === "escape" && isOpen) {
setIsOpen(false);
return;
}
if (toggle === "cmd+shift+d" && event.metaKey && event.shiftKey && event.key === "D") {
event.preventDefault();
setIsOpen(!isOpen);
}
};
document.addEventListener("keydown", handleKeyDown);
return () => document.removeEventListener("keydown", handleKeyDown);
}, [enableKeyboardShortcuts, keyboardShortcuts, isOpen]);
(0, import_react6.useEffect)(() => {
onBreakpointChange?.(breakpoint.current);
}, [breakpoint.current, onBreakpointChange]);
(0, import_react6.useEffect)(() => {
onViewportChange?.(viewport);
}, [viewport, onViewportChange]);
const getPositionClasses = () => {
switch (position) {
case "top-left":
return "top-6 left-6";
case "top-right":
return "top-6 right-6";
case "bottom-left":
return "bottom-6 left-6";
case "bottom-right":
default:
return "bottom-6 right-6";
}
};
const getBadgePosition = () => {
switch (position) {
case "top-left":
return "top-24 left-6";
case "top-right":
return "top-24 right-6";
case "bottom-left":
return "bottom-24 left-6";
case "bottom-right":
default:
return "bottom-24 right-6";
}
};
if (!isOpen) {
return /* @__PURE__ */ React.createElement(ErrorBoundary, null, /* @__PURE__ */ React.createElement(
"button",
{
onClick: () => setIsOpen(true),
className: cn(
"fixed z-50 w-16 h-16 rounded-full shadow-2xl transition-all duration-200 hover:scale-105",
"bg-gradient-to-r from-slate-700 to-slate-800 hover:from-slate-600 hover:to-slate-700",
"border border-slate-600/50 backdrop-blur-sm",
"flex items-center justify-center",
getPositionClasses(),
className
),
style,
title: "Open Breakpoint Debugger (\u2318\u21E7D)"
},
/* @__PURE__ */ React.createElement(import_lucide_react3.Monitor, { className: "w-7 h-7 text-slate-200" })
), /* @__PURE__ */ React.createElement("div", { className: cn("fixed z-50", getBadgePosition()) }, /* @__PURE__ */ React.createElement("div", { className: "bg-slate-900/90 text-slate-200 backdrop-blur-sm border border-slate-700/50 px-3 py-1 rounded-full text-sm font-mono" }, breakpoint.current.toUpperCase(), " \u2022 ", viewport.width, "\xD7", viewport.height)));
}
return /* @__PURE__ */ React.createElement(ErrorBoundary, null, /* @__PURE__ */ React.createElement("div", { className: cn("fixed z-50", getPositionClasses(), className), style }, /* @__PURE__ */ React.createElement(
DebuggerPanel,
{
breakpoints,
devices,
viewport,
breakpoint,
theme,
isMinimized,
onMinimize: setIsMinimized,
onClose: () => setIsOpen(false)
}
)));
}
// src/components/DeviceMockup.tsx
var import_react7 = require("react");
var import_lucide_react4 = require("lucide-react");
function DeviceMockup({
device,
scale = 0.5,
isRotated = false,
url,
onClose,
onScaleChange,
onRotate,
className,
style
}) {
const [isFullscreen, setIsFullscreen] = (0, import_react7.useState)(false);
const iframeRef = (0, import_react7.useRef)(null);
const currentWidth = isRotated ? device.height : device.width;
const currentHeight = isRotated ? device.width : device.height;
const currentUrl = url || (typeof window !== "undefined" ? window.location.origin : "");
const handleRotate = () => {
const newRotated = !isRotated;
onRotate?.(newRotated);
};
const handleScaleChange = (newScale) => {
onScaleChange?.(newScale);
};
return /* @__PURE__ */ React.createElement(
"div",
{
className: cn(
"fixed inset-0 z-50 bg-slate-900/80 backdrop-blur-sm flex items-center justify-center p-4",
isFullscreen && "p-0",
className
),
style
},
/* @__PURE__ */ React.createElement("div", { className: "absolute top-4 right-4 z-60 flex items-center gap-2" }, /* @__PURE__ */ React.createElement("div", { className: "bg-slate-800/90 backdrop-blur-sm rounded-lg p-2 border border-slate-700/50" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 text-sm text-slate-300 mb-2" }, /* @__PURE__ */ React.createElement("span", null, device.name), /* @__PURE__ */ React.createElement("span", { className: "text-slate-500" }, "\u2022"), /* @__PURE__ */ React.createElement("span", { className: "font-mono text-xs" }, currentWidth, "\xD7", currentHeight)), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement(
"button",
{
onClick: handleRotate,
className: "text-slate-400 hover:text-slate-200 h-8 w-8 p-0 flex items-center justify-center rounded hover:bg-slate-700/50 transition-colors",
title: "Rotate device"
},
/* @__PURE__ */ React.createElement(import_lucide_react4.RotateCcw, { className: "w-4 h-4" })
), /* @__PURE__ */ React.createElement(
"button",
{
onClick: () => setIsFullscreen(!isFullscreen),
className: "text-slate-400 hover:text-slate-200 h-8 w-8 p-0 flex items-center justify-center rounded hover:bg-slate-700/50 transition-colors",
title: "Toggle fullscreen"
},
isFullscreen ? /* @__PURE__ */ React.createElement(import_lucide_react4.Minimize2, { className: "w-4 h-4" }) : /* @__PURE__ */ React.createElement(import_lucide_react4.Maximize2, { className: "w-4 h-4" })
), /* @__PURE__ */ React.createElement(
"button",
{
onClick: onClose,
className: "text-slate-400 hover:text-slate-200 h-8 w-8 p-0 flex items-center justify-center rounded hover:bg-slate-700/50 transition-colors",
title: "Close mockup"
},
/* @__PURE__ */ React.createElement(import_lucide_react4.X, { className: "w-4 h-4" })
)))),
/* @__PURE__ */ React.createElement("div", { className: "transition-all duration-300" }, device.category === "mobile" && /* @__PURE__ */ React.createElement(
"div",
{
className: "relative bg-slate-900 rounded-[2.5rem] p-2 shadow-2xl border-4 border-slate-800",
style: {
width: (currentWidth + 40) * scale,
height: (currentHeight + 80) * scale
}
},
/* @__PURE__ */ React.createElement(
"div",
{
className: "w-full h-full bg-white rounded-[2rem] overflow-hidden relative",
style: {
width: currentWidth * scale,
height: currentHeight * scale
}
},
/* @__PURE__ */ React.createElement(
"iframe",
{
ref: iframeRef,
src: currentUrl,
className: "w-full h-full border-none",
style: {
transform: `scale(${scale})`,
transformOrigin: "top left",
width: `${100 / scale}%`,
height: `${100 / scale}%`
},
title: `${device.name} Mockup`
}
)
)
))
);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
DEFAULT_BREAKPOINTS,
DEFAULT_DEVICES,
DeviceMockup,
ErrorBoundary,
ResponsiveDebugger,
cn,
useBreakpoint,
useMediaQuery,
useViewport
});
//# sourceMappingURL=index.js.map