mirror of
https://codeberg.org/Toasterson/ips.git
synced 2026-04-10 13:20:42 +00:00
feat: Add copy buttons for FMRI and install command on detail page
Replace the cramped FMRI badge and install-cmd div with full-width copyable blocks that have labeled headers, single-line horizontal scrolling (no wrapping), and a copy-to-clipboard button. The button shows a checkmark on success. The install command copy strips the leading $ prompt.
This commit is contained in:
parent
195863f6d8
commit
7d5ddb626f
3 changed files with 94 additions and 32 deletions
|
|
@ -516,40 +516,70 @@ main.container {
|
|||
word-break: break-all;
|
||||
}
|
||||
|
||||
/* Install command */
|
||||
.install-cmd {
|
||||
/* Copyable blocks (FMRI, install command) */
|
||||
.copyable-block { margin-bottom: 0.75rem; }
|
||||
|
||||
.copyable-label {
|
||||
display: block;
|
||||
font-size: 0.72rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: var(--d-text-muted);
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
|
||||
.copyable-row {
|
||||
background: var(--d-bg-surface);
|
||||
border: 1px solid var(--d-border);
|
||||
border-radius: var(--d-radius);
|
||||
padding: 0.65rem 1rem;
|
||||
font-family: var(--d-mono);
|
||||
font-size: 0.84rem;
|
||||
color: var(--d-heading);
|
||||
padding: 0.55rem 0.75rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.6rem;
|
||||
margin-bottom: 2rem;
|
||||
overflow-x: auto;
|
||||
white-space: nowrap;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.install-cmd .prompt {
|
||||
.copyable-text {
|
||||
font-family: var(--d-mono);
|
||||
font-size: 0.82rem;
|
||||
color: var(--d-heading);
|
||||
white-space: nowrap;
|
||||
overflow-x: auto;
|
||||
flex: 1;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
.copyable-text .prompt {
|
||||
color: var(--d-accent);
|
||||
user-select: none;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* FMRI badge */
|
||||
.fmri-badge {
|
||||
display: inline-block;
|
||||
background: var(--d-bg-surface);
|
||||
border: 1px solid var(--d-border);
|
||||
.copy-btn {
|
||||
flex-shrink: 0;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 4px;
|
||||
padding: 0.15rem 0.5rem;
|
||||
font-family: var(--d-mono);
|
||||
font-size: 0.78rem;
|
||||
color: var(--d-text);
|
||||
word-break: break-all;
|
||||
background: transparent;
|
||||
border: 1px solid var(--d-border);
|
||||
color: var(--d-text-muted);
|
||||
cursor: pointer;
|
||||
transition: all var(--d-transition);
|
||||
}
|
||||
|
||||
.copy-btn:hover {
|
||||
background: var(--d-bg-hover);
|
||||
color: var(--d-heading);
|
||||
border-color: var(--d-accent-dim);
|
||||
}
|
||||
|
||||
.copy-btn.copied {
|
||||
color: var(--d-success);
|
||||
border-color: var(--d-success);
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
|
|
|
|||
|
|
@ -82,9 +82,14 @@
|
|||
.info-row{display:flex;justify-content:space-between;align-items:baseline;gap:1rem}
|
||||
.info-row .label{color:var(--d-text-muted);font-size:0.84rem;white-space:nowrap}
|
||||
.info-row .value{font-family:var(--d-mono);font-size:0.84rem;color:var(--d-heading);text-align:right;word-break:break-all}
|
||||
.install-cmd{background:var(--d-bg-surface);border:1px solid var(--d-border);border-radius:var(--d-radius);padding:0.65rem 1rem;font-family:var(--d-mono);font-size:0.84rem;color:var(--d-heading);display:flex;align-items:center;gap:0.6rem;margin-bottom:2rem;overflow-x:auto;white-space:nowrap}
|
||||
.install-cmd .prompt{color:var(--d-accent);user-select:none;font-weight:600}
|
||||
.fmri-badge{display:inline-block;background:var(--d-bg-surface);border:1px solid var(--d-border);border-radius:4px;padding:0.15rem 0.5rem;font-family:var(--d-mono);font-size:0.78rem;color:var(--d-text);word-break:break-all}
|
||||
.copyable-block{margin-bottom:0.75rem}
|
||||
.copyable-label{display:block;font-size:0.72rem;text-transform:uppercase;letter-spacing:0.06em;color:var(--d-text-muted);font-weight:600;margin-bottom:0.3rem}
|
||||
.copyable-row{background:var(--d-bg-surface);border:1px solid var(--d-border);border-radius:var(--d-radius);padding:0.55rem 0.75rem;display:flex;align-items:center;justify-content:space-between;gap:0.75rem}
|
||||
.copyable-text{font-family:var(--d-mono);font-size:0.82rem;color:var(--d-heading);white-space:nowrap;overflow-x:auto;flex:1;scrollbar-width:thin}
|
||||
.copyable-text .prompt{color:var(--d-accent);user-select:none;font-weight:600}
|
||||
.copy-btn{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:4px;background:transparent;border:1px solid var(--d-border);color:var(--d-text-muted);cursor:pointer;transition:all var(--d-transition)}
|
||||
.copy-btn:hover{background:var(--d-bg-hover);color:var(--d-heading);border-color:var(--d-accent-dim)}
|
||||
.copy-btn.copied{color:var(--d-success);border-color:var(--d-success)}
|
||||
.section-heading{font-size:1.05rem;margin:2rem 0 0.75rem;padding-bottom:0.4rem;border-bottom:1px solid var(--d-border-subtle)}
|
||||
.dep-list li{display:flex;align-items:center;gap:0.6rem;padding:0.4rem 0;border-bottom:1px solid var(--d-border-subtle);font-family:var(--d-mono);font-size:0.82rem}
|
||||
.dep-list li:last-child{border-bottom:none}
|
||||
|
|
|
|||
|
|
@ -56,18 +56,28 @@
|
|||
<span class="label">Compressed</span>
|
||||
<span class="value">{{ csize }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="label">FMRI</span>
|
||||
<span class="value">
|
||||
<span class="fmri-badge">{{ fmri_str }}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="install-cmd">
|
||||
<span class="prompt">$</span> pkg install {{ fmri_str }}
|
||||
<div class="copyable-block">
|
||||
<span class="copyable-label">FMRI</span>
|
||||
<div class="copyable-row">
|
||||
<code class="copyable-text" id="fmri-text">{{ fmri_str }}</code>
|
||||
<button class="copy-btn" onclick="copyText('fmri-text')" title="Copy FMRI">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="copyable-block">
|
||||
<span class="copyable-label">Install</span>
|
||||
<div class="copyable-row">
|
||||
<code class="copyable-text" id="install-text"><span class="prompt">$</span> pkg install {{ fmri_str }}</code>
|
||||
<button class="copy-btn" onclick="copyText('install-text', true)" title="Copy install command">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if !dependencies.is_empty() %}
|
||||
|
|
@ -106,4 +116,21 @@
|
|||
<span class="spinner"></span> Loading manifest...
|
||||
</span>
|
||||
<div id="manifest-content"></div>
|
||||
|
||||
<script>
|
||||
function copyText(id, stripPrompt) {
|
||||
const el = document.getElementById(id);
|
||||
let text = el.textContent;
|
||||
if (stripPrompt) text = text.replace(/^\$\s*/, '');
|
||||
navigator.clipboard.writeText(text.trim()).then(() => {
|
||||
const btn = el.parentElement.querySelector('.copy-btn');
|
||||
btn.classList.add('copied');
|
||||
btn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>';
|
||||
setTimeout(() => {
|
||||
btn.classList.remove('copied');
|
||||
btn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>';
|
||||
}, 1500);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue