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}
`;
}
}