diff --git a/packages/web/src/components/share/content-markdown.tsx b/packages/web/src/components/share/content-markdown.tsx index a083872e..8efa5f9a 100644 --- a/packages/web/src/components/share/content-markdown.tsx +++ b/packages/web/src/components/share/content-markdown.tsx @@ -2,6 +2,7 @@ import { marked } from "marked" import { codeToHtml } from "shiki" import markedShiki from "marked-shiki" import { createOverflow } from "./common" +import { CopyButton } from "./copy-button" import { createResource, createSignal } from "solid-js" import { transformerNotationDiff } from "@shikijs/transformers" import style from "./content-markdown.module.css" @@ -41,6 +42,7 @@ export function ContentMarkdown(props: Props) { class={style.root} data-highlight={props.highlight === true ? true : undefined} data-expanded={expanded() || props.expand === true ? true : undefined} + style={{ position: "relative" }} >
@@ -54,6 +56,7 @@ export function ContentMarkdown(props: Props) { {expanded() ? "Show less" : "Show more"} )} +
{props.text}
@@ -30,6 +32,7 @@ export function ContentText(props: Props) {
{expanded() ? "Show less" : "Show more"}
)}
+
)
}
diff --git a/packages/web/src/components/share/copy-button.module.css b/packages/web/src/components/share/copy-button.module.css
new file mode 100644
index 00000000..7494c2b8
--- /dev/null
+++ b/packages/web/src/components/share/copy-button.module.css
@@ -0,0 +1,47 @@
+.copyButtonWrapper {
+ position: absolute;
+ top: 0.5rem;
+ right: 0.5rem;
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.15s ease;
+}
+
+.copyButton {
+ width: 18px;
+ cursor: pointer;
+ background: none;
+ border: none;
+ padding: 0;
+ color: var(--sl-color-text-secondary);
+
+ svg {
+ display: block;
+ width: 16px;
+ height: 16px;
+ }
+
+ &[data-copied="true"] {
+ color: var(--sl-color-green-high);
+ }
+}
+
+/* Show copy button when parent is hovered */
+*:hover > .copyButtonWrapper {
+ opacity: 0.65;
+ visibility: visible;
+}
+
+.copyTooltip {
+ position: absolute;
+ top: 50%;
+ left: calc(100% + 12px);
+ transform: translate(0, -50%);
+ padding: 0.375em 0.5em;
+ background: var(--sl-color-white);
+ color: var(--sl-color-text-invert);
+ font-size: 0.6875rem;
+ border-radius: 7px;
+ white-space: nowrap;
+ z-index: 11;
+}
diff --git a/packages/web/src/components/share/copy-button.tsx b/packages/web/src/components/share/copy-button.tsx
new file mode 100644
index 00000000..a4434b1c
--- /dev/null
+++ b/packages/web/src/components/share/copy-button.tsx
@@ -0,0 +1,35 @@
+import { createSignal } from "solid-js"
+import { IconClipboard, IconCheckCircle } from "../icons"
+import styles from "./copy-button.module.css"
+
+interface CopyButtonProps {
+ text: string
+}
+
+export function CopyButton(props: CopyButtonProps) {
+ const [copied, setCopied] = createSignal(false)
+
+ function handleCopyClick() {
+ if (props.text) {
+ navigator.clipboard.writeText(props.text).catch((err) => console.error("Copy failed", err))
+
+ setCopied(true)
+ setTimeout(() => setCopied(false), 2000)
+ }
+ }
+
+ return (
+
+
+ {copied() && Copied!}
+
+ )
+}