@assistant-ui/react-devtools
Version:
React development tools for assistant-ui components
177 lines (176 loc) • 5.8 kB
JavaScript
"use client";
// src/DevToolsModal.tsx
import { useEffect, useMemo, useState, useSyncExternalStore } from "react";
import { DevToolsFrame } from "./DevToolsFrame.js";
import { getStyles, ANIMATION_STYLES } from "./styles/DevToolsModal.styles.js";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
var isDarkMode = () => {
if (typeof document === "undefined") return false;
return document.documentElement.classList.contains("dark") || document.body.classList.contains("dark");
};
var subscribeToThemeChanges = (callback) => {
if (typeof MutationObserver === "undefined") {
return () => {
};
}
const observer = new MutationObserver(callback);
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ["class"]
});
if (document.body !== document.documentElement) {
observer.observe(document.body, {
attributes: true,
attributeFilter: ["class"]
});
}
return () => observer.disconnect();
};
var DevToolsModalImpl = () => {
const [isOpen, setIsOpen] = useState(false);
const [buttonHover, setButtonHover] = useState(false);
const [closeHover, setCloseHover] = useState(false);
const darkMode = useSyncExternalStore(
subscribeToThemeChanges,
isDarkMode,
() => false
// Server-side always returns false
);
const styles = useMemo(() => getStyles(darkMode), [darkMode]);
useEffect(() => {
if (typeof document === "undefined") return;
const styleId = "devtools-modal-animations";
if (!document.getElementById(styleId)) {
const style = document.createElement("style");
style.id = styleId;
style.textContent = ANIMATION_STYLES;
document.head.appendChild(style);
}
return () => {
const style = document.getElementById(styleId);
if (style && !document.querySelector("[data-devtools-modal]")) {
style.remove();
}
};
}, []);
useEffect(() => {
if (!isOpen) return;
const handleEscape = (event) => {
if (event.key === "Escape") {
setIsOpen(false);
}
};
document.addEventListener("keydown", handleEscape);
return () => document.removeEventListener("keydown", handleEscape);
}, [isOpen]);
return /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx("div", { style: styles.floatingContainer, children: /* @__PURE__ */ jsx(
"button",
{
onClick: () => setIsOpen(true),
onMouseEnter: () => setButtonHover(true),
onMouseLeave: () => setButtonHover(false),
style: {
...styles.floatingButton,
...buttonHover ? styles.floatingButtonHover : {}
},
"aria-label": "Open assistant-ui DevTools",
title: "Open assistant-ui DevTools",
children: /* @__PURE__ */ jsx(
"svg",
{
width: "20",
height: "20",
viewBox: "0 0 24 24",
fill: "none",
xmlns: "http://www.w3.org/2000/svg",
style: { width: "20px", height: "20px" },
children: /* @__PURE__ */ jsx(
"path",
{
d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z",
stroke: "currentColor",
strokeWidth: "1.8",
strokeLinecap: "round",
strokeLinejoin: "round",
fill: "none"
}
)
}
)
}
) }),
isOpen && /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx("div", { style: styles.backdrop, onClick: () => setIsOpen(false) }),
/* @__PURE__ */ jsxs("div", { style: styles.modal, "data-devtools-modal": true, children: [
/* @__PURE__ */ jsx(
"button",
{
onClick: () => setIsOpen(false),
onMouseEnter: () => setCloseHover(true),
onMouseLeave: () => setCloseHover(false),
style: {
...styles.dismissButton,
...closeHover ? styles.dismissButtonHover : {}
},
"aria-label": "Close DevTools",
children: /* @__PURE__ */ jsxs(
"svg",
{
width: "14",
height: "14",
viewBox: "0 0 24 24",
fill: "none",
xmlns: "http://www.w3.org/2000/svg",
children: [
/* @__PURE__ */ jsx(
"path",
{
d: "M18 6L6 18",
stroke: "currentColor",
strokeWidth: "1.6",
strokeLinecap: "round",
strokeLinejoin: "round"
}
),
/* @__PURE__ */ jsx(
"path",
{
d: "M6 6L18 18",
stroke: "currentColor",
strokeWidth: "1.6",
strokeLinecap: "round",
strokeLinejoin: "round"
}
)
]
}
)
}
),
/* @__PURE__ */ jsx("div", { style: styles.modalContent, children: /* @__PURE__ */ jsx(
DevToolsFrame,
{
style: {
width: "100%",
height: "100%",
border: "none",
borderRadius: "12px",
backgroundColor: "transparent"
}
}
) })
] })
] })
] });
};
var DevToolsModal = () => {
if (typeof process !== "undefined" && process.env?.["NODE_ENV"] === "production") {
return null;
}
return /* @__PURE__ */ jsx(DevToolsModalImpl, {});
};
export {
DevToolsModal
};
//# sourceMappingURL=DevToolsModal.js.map