Archived
Use chat copy icon for code blocks
This commit is contained in:
@@ -26,8 +26,12 @@ export class FormattedText extends LitElement {
|
|||||||
const button = document.createElement("button");
|
const button = document.createElement("button");
|
||||||
button.type = "button";
|
button.type = "button";
|
||||||
button.className = "code-copy-button";
|
button.className = "code-copy-button";
|
||||||
button.textContent = "Copy";
|
button.title = "Copy code block";
|
||||||
button.setAttribute("aria-label", "Copy code block");
|
button.setAttribute("aria-label", "Copy code block");
|
||||||
|
const icon = document.createElement("span");
|
||||||
|
icon.setAttribute("aria-hidden", "true");
|
||||||
|
icon.textContent = "⧉";
|
||||||
|
button.append(icon);
|
||||||
element.before(wrapper);
|
element.before(wrapper);
|
||||||
wrapper.append(element, button);
|
wrapper.append(element, button);
|
||||||
});
|
});
|
||||||
@@ -44,12 +48,20 @@ export class FormattedText extends LitElement {
|
|||||||
|
|
||||||
private async copyCode(text: string, button: HTMLButtonElement): Promise<void> {
|
private async copyCode(text: string, button: HTMLButtonElement): Promise<void> {
|
||||||
const ok = await writeClipboard(text);
|
const ok = await writeClipboard(text);
|
||||||
button.textContent = ok ? "Copied" : "Failed";
|
this.setCopyButtonState(button, ok ? "copied" : "failed");
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
button.textContent = "Copy";
|
this.setCopyButtonState(button, "idle");
|
||||||
}, 1200);
|
}, 1200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setCopyButtonState(button: HTMLButtonElement, state: "idle" | "copied" | "failed"): void {
|
||||||
|
const icon = button.querySelector("span");
|
||||||
|
if (icon !== null) icon.textContent = state === "copied" ? "✓" : "⧉";
|
||||||
|
const label = state === "copied" ? "Copied code block" : state === "failed" ? "Failed to copy code block" : "Copy code block";
|
||||||
|
button.title = label;
|
||||||
|
button.setAttribute("aria-label", label);
|
||||||
|
}
|
||||||
|
|
||||||
static override styles = formattedTextStyles;
|
static override styles = formattedTextStyles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -195,11 +195,11 @@ export const formattedTextStyles = css`
|
|||||||
li + li { margin-top: 3px; }
|
li + li { margin-top: 3px; }
|
||||||
code { border: 1px solid #30363d; border-radius: 4px; background: #0d1117; padding: 1px 4px; font: 13px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
|
code { border: 1px solid #30363d; border-radius: 4px; background: #0d1117; padding: 1px 4px; font: 13px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
|
||||||
.code-block-wrapper { position: relative; }
|
.code-block-wrapper { position: relative; }
|
||||||
.code-block-wrapper pre { margin: 0; padding-right: 58px; }
|
.code-block-wrapper pre { margin: 0; padding-right: 40px; }
|
||||||
pre { border: 1px solid #30363d; border-radius: 8px; background: #0d1117; padding: 10px; overflow: auto; }
|
pre { border: 1px solid #30363d; border-radius: 8px; background: #0d1117; padding: 10px; overflow: auto; }
|
||||||
pre code { border: 0; padding: 0; background: transparent; }
|
pre code { border: 0; padding: 0; background: transparent; }
|
||||||
.code-copy-button { position: absolute; top: 6px; right: 6px; z-index: 1; border: 1px solid #30363d; border-radius: 6px; background: #161b22; color: #8b949e; padding: 3px 7px; font: 12px system-ui, sans-serif; cursor: pointer; }
|
.code-copy-button { position: absolute; top: 6px; right: 6px; z-index: 1; display: inline-grid; place-items: center; width: 24px; height: 24px; border: 1px solid #30363d; border-radius: 6px; background: #161b22; color: #8b949e; padding: 0; font: 14px system-ui, sans-serif; line-height: 1; cursor: pointer; }
|
||||||
.code-copy-button:hover { color: #e6edf3; border-color: #58a6ff; }
|
.code-copy-button:hover, .code-copy-button:focus { color: #e6edf3; border-color: #58a6ff; }
|
||||||
blockquote { border-left: 3px solid #30363d; padding-left: 10px; color: #8b949e; }
|
blockquote { border-left: 3px solid #30363d; padding-left: 10px; color: #8b949e; }
|
||||||
a { color: #58a6ff; }
|
a { color: #58a6ff; }
|
||||||
h1, h2, h3, h4 { margin: 14px 0 8px; line-height: 1.2; }
|
h1, h2, h3, h4 { margin: 14px 0 8px; line-height: 1.2; }
|
||||||
|
|||||||
Reference in New Issue
Block a user