UNPKG

@motion-core/motion-gpu

Version:

Framework-agnostic WebGPU runtime for fullscreen WGSL shaders with explicit Svelte, React, and Vue adapter entrypoints.

195 lines (194 loc) 8.29 kB
import { createMotionGPUErrorOverlayModel } from "../core/error-overlay-model.js"; import { registerErrorOverlay } from "../core/error-overlay-stack.js"; /* empty css */ import { Portal } from "./Portal.js"; import { useEffect, useId, useRef, useState } from "react"; import { jsx, jsxs } from "react/jsx-runtime"; //#region src/lib/react/MotionGPUErrorOverlay.tsx var FOCUSABLE_SELECTOR = "a[href], button:not([disabled]), summary, input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])"; function ChevronDownIcon() { return /* @__PURE__ */ jsx("svg", { className: "motiongpu-error-details-chevron", viewBox: "0 0 18 18", fill: "none", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ jsx("polyline", { points: "15.25 6.5 9 12.75 2.75 6.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }); } function MotionGPUErrorOverlay({ report, onDismiss }) { const model = createMotionGPUErrorOverlayModel(report); const detailsSummary = report.source ? "Additional diagnostics" : "Technical details"; const componentId = useId(); const titleId = `${componentId}-title`; const descriptionId = `${componentId}-description`; const sourceTitleId = `${componentId}-source-title`; const overlayElement = useRef(null); const [dialogElement, setDialogElement] = useState(null); const getFocusableElements = () => { if (!dialogElement) return []; return Array.from(dialogElement.querySelectorAll(FOCUSABLE_SELECTOR)).filter((element) => element.getAttribute("aria-hidden") !== "true"); }; const handleDialogKeyDown = (event) => { if (event.key !== "Tab" || !dialogElement) return; const focusableElements = getFocusableElements(); if (focusableElements.length === 0) { event.preventDefault(); dialogElement.focus({ preventScroll: true }); return; } const firstElement = focusableElements[0]; const lastElement = focusableElements[focusableElements.length - 1]; const activeElement = document.activeElement; const focusIsOutsideDialog = !(activeElement instanceof Node) || !dialogElement.contains(activeElement); if (event.shiftKey && (activeElement === firstElement || activeElement === dialogElement || focusIsOutsideDialog)) { event.preventDefault(); lastElement.focus(); return; } if (!event.shiftKey && (activeElement === lastElement || activeElement === dialogElement || focusIsOutsideDialog)) { event.preventDefault(); firstElement.focus(); } }; useEffect(() => { if (!dialogElement) return; const portalRoot = overlayElement.current?.parentElement; if (!portalRoot) return; return registerErrorOverlay({ dialog: dialogElement, portalRoot, onDismiss }); }, [dialogElement, onDismiss]); return /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx("div", { ref: overlayElement, className: "motiongpu-error-overlay", role: "presentation", children: /* @__PURE__ */ jsx("div", { className: "motiongpu-error-dialog-shell", role: "presentation", children: /* @__PURE__ */ jsxs("div", { ref: setDialogElement, className: "motiongpu-error-dialog", role: "alertdialog", "aria-modal": "true", "aria-labelledby": titleId, "aria-describedby": descriptionId, tabIndex: -1, "data-testid": "motiongpu-error", onKeyDown: handleDialogKeyDown, children: [ /* @__PURE__ */ jsx("header", { className: "motiongpu-error-header", children: /* @__PURE__ */ jsxs("div", { className: "motiongpu-error-header-top", children: [/* @__PURE__ */ jsxs("div", { className: "motiongpu-error-header-copy", children: [/* @__PURE__ */ jsx("h2", { id: titleId, className: "motiongpu-error-title", children: report.title }), /* @__PURE__ */ jsxs("p", { className: "motiongpu-error-recoverable", children: ["Recoverable: ", /* @__PURE__ */ jsx("span", { children: report.recoverable ? "yes" : "no" })] })] }), /* @__PURE__ */ jsxs("div", { className: "motiongpu-error-badges", children: [/* @__PURE__ */ jsx("div", { className: "motiongpu-error-badge-wrap", children: /* @__PURE__ */ jsx("p", { className: "motiongpu-error-badge motiongpu-error-badge-phase", children: report.phase }) }), /* @__PURE__ */ jsx("div", { className: "motiongpu-error-badge-wrap", children: /* @__PURE__ */ jsx("p", { className: "motiongpu-error-badge motiongpu-error-badge-severity", children: report.severity }) })] })] }) }), /* @__PURE__ */ jsxs("div", { id: descriptionId, className: "motiongpu-error-body", children: [model.displayMessage.length > 0 ? /* @__PURE__ */ jsx("p", { className: "motiongpu-error-message", children: model.displayMessage }) : null, /* @__PURE__ */ jsx("p", { className: "motiongpu-error-hint", children: report.hint })] }), report.source ? /* @__PURE__ */ jsxs("section", { className: "motiongpu-error-source", "aria-labelledby": sourceTitleId, children: [/* @__PURE__ */ jsx("h3", { id: sourceTitleId, className: "motiongpu-error-source-title", children: "Source" }), /* @__PURE__ */ jsxs("figure", { className: "motiongpu-error-source-frame", children: [/* @__PURE__ */ jsxs("figcaption", { className: "motiongpu-error-source-tabs", children: [/* @__PURE__ */ jsxs("span", { className: "motiongpu-error-source-tab motiongpu-error-source-tab-active", children: [report.source.location, report.source.column ? `, col ${report.source.column}` : ""] }), /* @__PURE__ */ jsx("span", { className: "motiongpu-error-source-tab-spacer", "aria-hidden": "true" })] }), /* @__PURE__ */ jsx("div", { className: "motiongpu-error-source-snippet", role: "region", "aria-label": `Source code from ${report.source.location}`, children: report.source.snippet.map((snippetLine) => /* @__PURE__ */ jsxs("div", { className: snippetLine.highlight ? "motiongpu-error-source-row motiongpu-error-source-row-active" : "motiongpu-error-source-row", children: [/* @__PURE__ */ jsxs("span", { className: "motiongpu-error-source-line", children: [snippetLine.highlight ? /* @__PURE__ */ jsx("span", { className: "motiongpu-sr-only", children: "Error line: " }) : null, snippetLine.number] }), /* @__PURE__ */ jsx("span", { className: "motiongpu-error-source-code", children: snippetLine.code || " " })] }, `snippet-${snippetLine.number}`)) })] })] }) : null, /* @__PURE__ */ jsxs("div", { className: "motiongpu-error-sections", children: [ report.details.length > 0 ? /* @__PURE__ */ jsxs("details", { className: "motiongpu-error-details", open: true, children: [/* @__PURE__ */ jsxs("summary", { children: [/* @__PURE__ */ jsx(ChevronDownIcon, {}), /* @__PURE__ */ jsx("span", { children: detailsSummary })] }), /* @__PURE__ */ jsx("pre", { children: report.details.join("\n") })] }) : null, report.stack.length > 0 ? /* @__PURE__ */ jsxs("details", { className: "motiongpu-error-details", children: [/* @__PURE__ */ jsxs("summary", { children: [/* @__PURE__ */ jsx(ChevronDownIcon, {}), /* @__PURE__ */ jsx("span", { children: "Stack trace" })] }), /* @__PURE__ */ jsx("pre", { children: report.stack.join("\n") })] }) : null, report.context ? /* @__PURE__ */ jsxs("details", { className: "motiongpu-error-details", children: [/* @__PURE__ */ jsxs("summary", { children: [/* @__PURE__ */ jsx(ChevronDownIcon, {}), /* @__PURE__ */ jsx("span", { children: "Runtime context" })] }), /* @__PURE__ */ jsx("pre", { children: model.runtimeContextText })] }) : null ] }) ] }) }) }) }); } //#endregion export { MotionGPUErrorOverlay }; //# sourceMappingURL=MotionGPUErrorOverlay.js.map