import { DeesElement, customElement, html, property, css, cssManager, type TemplateResult, } from '@design.estate/dees-element'; import type { TSgProtocol } from '../interfaces.js'; declare global { interface HTMLElementTagNameMap { 'sg-install-snippet': SgInstallSnippet; } } @customElement('sg-install-snippet') export class SgInstallSnippet extends DeesElement { public static demo = () => html`
`; public static demoGroups = ['Packages']; @property({ type: String }) accessor protocol: TSgProtocol = 'npm'; @property({ type: String }) accessor packageName: string = ''; @property({ type: String }) accessor registryUrl: string = ''; public static styles = [ cssManager.defaultStyles, css` :host { display: block; } .snippet { background: ${cssManager.bdTheme('#f5f5f5', '#111')}; border: 1px solid ${cssManager.bdTheme('#e5e5e5', '#333')}; padding: 12px 16px; font-family: 'JetBrains Mono', monospace; font-size: 13px; color: ${cssManager.bdTheme('#333', '#e5e5e5')}; position: relative; overflow-x: auto; white-space: nowrap; } .label { font-size: 11px; color: ${cssManager.bdTheme('#999', '#666')}; margin-bottom: 4px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; text-transform: uppercase; letter-spacing: 0.05em; } .copy-btn { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); background: ${cssManager.bdTheme('#e5e5e5', '#333')}; border: none; padding: 4px 8px; cursor: pointer; font-size: 11px; color: ${cssManager.bdTheme('#666', '#999')}; } .copy-btn:hover { background: ${cssManager.bdTheme('#ddd', '#444')}; } `, ]; private getInstallCommand(): { label: string; command: string } { const reg = this.registryUrl; switch (this.protocol) { case 'npm': return { label: 'npm', command: reg ? `npm install ${this.packageName} --registry=https://${reg}` : `npm install ${this.packageName}`, }; case 'oci': return { label: 'Docker / OCI', command: reg ? `docker pull ${reg}/${this.packageName}` : `docker pull ${this.packageName}`, }; case 'maven': return { label: 'Maven', command: `\n ${this.packageName.split('/')[0] || ''}\n ${this.packageName.split('/')[1] || this.packageName}\n`, }; case 'cargo': return { label: 'Cargo', command: `cargo add ${this.packageName}`, }; case 'pypi': return { label: 'pip', command: reg ? `pip install ${this.packageName} --index-url https://${reg}/simple/` : `pip install ${this.packageName}`, }; case 'composer': return { label: 'Composer', command: `composer require ${this.packageName}`, }; case 'rubygems': return { label: 'gem', command: reg ? `gem install ${this.packageName} --source https://${reg}` : `gem install ${this.packageName}`, }; default: return { label: this.protocol, command: this.packageName }; } } private async copyToClipboard() { const { command } = this.getInstallCommand(); try { await navigator.clipboard.writeText(command); } catch { // Fallback for browsers without clipboard API } } public render(): TemplateResult { const { label, command } = this.getInstallCommand(); return html`
${label}
${command}
`; } }