From 558dcb7191e8844b2465e48dd0ca40727f35817b Mon Sep 17 00:00:00 2001 From: Kieran Farr Date: Mon, 30 Dec 2024 23:12:22 -0800 Subject: [PATCH] copy button styling is a hot mess --- src/editor/components/widgets/AIChatPanel.js | 28 +++++++++++- src/editor/style/chat-panel.scss | 47 ++++++++++++++++++-- 2 files changed, 70 insertions(+), 5 deletions(-) diff --git a/src/editor/components/widgets/AIChatPanel.js b/src/editor/components/widgets/AIChatPanel.js index 31d93135..d760fbc6 100644 --- a/src/editor/components/widgets/AIChatPanel.js +++ b/src/editor/components/widgets/AIChatPanel.js @@ -4,6 +4,29 @@ import { getGenerativeModel } from 'firebase/vertexai'; import Collapsible from '../Collapsible'; import JSONPretty from 'react-json-pretty'; import 'react-json-pretty/themes/monikai.css'; +import { Copy32Icon } from '../../icons'; + +// Helper component for the copy button +const CopyButton = ({ jsonData }) => { + const [copied, setCopied] = useState(false); + + const handleCopy = async () => { + try { + await navigator.clipboard.writeText(JSON.stringify(jsonData, null, 2)); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } catch (err) { + console.error('Failed to copy:', err); + } + }; + + return ( + + ); +}; // Helper component to render message content with JSON formatting const MessageContent = ({ content }) => { @@ -58,7 +81,10 @@ const MessageContent = ({ content }) => { {parts.map((part, index) => (
{part.type === 'json' ? ( - + <> + + + ) : ( {part.content} )} diff --git a/src/editor/style/chat-panel.scss b/src/editor/style/chat-panel.scss index afa7aba0..a215bffa 100644 --- a/src/editor/style/chat-panel.scss +++ b/src/editor/style/chat-panel.scss @@ -34,29 +34,37 @@ &.assistant { align-self: flex-start; background-color: variables.$darkgray-500; + width: 100%; // Ensure full width for JSON content // Ensure JSON blocks expand properly within assistant messages .json-block { width: 100%; margin: 0.5em 0; + position: relative; + padding-right: 80px; // Make room for the copy button + background-color: variables.$darkgray-900; // Darker background for JSON + border-radius: 6px; + overflow: hidden; // Contain the JSON content } // Override react-json-pretty default styles .json-pretty { width: 100% !important; max-width: none !important; - font-family: 'Fira Code', Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', + font-family: Monaco, 'Andale Mono', 'Ubuntu Mono', 'Fira Code', Consolas, monospace !important; font-size: 13px !important; line-height: 1.4 !important; background-color: variables.$darkgray-900 !important; - padding: 8px !important; + padding: 12px !important; border-radius: 6px !important; overflow-x: auto !important; + color: variables.$white !important; // Ensure base text is visible // Style JSON keys .__json-key__ { color: variables.$purple-100 !important; + font-weight: 600 !important; } // Style JSON strings @@ -73,6 +81,37 @@ .__json-punctuation__ { color: variables.$gray-300 !important; } + + // Add some spacing between properties + .json-pretty-key { + margin-right: 8px !important; + } + } + + .copy-button { + position: absolute; + right: 8px; + top: 8px; + background: variables.$darkgray-700; + border: 1px solid variables.$darkgray-600; + cursor: pointer; + padding: 4px 8px; + border-radius: 4px; + color: variables.$gray-300; + display: flex; + align-items: center; + gap: 4px; + font-size: 12px; + z-index: 1; + + &:hover { + background: variables.$darkgray-600; + color: variables.$white; + } + + &:active { + background: variables.$darkgray-500; + } } } } @@ -106,11 +145,11 @@ cursor: pointer; &:hover { - background-color: variables.$purple-100; + background-color: variables.$purple-700; } &:active { - background-color: variables.$purple-200; + background-color: variables.$purple-600; } &:disabled {