From e223e8be23fd481b1856768f7994fae942c609de Mon Sep 17 00:00:00 2001 From: Kawa Date: Fri, 27 Mar 2026 11:45:21 +0100 Subject: [PATCH] feat(04-02): add OutputBlock reusable component - Pre-formatted code block with label, copy button, and optional download button - Copy button calls navigator.clipboard.writeText with 2s "Copied!" feedback - Download button calls downloadFile(content, filename) when filename prop provided - disabled prop gates both copy and download actions (SECU-01 security gate) --- src/components/wizard/OutputBlock.tsx | 53 +++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/components/wizard/OutputBlock.tsx diff --git a/src/components/wizard/OutputBlock.tsx b/src/components/wizard/OutputBlock.tsx new file mode 100644 index 0000000..c52bcd7 --- /dev/null +++ b/src/components/wizard/OutputBlock.tsx @@ -0,0 +1,53 @@ +// src/components/wizard/OutputBlock.tsx +// Reusable output block: pre-formatted content + copy button + optional download button. +// disabled prop gates both actions (SECU-01 security acknowledgement gate). +import { useState } from 'react'; +import { downloadFile } from '../../utils/downloadFile'; + +export interface OutputBlockProps { + label: string; + content: string; + filename?: string; + disabled?: boolean; +} + +export function OutputBlock({ label, content, filename, disabled = false }: OutputBlockProps) { + const [copied, setCopied] = useState(false); + + async function handleCopy() { + await navigator.clipboard.writeText(content); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } + + return ( +
+
+ {label} +
+ + {filename && ( + + )} +
+
+
+        {content}
+      
+
+ ); +}