mirror of
https://github.com/github/awesome-copilot.git
synced 2026-02-22 19:35:13 +00:00
feat: implement split button dropdown for install options
- Replace separate VS Code/Insiders buttons with single Install dropdown - Primary 'Install' button opens in VS Code, dropdown chevron reveals options - Dropdown shows 'VS Code' and 'VS Code Insiders' choices - Add CSS for split button styling with glassmorphism dropdown - Apply to modal and all list views (agents, prompts, instructions)
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generated": "2026-01-28T08:51:25.860Z",
|
"generated": "2026-01-28T22:33:37.643Z",
|
||||||
"counts": {
|
"counts": {
|
||||||
"agents": 140,
|
"agents": 140,
|
||||||
"prompts": 134,
|
"prompts": 134,
|
||||||
|
|||||||
@@ -646,6 +646,101 @@ a:hover {
|
|||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Split Button Dropdown */
|
||||||
|
.install-dropdown {
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.install-dropdown .install-btn-main {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-right: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.install-dropdown .install-btn-toggle {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
padding: 10px 10px;
|
||||||
|
min-width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.install-dropdown .install-btn-toggle svg {
|
||||||
|
transition: transform var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.install-dropdown.open .install-btn-toggle svg {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.install-dropdown-menu {
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
right: 0;
|
||||||
|
margin-top: 4px;
|
||||||
|
min-width: 160px;
|
||||||
|
background: var(--color-bg-secondary);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
|
z-index: 1000;
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
transform: translateY(-8px);
|
||||||
|
transition: all var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.install-dropdown.open .install-dropdown-menu {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.install-dropdown-menu a {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 10px 14px;
|
||||||
|
color: var(--color-text);
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 14px;
|
||||||
|
transition: background var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.install-dropdown-menu a:first-child {
|
||||||
|
border-radius: var(--border-radius) var(--border-radius) 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.install-dropdown-menu a:last-child {
|
||||||
|
border-radius: 0 0 var(--border-radius) var(--border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.install-dropdown-menu a:hover {
|
||||||
|
background: var(--color-bg-tertiary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.install-dropdown-menu svg {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Small variant for list items */
|
||||||
|
.install-dropdown.install-dropdown-small .install-btn-main {
|
||||||
|
padding: 8px 12px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.install-dropdown.install-dropdown-small .install-btn-toggle {
|
||||||
|
padding: 8px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.install-dropdown-menu .dropdown-divider {
|
||||||
|
height: 1px;
|
||||||
|
background: var(--color-border);
|
||||||
|
margin: 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Spinner animation */
|
/* Spinner animation */
|
||||||
@keyframes spin {
|
@keyframes spin {
|
||||||
from {
|
from {
|
||||||
|
|||||||
@@ -14,18 +14,29 @@
|
|||||||
</svg>
|
</svg>
|
||||||
Copy
|
Copy
|
||||||
</button>
|
</button>
|
||||||
<a id="install-btn" class="btn btn-primary" target="_blank" rel="noopener" title="Install to VS Code">
|
<div id="install-dropdown" class="install-dropdown" style="display: none;">
|
||||||
<svg viewBox="0 0 100 100" width="16" height="16" fill="currentColor">
|
<a id="install-btn-main" class="btn btn-primary install-btn-main" target="_blank" rel="noopener">
|
||||||
<path d="M95.436 26.986L75.282 15.768a6.04 6.04 0 0 0-6.895.876L28.78 51.927 11.912 39.151a4.03 4.03 0 0 0-5.154.387l-5.36 4.878a4.03 4.03 0 0 0-.003 5.947l14.646 13.396-14.646 13.396a4.03 4.03 0 0 0 .003 5.947l5.36 4.878a4.03 4.03 0 0 0 5.154.387L28.78 74.59l39.607 35.283a6.04 6.04 0 0 0 6.895.876l20.154-11.218a6.04 6.04 0 0 0 3.127-5.288V32.274a6.04 6.04 0 0 0-3.127-5.288zM75.015 73.428L46.339 51.927l28.676-21.5z" transform="scale(0.16)"/>
|
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||||
</svg>
|
<path d="M7.47 10.78a.75.75 0 0 0 1.06 0l3.75-3.75a.75.75 0 0 0-1.06-1.06L8.75 8.44V1.75a.75.75 0 0 0-1.5 0v6.69L4.78 5.97a.75.75 0 0 0-1.06 1.06l3.75 3.75ZM3.75 13a.75.75 0 0 0 0 1.5h8.5a.75.75 0 0 0 0-1.5h-8.5Z"/>
|
||||||
VS Code
|
</svg>
|
||||||
</a>
|
Install
|
||||||
<a id="install-insiders-btn" class="btn btn-secondary" target="_blank" rel="noopener" title="Install to VS Code Insiders">
|
</a>
|
||||||
<svg viewBox="0 0 100 100" width="16" height="16" fill="currentColor">
|
<button type="button" class="btn btn-primary install-btn-toggle" aria-label="Install options">
|
||||||
<path d="M95.436 26.986L75.282 15.768a6.04 6.04 0 0 0-6.895.876L28.78 51.927 11.912 39.151a4.03 4.03 0 0 0-5.154.387l-5.36 4.878a4.03 4.03 0 0 0-.003 5.947l14.646 13.396-14.646 13.396a4.03 4.03 0 0 0 .003 5.947l5.36 4.878a4.03 4.03 0 0 0 5.154.387L28.78 74.59l39.607 35.283a6.04 6.04 0 0 0 6.895.876l20.154-11.218a6.04 6.04 0 0 0 3.127-5.288V32.274a6.04 6.04 0 0 0-3.127-5.288zM75.015 73.428L46.339 51.927l28.676-21.5z" transform="scale(0.16)"/>
|
<svg viewBox="0 0 16 16" width="12" height="12" fill="currentColor">
|
||||||
</svg>
|
<path d="M4.427 7.427l3.396 3.396a.25.25 0 00.354 0l3.396-3.396A.25.25 0 0011.396 7H4.604a.25.25 0 00-.177.427z"/>
|
||||||
Insiders
|
</svg>
|
||||||
</a>
|
</button>
|
||||||
|
<div class="install-dropdown-menu">
|
||||||
|
<a id="install-vscode" target="_blank" rel="noopener">
|
||||||
|
<svg viewBox="0 0 100 100" fill="currentColor"><path d="M95.436 26.986L75.282 15.768a6.04 6.04 0 0 0-6.895.876L28.78 51.927 11.912 39.151a4.03 4.03 0 0 0-5.154.387l-5.36 4.878a4.03 4.03 0 0 0-.003 5.947l14.646 13.396-14.646 13.396a4.03 4.03 0 0 0 .003 5.947l5.36 4.878a4.03 4.03 0 0 0 5.154.387L28.78 74.59l39.607 35.283a6.04 6.04 0 0 0 6.895.876l20.154-11.218a6.04 6.04 0 0 0 3.127-5.288V32.274a6.04 6.04 0 0 0-3.127-5.288zM75.015 73.428L46.339 51.927l28.676-21.5z" transform="scale(0.16)"/></svg>
|
||||||
|
VS Code
|
||||||
|
</a>
|
||||||
|
<a id="install-insiders" target="_blank" rel="noopener">
|
||||||
|
<svg viewBox="0 0 100 100" fill="currentColor"><path d="M95.436 26.986L75.282 15.768a6.04 6.04 0 0 0-6.895.876L28.78 51.927 11.912 39.151a4.03 4.03 0 0 0-5.154.387l-5.36 4.878a4.03 4.03 0 0 0-.003 5.947l14.646 13.396-14.646 13.396a4.03 4.03 0 0 0 .003 5.947l5.36 4.878a4.03 4.03 0 0 0 5.154.387L28.78 74.59l39.607 35.283a6.04 6.04 0 0 0 6.895.876l20.154-11.218a6.04 6.04 0 0 0 3.127-5.288V32.274a6.04 6.04 0 0 0-3.127-5.288zM75.015 73.428L46.339 51.927l28.676-21.5z" transform="scale(0.16)"/></svg>
|
||||||
|
VS Code Insiders
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<button id="close-modal" class="btn btn-icon" title="Close">
|
<button id="close-modal" class="btn btn-icon" title="Close">
|
||||||
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
<svg viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
|
||||||
<path d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path>
|
<path d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"></path>
|
||||||
|
|||||||
@@ -37,6 +37,39 @@ export function setupModal(): void {
|
|||||||
showToast(success ? 'Copied to clipboard!' : 'Failed to copy', success ? 'success' : 'error');
|
showToast(success ? 'Copied to clipboard!' : 'Failed to copy', success ? 'success' : 'error');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Setup install dropdown toggle
|
||||||
|
setupInstallDropdown('install-dropdown');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup install dropdown toggle functionality
|
||||||
|
*/
|
||||||
|
export function setupInstallDropdown(containerId: string): void {
|
||||||
|
const container = document.getElementById(containerId);
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
const toggle = container.querySelector('.install-btn-toggle');
|
||||||
|
|
||||||
|
toggle?.addEventListener('click', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
container.classList.toggle('open');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close dropdown when clicking outside
|
||||||
|
document.addEventListener('click', (e) => {
|
||||||
|
if (!container.contains(e.target as Node)) {
|
||||||
|
container.classList.remove('open');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close dropdown when clicking a menu item
|
||||||
|
container.querySelectorAll('.install-dropdown-menu a').forEach(link => {
|
||||||
|
link.addEventListener('click', () => {
|
||||||
|
container.classList.remove('open');
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,8 +79,10 @@ export async function openFileModal(filePath: string, type: string): Promise<voi
|
|||||||
const modal = document.getElementById('file-modal');
|
const modal = document.getElementById('file-modal');
|
||||||
const title = document.getElementById('modal-title');
|
const title = document.getElementById('modal-title');
|
||||||
const contentEl = document.getElementById('modal-content')?.querySelector('code');
|
const contentEl = document.getElementById('modal-content')?.querySelector('code');
|
||||||
const installBtn = document.getElementById('install-btn') as HTMLAnchorElement | null;
|
const installDropdown = document.getElementById('install-dropdown');
|
||||||
const installInsidersBtn = document.getElementById('install-insiders-btn') as HTMLAnchorElement | null;
|
const installBtnMain = document.getElementById('install-btn-main') as HTMLAnchorElement | null;
|
||||||
|
const installVscode = document.getElementById('install-vscode') as HTMLAnchorElement | null;
|
||||||
|
const installInsiders = document.getElementById('install-insiders') as HTMLAnchorElement | null;
|
||||||
|
|
||||||
if (!modal || !title || !contentEl) return;
|
if (!modal || !title || !contentEl) return;
|
||||||
|
|
||||||
@@ -59,22 +94,18 @@ export async function openFileModal(filePath: string, type: string): Promise<voi
|
|||||||
contentEl.textContent = 'Loading...';
|
contentEl.textContent = 'Loading...';
|
||||||
modal.classList.remove('hidden');
|
modal.classList.remove('hidden');
|
||||||
|
|
||||||
// Setup install buttons (VS Code and VS Code Insiders)
|
// Setup install dropdown
|
||||||
const installUrl = getVSCodeInstallUrl(type, filePath, false);
|
const vscodeUrl = getVSCodeInstallUrl(type, filePath, false);
|
||||||
const installInsidersUrl = getVSCodeInstallUrl(type, filePath, true);
|
const insidersUrl = getVSCodeInstallUrl(type, filePath, true);
|
||||||
|
|
||||||
if (installUrl && installBtn) {
|
if (vscodeUrl && installDropdown) {
|
||||||
installBtn.href = installUrl;
|
installDropdown.style.display = 'inline-flex';
|
||||||
installBtn.style.display = 'inline-flex';
|
installDropdown.classList.remove('open');
|
||||||
} else if (installBtn) {
|
if (installBtnMain) installBtnMain.href = vscodeUrl;
|
||||||
installBtn.style.display = 'none';
|
if (installVscode) installVscode.href = vscodeUrl;
|
||||||
}
|
if (installInsiders) installInsiders.href = insidersUrl || '#';
|
||||||
|
} else if (installDropdown) {
|
||||||
if (installInsidersUrl && installInsidersBtn) {
|
installDropdown.style.display = 'none';
|
||||||
installInsidersBtn.href = installInsidersUrl;
|
|
||||||
installInsidersBtn.style.display = 'inline-flex';
|
|
||||||
} else if (installInsidersBtn) {
|
|
||||||
installInsidersBtn.style.display = 'none';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch and display content
|
// Fetch and display content
|
||||||
@@ -93,9 +124,15 @@ export async function openFileModal(filePath: string, type: string): Promise<voi
|
|||||||
*/
|
*/
|
||||||
export function closeModal(): void {
|
export function closeModal(): void {
|
||||||
const modal = document.getElementById('file-modal');
|
const modal = document.getElementById('file-modal');
|
||||||
|
const installDropdown = document.getElementById('install-dropdown');
|
||||||
|
|
||||||
if (modal) {
|
if (modal) {
|
||||||
modal.classList.add('hidden');
|
modal.classList.add('hidden');
|
||||||
}
|
}
|
||||||
|
if (installDropdown) {
|
||||||
|
installDropdown.classList.remove('open');
|
||||||
|
}
|
||||||
|
|
||||||
currentFilePath = null;
|
currentFilePath = null;
|
||||||
currentFileContent = null;
|
currentFileContent = null;
|
||||||
currentFileType = null;
|
currentFileType = null;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
import { createChoices, getChoicesValues, type Choices } from '../choices';
|
import { createChoices, getChoicesValues, type Choices } from '../choices';
|
||||||
import { FuzzySearch } from '../search';
|
import { FuzzySearch } from '../search';
|
||||||
import { fetchData, debounce, escapeHtml, getGitHubUrl, getVSCodeInstallUrl } from '../utils';
|
import { fetchData, debounce, escapeHtml, getGitHubUrl, getInstallDropdownHtml, setupDropdownCloseHandlers } from '../utils';
|
||||||
import { setupModal, openFileModal } from '../modal';
|
import { setupModal, openFileModal } from '../modal';
|
||||||
|
|
||||||
interface Agent {
|
interface Agent {
|
||||||
@@ -102,13 +102,7 @@ function renderItems(items: Agent[], query = ''): void {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="resource-actions">
|
<div class="resource-actions">
|
||||||
<a href="${getVSCodeInstallUrl(resourceType, item.path, false)}" class="btn btn-primary btn-small" target="_blank" onclick="event.stopPropagation()" title="Install to VS Code">
|
${getInstallDropdownHtml(resourceType, item.path, true)}
|
||||||
<svg viewBox="0 0 100 100" width="14" height="14" fill="currentColor"><path d="M95.436 26.986L75.282 15.768a6.04 6.04 0 0 0-6.895.876L28.78 51.927 11.912 39.151a4.03 4.03 0 0 0-5.154.387l-5.36 4.878a4.03 4.03 0 0 0-.003 5.947l14.646 13.396-14.646 13.396a4.03 4.03 0 0 0 .003 5.947l5.36 4.878a4.03 4.03 0 0 0 5.154.387L28.78 74.59l39.607 35.283a6.04 6.04 0 0 0 6.895.876l20.154-11.218a6.04 6.04 0 0 0 3.127-5.288V32.274a6.04 6.04 0 0 0-3.127-5.288zM75.015 73.428L46.339 51.927l28.676-21.5z" transform="scale(0.16)"/></svg>
|
|
||||||
VS Code
|
|
||||||
</a>
|
|
||||||
<a href="${getVSCodeInstallUrl(resourceType, item.path, true)}" class="btn btn-secondary btn-small" target="_blank" onclick="event.stopPropagation()" title="Install to VS Code Insiders">
|
|
||||||
Insiders
|
|
||||||
</a>
|
|
||||||
<a href="${getGitHubUrl(item.path)}" class="btn btn-secondary btn-small" target="_blank" onclick="event.stopPropagation()">
|
<a href="${getGitHubUrl(item.path)}" class="btn btn-secondary btn-small" target="_blank" onclick="event.stopPropagation()">
|
||||||
GitHub
|
GitHub
|
||||||
</a>
|
</a>
|
||||||
@@ -175,6 +169,7 @@ export async function initAgentsPage(): Promise<void> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
setupModal();
|
setupModal();
|
||||||
|
setupDropdownCloseHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto-initialize when DOM is ready
|
// Auto-initialize when DOM is ready
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
import { createChoices, getChoicesValues, type Choices } from '../choices';
|
import { createChoices, getChoicesValues, type Choices } from '../choices';
|
||||||
import { FuzzySearch } from '../search';
|
import { FuzzySearch } from '../search';
|
||||||
import { fetchData, debounce, escapeHtml, getGitHubUrl, getVSCodeInstallUrl } from '../utils';
|
import { fetchData, debounce, escapeHtml, getGitHubUrl, getInstallDropdownHtml, setupDropdownCloseHandlers } from '../utils';
|
||||||
import { setupModal, openFileModal } from '../modal';
|
import { setupModal, openFileModal } from '../modal';
|
||||||
|
|
||||||
interface Instruction {
|
interface Instruction {
|
||||||
@@ -72,13 +72,7 @@ function renderItems(items: Instruction[], query = ''): void {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="resource-actions">
|
<div class="resource-actions">
|
||||||
<a href="${getVSCodeInstallUrl('instructions', item.path, false)}" class="btn btn-primary btn-small" target="_blank" onclick="event.stopPropagation()" title="Install to VS Code">
|
${getInstallDropdownHtml('instructions', item.path, true)}
|
||||||
<svg viewBox="0 0 100 100" width="14" height="14" fill="currentColor"><path d="M95.436 26.986L75.282 15.768a6.04 6.04 0 0 0-6.895.876L28.78 51.927 11.912 39.151a4.03 4.03 0 0 0-5.154.387l-5.36 4.878a4.03 4.03 0 0 0-.003 5.947l14.646 13.396-14.646 13.396a4.03 4.03 0 0 0 .003 5.947l5.36 4.878a4.03 4.03 0 0 0 5.154.387L28.78 74.59l39.607 35.283a6.04 6.04 0 0 0 6.895.876l20.154-11.218a6.04 6.04 0 0 0 3.127-5.288V32.274a6.04 6.04 0 0 0-3.127-5.288zM75.015 73.428L46.339 51.927l28.676-21.5z" transform="scale(0.16)"/></svg>
|
|
||||||
VS Code
|
|
||||||
</a>
|
|
||||||
<a href="${getVSCodeInstallUrl('instructions', item.path, true)}" class="btn btn-secondary btn-small" target="_blank" onclick="event.stopPropagation()" title="Install to VS Code Insiders">
|
|
||||||
Insiders
|
|
||||||
</a>
|
|
||||||
<a href="${getGitHubUrl(item.path)}" class="btn btn-secondary btn-small" target="_blank" onclick="event.stopPropagation()">
|
<a href="${getGitHubUrl(item.path)}" class="btn btn-secondary btn-small" target="_blank" onclick="event.stopPropagation()">
|
||||||
GitHub
|
GitHub
|
||||||
</a>
|
</a>
|
||||||
@@ -127,6 +121,7 @@ export async function initInstructionsPage(): Promise<void> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
setupModal();
|
setupModal();
|
||||||
|
setupDropdownCloseHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto-initialize when DOM is ready
|
// Auto-initialize when DOM is ready
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
import { createChoices, getChoicesValues, type Choices } from '../choices';
|
import { createChoices, getChoicesValues, type Choices } from '../choices';
|
||||||
import { FuzzySearch } from '../search';
|
import { FuzzySearch } from '../search';
|
||||||
import { fetchData, debounce, escapeHtml, getGitHubUrl, getVSCodeInstallUrl } from '../utils';
|
import { fetchData, debounce, escapeHtml, getGitHubUrl, getInstallDropdownHtml, setupDropdownCloseHandlers } from '../utils';
|
||||||
import { setupModal, openFileModal } from '../modal';
|
import { setupModal, openFileModal } from '../modal';
|
||||||
|
|
||||||
interface Prompt {
|
interface Prompt {
|
||||||
@@ -67,13 +67,7 @@ function renderItems(items: Prompt[], query = ''): void {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="resource-actions">
|
<div class="resource-actions">
|
||||||
<a href="${getVSCodeInstallUrl(resourceType, item.path, false)}" class="btn btn-primary btn-small" target="_blank" onclick="event.stopPropagation()" title="Install to VS Code">
|
${getInstallDropdownHtml(resourceType, item.path, true)}
|
||||||
<svg viewBox="0 0 100 100" width="14" height="14" fill="currentColor"><path d="M95.436 26.986L75.282 15.768a6.04 6.04 0 0 0-6.895.876L28.78 51.927 11.912 39.151a4.03 4.03 0 0 0-5.154.387l-5.36 4.878a4.03 4.03 0 0 0-.003 5.947l14.646 13.396-14.646 13.396a4.03 4.03 0 0 0 .003 5.947l5.36 4.878a4.03 4.03 0 0 0 5.154.387L28.78 74.59l39.607 35.283a6.04 6.04 0 0 0 6.895.876l20.154-11.218a6.04 6.04 0 0 0 3.127-5.288V32.274a6.04 6.04 0 0 0-3.127-5.288zM75.015 73.428L46.339 51.927l28.676-21.5z" transform="scale(0.16)"/></svg>
|
|
||||||
VS Code
|
|
||||||
</a>
|
|
||||||
<a href="${getVSCodeInstallUrl(resourceType, item.path, true)}" class="btn btn-secondary btn-small" target="_blank" onclick="event.stopPropagation()" title="Install to VS Code Insiders">
|
|
||||||
Insiders
|
|
||||||
</a>
|
|
||||||
<a href="${getGitHubUrl(item.path)}" class="btn btn-secondary btn-small" target="_blank" onclick="event.stopPropagation()">
|
<a href="${getGitHubUrl(item.path)}" class="btn btn-secondary btn-small" target="_blank" onclick="event.stopPropagation()">
|
||||||
GitHub
|
GitHub
|
||||||
</a>
|
</a>
|
||||||
@@ -122,6 +116,7 @@ export async function initPromptsPage(): Promise<void> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
setupModal();
|
setupModal();
|
||||||
|
setupDropdownCloseHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto-initialize when DOM is ready
|
// Auto-initialize when DOM is ready
|
||||||
|
|||||||
@@ -205,3 +205,57 @@ export function getResourceIcon(type: string): string {
|
|||||||
};
|
};
|
||||||
return icons[type] || '📄';
|
return icons[type] || '📄';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate HTML for install dropdown button
|
||||||
|
*/
|
||||||
|
export function getInstallDropdownHtml(type: string, filePath: string, small = false): string {
|
||||||
|
const vscodeUrl = getVSCodeInstallUrl(type, filePath, false);
|
||||||
|
const insidersUrl = getVSCodeInstallUrl(type, filePath, true);
|
||||||
|
|
||||||
|
if (!vscodeUrl) return '';
|
||||||
|
|
||||||
|
const sizeClass = small ? 'install-dropdown-small' : '';
|
||||||
|
const uniqueId = `install-${filePath.replace(/[^a-zA-Z0-9]/g, '-')}`;
|
||||||
|
|
||||||
|
return `
|
||||||
|
<div class="install-dropdown ${sizeClass}" id="${uniqueId}" onclick="event.stopPropagation()">
|
||||||
|
<a href="${vscodeUrl}" class="btn btn-primary ${small ? 'btn-small' : ''} install-btn-main" target="_blank" rel="noopener">
|
||||||
|
<svg viewBox="0 0 16 16" width="${small ? 14 : 16}" height="${small ? 14 : 16}" fill="currentColor">
|
||||||
|
<path d="M7.47 10.78a.75.75 0 0 0 1.06 0l3.75-3.75a.75.75 0 0 0-1.06-1.06L8.75 8.44V1.75a.75.75 0 0 0-1.5 0v6.69L4.78 5.97a.75.75 0 0 0-1.06 1.06l3.75 3.75ZM3.75 13a.75.75 0 0 0 0 1.5h8.5a.75.75 0 0 0 0-1.5h-8.5Z"/>
|
||||||
|
</svg>
|
||||||
|
Install
|
||||||
|
</a>
|
||||||
|
<button type="button" class="btn btn-primary ${small ? 'btn-small' : ''} install-btn-toggle" aria-label="Install options" onclick="event.preventDefault(); this.parentElement.classList.toggle('open');">
|
||||||
|
<svg viewBox="0 0 16 16" width="12" height="12" fill="currentColor">
|
||||||
|
<path d="M4.427 7.427l3.396 3.396a.25.25 0 00.354 0l3.396-3.396A.25.25 0 0011.396 7H4.604a.25.25 0 00-.177.427z"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<div class="install-dropdown-menu">
|
||||||
|
<a href="${vscodeUrl}" target="_blank" rel="noopener" onclick="this.closest('.install-dropdown').classList.remove('open')">
|
||||||
|
<svg viewBox="0 0 100 100" fill="currentColor"><path d="M95.436 26.986L75.282 15.768a6.04 6.04 0 0 0-6.895.876L28.78 51.927 11.912 39.151a4.03 4.03 0 0 0-5.154.387l-5.36 4.878a4.03 4.03 0 0 0-.003 5.947l14.646 13.396-14.646 13.396a4.03 4.03 0 0 0 .003 5.947l5.36 4.878a4.03 4.03 0 0 0 5.154.387L28.78 74.59l39.607 35.283a6.04 6.04 0 0 0 6.895.876l20.154-11.218a6.04 6.04 0 0 0 3.127-5.288V32.274a6.04 6.04 0 0 0-3.127-5.288zM75.015 73.428L46.339 51.927l28.676-21.5z" transform="scale(0.16)"/></svg>
|
||||||
|
VS Code
|
||||||
|
</a>
|
||||||
|
<a href="${insidersUrl}" target="_blank" rel="noopener" onclick="this.closest('.install-dropdown').classList.remove('open')">
|
||||||
|
<svg viewBox="0 0 100 100" fill="currentColor"><path d="M95.436 26.986L75.282 15.768a6.04 6.04 0 0 0-6.895.876L28.78 51.927 11.912 39.151a4.03 4.03 0 0 0-5.154.387l-5.36 4.878a4.03 4.03 0 0 0-.003 5.947l14.646 13.396-14.646 13.396a4.03 4.03 0 0 0 .003 5.947l5.36 4.878a4.03 4.03 0 0 0 5.154.387L28.78 74.59l39.607 35.283a6.04 6.04 0 0 0 6.895.876l20.154-11.218a6.04 6.04 0 0 0 3.127-5.288V32.274a6.04 6.04 0 0 0-3.127-5.288zM75.015 73.428L46.339 51.927l28.676-21.5z" transform="scale(0.16)"/></svg>
|
||||||
|
VS Code Insiders
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup dropdown close handlers for dynamically created dropdowns
|
||||||
|
*/
|
||||||
|
export function setupDropdownCloseHandlers(): void {
|
||||||
|
document.addEventListener('click', (e) => {
|
||||||
|
const target = e.target as HTMLElement;
|
||||||
|
// Close all open dropdowns if clicking outside
|
||||||
|
if (!target.closest('.install-dropdown')) {
|
||||||
|
document.querySelectorAll('.install-dropdown.open').forEach(dropdown => {
|
||||||
|
dropdown.classList.remove('open');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user