nexus-overdrive / components /terminal.js
00Boobs00's picture
Expand, refactor and iterate much further with my full appreciation.
e475bc2 verified
class CustomTerminal extends HTMLElement {
connectedCallback() {
const title = this.getAttribute('title') || 'NEXUS TERMINAL';
const lines = this.getAttribute('lines') || '5';
const autoScroll = this.hasAttribute('auto-scroll');
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
:host {
display: block;
font-family: 'Courier New', monospace;
}
.terminal {
background: #0a0a0a;
border: 1px solid #222;
border-radius: 8px;
overflow: hidden;
}
.terminal-header {
background: #111;
padding: 0.75rem 1rem;
display: flex;
align-items: center;
gap: 0.5rem;
border-bottom: 1px solid #222;
}
.dot {
width: 12px;
height: 12px;
border-radius: 50%;
}
.dot-red { background: #ff5f57; }
.dot-yellow { background: #febc2e; }
.dot-green { background: #28c840; }
.terminal-title {
flex: 1;
text-align: center;
color: #666;
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 0.1em;
}
.terminal-body {
padding: 1rem;
height: ${lines * 24 + 32}px;
overflow-y: auto;
background: linear-gradient(180deg, #0a0a0a 0%, #050505 100%);
}
.terminal-line {
margin: 0.25rem 0;
font-size: 0.875rem;
line-height: 1.5;
}
.line-prefix {
color: #b026ff;
}
.line-content {
color: #00ff9d;
}
.line-error {
color: #ff003c;
}
.line-info {
color: #00f3ff;
}
.line-system {
color: #666;
}
.cursor {
display: inline-block;
width: 8px;
height: 16px;
background: #00ff9d;
animation: blink 1s step-end infinite;
vertical-align: middle;
}
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: #0a0a0a;
}
::-webkit-scrollbar-thumb {
background: #222;
border-radius: 3px;
}
</style>
<div class="terminal">
<div class="terminal-header">
<div class="dot dot-red"></div>
<div class="dot dot-yellow"></div>
<div class="dot dot-green"></div>
<span class="terminal-title">${title}</span>
</div>
<div class="terminal-body" id="terminal-body">
<div class="terminal-line">
<span class="line-prefix">nexus@overdrive:~$</span>
<span class="line-content"> initializing autonomous systems...</span>
</div>
<div class="terminal-line">
<span class="line-prefix">nexus@overdrive:~$</span>
<span class="line-info"> βœ“ neural network online</span>
</div>
<div class="terminal-line">
<span class="line-prefix">nexus@overdrive:~$</span>
<span class="line-info"> βœ“ quantum processors connected</span>
</div>
<div class="terminal-line">
<span class="line-prefix">nexus@overdrive:~$</span>
<span class="line-system"> awaiting input...<span class="cursor"></span></span>
</div>
</div>
</div>
`;
}
addLine(content, type = 'default') {
const body = this.shadowRoot.getElementById('terminal-body');
const prefix = this.getAttribute('prefix') || 'nexus@overdrive:~$';
const typeClass = {
default: 'line-content',
error: 'line-error',
info: 'line-info',
system: 'line-system'
}[type] || 'line-content';
// Remove cursor from last line
const lastLine = body.lastElementChild;
if (lastLine) {
const cursor = lastLine.querySelector('.cursor');
if (cursor) cursor.remove();
}
// Add new line
const line = document.createElement('div');
line.className = 'terminal-line';
line.innerHTML = `
<span class="line-prefix">${prefix}</span>
<span class="${typeClass}"> ${content}</span>
`;
body.appendChild(line);
// Add cursor to new line
const cursorLine = document.createElement('div');
cursorLine.className = 'terminal-line';
cursorLine.innerHTML = `<span class="line-prefix">${prefix}</span><span class="line-system"> awaiting input...<span class="cursor"></span></span>`;
body.appendChild(cursorLine);
// Auto scroll
if (this.hasAttribute('auto-scroll')) {
body.scrollTop = body.scrollHeight;
}
}
clear() {
const body = this.shadowRoot.getElementById('terminal-body');
body.innerHTML = '';
}
}
customElements.define('custom-terminal', CustomTerminal);