From 8743f66b29ed1957848c0e78f051fcc4332cbdec Mon Sep 17 00:00:00 2001 From: Austen Frostad Date: Wed, 13 May 2026 20:22:52 -0700 Subject: [PATCH 1/2] Enhances clipboard copying with MIME type selection Introduces a new component to allow copying text content to the clipboard with various MIME types (e.g., plain text, HTML, Markdown). Utilizes the `ClipboardItem` API for rich data transfers, falling back to `writeText` for basic plain text copy if advanced features are unavailable. The UI now includes a dropdown for MIME type selection. Updates class attributes to className for React consistency. --- index.jsx | 82 +++++++++++++++++++++++++++++++++++++++++++++---------- style.css | 38 ++++++++++++++++++++++++-- 2 files changed, 103 insertions(+), 17 deletions(-) diff --git a/index.jsx b/index.jsx index 692f0e2..f8945c2 100644 --- a/index.jsx +++ b/index.jsx @@ -1,4 +1,4 @@ -import React, { useCallback } from 'react'; +import React, { useCallback, useState } from 'react'; import ReactDOM from 'react-dom'; const MDN_BASE = `https://developer.mozilla.org/en-US/docs/Web/API`; @@ -26,6 +26,67 @@ const MDN_URLS = { } }; +const TEXT_COPY_MIME_OPTIONS = [ + { value: 'text/plain', label: 'Plain text' }, + { value: 'text/html', label: 'HTML' }, + { value: 'text/markdown', label: 'Markdown' }, + { value: 'text/rtf', label: 'Rich text (RTF)' }, + { value: 'image/svg+xml', label: 'SVG' } +]; + +function CopyAsMime({ text }) { + const [mimeType, setMimeType] = useState('text/plain'); + + const writeAsMime = useCallback(async () => { + if (!navigator.clipboard) { + return; + } + + if (navigator.clipboard.write && window.ClipboardItem) { + try { + const items = { + 'text/plain': new Blob([text], { + type: 'text/plain' + }) + }; + + if (mimeType !== 'text/plain') { + items[mimeType] = new Blob([text], { + type: mimeType + }); + } + + await navigator.clipboard.write([new ClipboardItem(items)]); + } catch (error) { + console.warn( + 'ClipboardItem write failed, falling back to writeText', + error + ); + } + } else if (navigator.clipboard.writeText) { + await navigator.clipboard.writeText(text); + } + }, [mimeType, text]); + + return ( +
+ + +
+ ); +} + async function extractData(data) { if (!data) { return undefined; @@ -230,22 +291,13 @@ function ClipboardInspector(props) { navigator.clipboard && navigator.clipboard .writeText && ( -
- -
+ )} -
+													
 														
 															{typeof obj.data ===
 															'object'
@@ -326,7 +378,7 @@ function ClipboardInspector(props) {
 														
 															{item.kind ===
 															'string' ? (
-																
+																
 																	
 																		{item.as_string_or_file || (
 																			
diff --git a/style.css b/style.css
index bbe434d..5311a93 100644
--- a/style.css
+++ b/style.css
@@ -178,8 +178,42 @@ h1 + p {
 	margin: -0.5em 0;
 }
 
-.cb-copy {
-	padding: 0.5em 0.5em 0.5em 0;
+.cb-copy-as-dropdown {
+	margin-top: 0.75em;
+	display: inline-flex;
+	align-items: stretch;
+	border: 0.1em solid;
+	background: #f3f3f3;
+	box-shadow: 0.1em 0.1em currentColor;
+}
+
+.cb-copy-as-dropdown button {
+	appearance: none;
+	border: none;
+	background: transparent;
+	padding: 0.5em 0.75em;
+	font: inherit;
+	cursor: pointer;
+}
+
+.cb-copy-as-dropdown select {
+	border: none;
+	background: #fff;
+	padding: 0.5em 0.6em;
+	font: inherit;
+	color: inherit;
+	outline: none;
+	width: 7em;
+}
+
+.cb-copy-as-dropdown button:hover,
+.cb-copy-as-dropdown select:hover {
+	background: #fafafa;
+}
+
+.cb-copy-as-dropdown button:focus,
+.cb-copy-as-dropdown select:focus {
+	outline: 2px solid #006be4;
 }
 
 @media (max-width: 60ch) {

From 9ab1dcad6345e377a2c9b305aac31bb7570ddd66 Mon Sep 17 00:00:00 2001
From: Austen Frostad 
Date: Thu, 14 May 2026 08:05:26 -0700
Subject: [PATCH 2/2] Only Include the actual supported formats of Async
 Clipboard API

---
 index.jsx | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/index.jsx b/index.jsx
index f8945c2..2083dd9 100644
--- a/index.jsx
+++ b/index.jsx
@@ -28,10 +28,7 @@ const MDN_URLS = {
 
 const TEXT_COPY_MIME_OPTIONS = [
 	{ value: 'text/plain', label: 'Plain text' },
-	{ value: 'text/html', label: 'HTML' },
-	{ value: 'text/markdown', label: 'Markdown' },
-	{ value: 'text/rtf', label: 'Rich text (RTF)' },
-	{ value: 'image/svg+xml', label: 'SVG' }
+	{ value: 'text/html', label: 'HTML' }
 ];
 
 function CopyAsMime({ text }) {