1
0
mirror of https://github.com/coalaura/whiskr.git synced 2025-12-02 20:22:52 +00:00

sticky markdown copy

This commit is contained in:
Laura
2025-11-30 22:52:16 +01:00
parent 4d1bdf981a
commit cb9a724770
4 changed files with 51 additions and 33 deletions

View File

@@ -225,7 +225,6 @@ body:not(.loading) #loading {
display: block; display: block;
height: 14px; height: 14px;
flex-shrink: 0; flex-shrink: 0;
margin-bottom: -40px;
} }
#messages:empty::before { #messages:empty::before {
@@ -233,7 +232,7 @@ body:not(.loading) #loading {
color: var(--c-subtext); color: var(--c-subtext);
font-style: italic; font-style: italic;
align-self: center; align-self: center;
margin-top: 20px; margin-top: 5px;
} }
#message, #message,
@@ -446,7 +445,7 @@ body:not(.loading) #loading {
.message .body { .message .body {
position: relative; position: relative;
border-radius: 6px; border-radius: 6px;
overflow: hidden; overflow: visible;
padding: 14px 12px; padding: 14px 12px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -456,6 +455,7 @@ body:not(.loading) #loading {
.message.collapsed .body { .message.collapsed .body {
height: 32px; height: 32px;
overflow: hidden;
} }
.message.collapsed .body>* { .message.collapsed .body>* {
@@ -1182,6 +1182,7 @@ label[for="reasoning-tokens"] {
height: 20px; height: 20px;
background-image: url(icons/up.svg); background-image: url(icons/up.svg);
transition: 150ms; transition: 150ms;
z-index: 15;
} }
#bottom { #bottom {

View File

@@ -2,7 +2,7 @@
font-size: 15px; font-size: 15px;
line-height: 23px; line-height: 23px;
color: var(--c-text); color: var(--c-text);
overflow: hidden; overflow: visible;
word-wrap: break-word; word-wrap: break-word;
} }
@@ -153,37 +153,38 @@
.markdown pre { .markdown pre {
background: var(--c-mantle); background: var(--c-mantle);
white-space: pre-wrap; white-space: pre-wrap;
padding: 10px 12px; padding: 0;
border-radius: 6px; border-radius: 6px;
line-height: 18px; line-height: 18px;
overflow: hidden;
tab-size: 4; tab-size: 4;
position: relative;
} }
.markdown pre code { .markdown pre code {
display: block;
background: transparent; background: transparent;
padding: 0; padding: 10px 12px;
margin: 0; margin: 0;
} }
.markdown .pre-header { .markdown .pre-header {
position: relative;
background: var(--c-surface0); background: var(--c-surface0);
padding: 8px 12px; padding: 8px 12px;
margin: -10px -12px; margin: 0;
margin-bottom: 10px;
font-size: 12px; font-size: 12px;
line-height: 14px; line-height: 14px;
border-top-left-radius: 6px;
border-top-right-radius: 6px;
} }
.markdown .pre-copy { .markdown .pre-copy {
position: absolute; position: sticky;
top: 6px; top: 34px;
right: 10px; float: right;
width: 18px; margin-top: -30px;
height: 18px; width: 30px;
opacity: 0; height: 30px;
transition: 150ms; background-size: 20px;
} }
.markdown pre:hover .pre-copy { .markdown pre:hover .pre-copy {
@@ -200,22 +201,22 @@
padding-left: 28px; padding-left: 28px;
} }
.markdown > :first-child { .markdown> :first-child {
margin-top: 0; margin-top: 0;
} }
.markdown blockquote > *, .markdown blockquote>*,
.markdown td > *, .markdown td>*,
.markdown th > *, .markdown th>*,
.markdown > * { .markdown>* {
margin: 0; margin: 0;
margin-bottom: 14px; margin-bottom: 14px;
} }
.markdown blockquote > *:last-child, .markdown blockquote>*:last-child,
.markdown td > *:last-child, .markdown td>*:last-child,
.markdown th > *:last-child, .markdown th>*:last-child,
.markdown > *:last-child { .markdown>*:last-child {
margin-bottom: 0; margin-bottom: 0;
} }

View File

@@ -258,6 +258,17 @@
this.#_message.appendChild(_header); this.#_message.appendChild(_header);
_header.addEventListener("auxclick", event => {
if (event.button !== 1) {
return;
}
this.#_message.scrollIntoView({
behavior: "smooth",
block: "start",
});
});
// message role (wrapper) // message role (wrapper)
const _wrapper = make("div", "role", this.#role); const _wrapper = make("div", "role", this.#role);

View File

@@ -50,9 +50,10 @@
renderer: { renderer: {
code: code => { code: code => {
const header = `<div class="pre-header">${escapeHtml(code.lang)}<button class="pre-copy" title="Copy code contents"></button></div>`; const header = `<div class="pre-header">${escapeHtml(code.lang)}</div>`;
const button = `<button class="pre-copy" title="Copy code contents"></button>`;
return `<pre class="l-${escapeHtml(code.lang)}">${header}<code>${code.text}</code></pre>`; return `<pre class="l-${escapeHtml(code.lang)}">${header}${button}<code>${code.text}</code></pre>`;
}, },
link: link => `<a href="${link.href}" target="_blank">${escapeHtml(link.text || link.href)}</a>`, link: link => `<a href="${link.href}" target="_blank">${escapeHtml(link.text || link.href)}</a>`,
@@ -140,9 +141,13 @@
} }
addEventListener("click", event => { addEventListener("click", event => {
const button = event.target, const button = event.target;
header = button.closest(".pre-header"),
pre = header?.closest("pre"), if (!button.classList.contains("pre-copy")) {
return;
}
const pre = button.closest("pre"),
code = pre?.querySelector("code"); code = pre?.querySelector("code");
if (!code) { if (!code) {