File size: 2,124 Bytes
f3726ae | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | import { Icon } from "./Icon";
type Props = {
open: boolean;
title?: string;
jsonText: string;
onClose: () => void;
};
export function PayloadViewerModal({
open,
title = "Request payload",
jsonText,
onClose,
}: Props) {
if (!open) return null;
const copy = () => {
void navigator.clipboard.writeText(jsonText);
};
return (
<div
className="fixed inset-0 z-[100] flex items-center justify-center p-4"
role="dialog"
aria-modal="true"
aria-labelledby="payload-modal-title"
>
<button
type="button"
className="absolute inset-0 bg-black/40 backdrop-blur-[1px]"
aria-label="Close"
onClick={onClose}
/>
<div className="relative flex max-h-[85vh] w-full max-w-3xl flex-col rounded-2xl border border-outline-variant bg-surface-container-lowest shadow-xl">
<div className="flex shrink-0 items-center justify-between gap-3 border-b border-outline-variant px-4 py-3">
<h2
id="payload-modal-title"
className="font-headline-md text-base font-bold text-primary"
>
{title}
</h2>
<div className="flex items-center gap-2">
<button
type="button"
onClick={copy}
className="flex items-center gap-1.5 rounded-lg border border-outline-variant bg-surface-container-low px-3 py-1.5 text-xs font-semibold text-primary hover:bg-surface-container-high"
>
<Icon name="content_copy" className="text-sm" />
Copy JSON
</button>
<button
type="button"
onClick={onClose}
className="rounded-lg p-2 text-secondary hover:bg-surface-container-high hover:text-primary"
aria-label="Close"
>
<Icon name="close" className="text-xl" />
</button>
</div>
</div>
<pre className="min-h-0 flex-1 overflow-auto p-4 font-data-mono text-[11px] leading-relaxed text-primary">
{jsonText}
</pre>
</div>
</div>
);
}
|