Skip to content

Commit 5c53acd

Browse files
committed
feat: ARIA speech bubble hints, Solana-focused commands, entrance animation
1 parent 038f21f commit 5c53acd

3 files changed

Lines changed: 164 additions & 36 deletions

File tree

src/panels/Terminal/Terminal.css

Lines changed: 113 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -359,45 +359,130 @@
359359
border-radius: 3px;
360360
}
361361

362+
/* ── ARIA speech bubble overlays ── hints + history search */
363+
364+
@keyframes ariaHintIn {
365+
from {
366+
opacity: 0;
367+
transform: translateY(4px);
368+
}
369+
to {
370+
opacity: 1;
371+
transform: translateY(0);
372+
}
373+
}
374+
362375
.terminal-overlay {
363376
position: absolute;
364377
right: 10px;
365378
bottom: 10px;
366-
width: min(420px, calc(100% - 20px));
379+
width: min(300px, calc(100% - 20px));
367380
border: 1px solid var(--border);
368381
border-radius: 8px;
369-
background: rgba(16, 16, 16, 0.97);
370-
backdrop-filter: blur(6px);
371-
padding: 8px;
382+
background: var(--s2);
383+
backdrop-filter: blur(8px);
384+
padding: 7px 8px;
372385
display: flex;
373386
flex-direction: column;
374-
gap: 4px;
387+
gap: 3px;
375388
z-index: 4;
376389
}
377390

378-
.terminal-overlay-header {
391+
/* ARIA speech bubble variant */
392+
.terminal-overlay.aria-bubble {
393+
border-color: rgba(62, 207, 142, 0.2);
394+
background: var(--s2);
395+
box-shadow:
396+
0 0 0 1px rgba(62, 207, 142, 0.06) inset,
397+
var(--shadow-float),
398+
0 0 16px rgba(62, 207, 142, 0.04);
399+
animation: ariaHintIn 0.15s ease both;
400+
}
401+
402+
/* Tail pointing toward the bottom-right corner (where ARIA lives) */
403+
.aria-bubble-tail {
404+
position: absolute;
405+
bottom: -6px;
406+
right: 18px;
407+
width: 10px;
408+
height: 6px;
409+
overflow: visible;
410+
pointer-events: none;
411+
}
412+
413+
.aria-bubble-tail::before,
414+
.aria-bubble-tail::after {
415+
content: '';
416+
position: absolute;
417+
bottom: 0;
418+
right: 0;
419+
border-style: solid;
420+
}
421+
422+
/* Outer tail (border color) */
423+
.aria-bubble-tail::before {
424+
border-width: 6px 5px 0 5px;
425+
border-color: rgba(62, 207, 142, 0.2) transparent transparent transparent;
426+
right: 0;
427+
}
428+
429+
/* Inner tail (fill color) */
430+
.aria-bubble-tail::after {
431+
border-width: 5px 4px 0 4px;
432+
border-color: var(--s2) transparent transparent transparent;
433+
right: 1px;
434+
bottom: 1px;
435+
}
436+
437+
/* Identity row — owl icon + "aria" label */
438+
.aria-bubble-identity {
379439
display: flex;
380440
align-items: center;
381-
justify-content: space-between;
441+
gap: 5px;
382442
}
383443

384-
.terminal-overlay-title {
444+
.aria-hint-owl {
445+
flex-shrink: 0;
446+
display: block;
447+
}
448+
449+
.aria-bubble-label {
385450
font-size: 10px;
386-
color: var(--t3);
387-
text-transform: uppercase;
388-
letter-spacing: 0.4px;
451+
font-family: var(--font-code);
452+
color: var(--green);
453+
letter-spacing: 1px;
454+
opacity: 0.75;
455+
}
456+
457+
.aria-bubble-hint-key {
458+
font-size: 9px;
459+
font-family: var(--font-code);
460+
color: var(--t4);
461+
letter-spacing: 0.3px;
462+
padding: 0 4px;
463+
border: 1px solid var(--border);
464+
border-radius: 3px;
465+
line-height: 1.6;
466+
}
467+
468+
.terminal-overlay-header {
469+
display: flex;
470+
align-items: center;
471+
justify-content: space-between;
472+
margin-bottom: 2px;
389473
}
390474

391475
.terminal-overlay-dismiss {
392476
width: 16px;
393477
height: 16px;
394478
font-size: 12px;
395-
color: var(--t3);
479+
color: var(--t4);
396480
display: flex;
397481
align-items: center;
398482
justify-content: center;
399483
border-radius: 3px;
400484
cursor: pointer;
485+
flex-shrink: 0;
401486
}
402487

403488
.terminal-overlay-dismiss:hover {
@@ -407,30 +492,36 @@
407492

408493
.terminal-overlay-item {
409494
height: 24px;
410-
border-radius: 4px;
411-
font-family: 'JetBrains Mono', 'Cascadia Code', monospace;
495+
border-radius: var(--radius-md);
496+
font-family: var(--font-code);
412497
font-size: 11px;
413498
text-align: left;
414499
color: var(--t2);
415-
padding: 0 8px;
500+
padding: 0 7px;
501+
transition: background var(--transition-fast), color var(--transition-fast);
416502
}
417503

418504
.terminal-overlay-item:hover,
419505
.terminal-overlay-item.active {
420-
background: var(--hover-bg);
506+
background: var(--s3);
421507
color: var(--t1);
422508
}
423509

510+
.terminal-overlay-item.active {
511+
color: var(--green);
512+
}
513+
424514
.terminal-history-query {
425515
min-height: 22px;
426516
border: 1px solid var(--border);
427-
border-radius: 4px;
517+
border-radius: var(--radius-md);
428518
display: flex;
429519
align-items: center;
430520
padding: 0 8px;
431521
font-size: 11px;
432522
color: var(--t1);
433-
font-family: 'JetBrains Mono', 'Cascadia Code', monospace;
523+
font-family: var(--font-code);
524+
margin-bottom: 2px;
434525
}
435526

436527
.terminal-history-query:focus-within {
@@ -441,13 +532,14 @@
441532
.terminal-history-results {
442533
display: flex;
443534
flex-direction: column;
444-
gap: 2px;
535+
gap: 1px;
445536
}
446537

447538
.terminal-history-empty {
448539
font-size: 11px;
449-
color: var(--t3);
450-
padding: 4px 2px;
540+
font-family: var(--font-code);
541+
color: var(--t4);
542+
padding: 4px 7px;
451543
}
452544

453545
/* Terminal output search overlay — top-right of terminal container */

src/panels/Terminal/TerminalOverlays.tsx

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
import { useRef, useEffect } from 'react'
22

3+
// Minimal inline owl — two dots for eyes, no external dependency
4+
function AriaOwlMini() {
5+
return (
6+
<svg
7+
className="aria-hint-owl"
8+
width="14"
9+
height="10"
10+
viewBox="0 0 14 10"
11+
fill="none"
12+
aria-hidden="true"
13+
>
14+
<ellipse cx="4" cy="5" rx="2.5" ry="3" fill="var(--s3)" stroke="var(--s5)" strokeWidth="0.6" />
15+
<ellipse cx="10" cy="5" rx="2.5" ry="3" fill="var(--s3)" stroke="var(--s5)" strokeWidth="0.6" />
16+
<circle cx="4" cy="5" r="1.1" fill="var(--green)" opacity="0.85" />
17+
<circle cx="10" cy="5" r="1.1" fill="var(--green)" opacity="0.85" />
18+
<circle cx="4.4" cy="4.6" r="0.35" fill="var(--bg)" />
19+
<circle cx="10.4" cy="4.6" r="0.35" fill="var(--bg)" />
20+
</svg>
21+
)
22+
}
23+
324
// --- Terminal output search ---
425

526
interface TerminalSearchOverlayProps {
@@ -80,13 +101,19 @@ interface HintsOverlayProps {
80101

81102
export function HintsOverlay({ hints, onAcceptHint, onDismiss }: HintsOverlayProps) {
82103
return (
83-
<div className="terminal-overlay hints" onPointerDown={(e) => e.stopPropagation()}>
104+
<div className="terminal-overlay hints aria-bubble" onPointerDown={(e) => e.stopPropagation()}>
105+
<div className="aria-bubble-tail" aria-hidden="true" />
84106
<div className="terminal-overlay-header">
85-
<div className="terminal-overlay-title">Hints (Tab)</div>
107+
<div className="aria-bubble-identity">
108+
<AriaOwlMini />
109+
<span className="aria-bubble-label">aria</span>
110+
</div>
86111
<button className="terminal-overlay-dismiss" onClick={onDismiss}>&times;</button>
87112
</div>
88113
{hints.slice(0, 5).map((hint) => (
89-
<button key={hint} className="terminal-overlay-item" onClick={() => onAcceptHint(hint)}>{hint}</button>
114+
<button key={hint} className="terminal-overlay-item" onClick={() => onAcceptHint(hint)}>
115+
{hint}
116+
</button>
90117
))}
91118
</div>
92119
)
@@ -103,8 +130,15 @@ interface HistorySearchOverlayProps {
103130

104131
export function HistorySearchOverlay({ query, matches, selectionIndex, onSelectAndApply }: HistorySearchOverlayProps) {
105132
return (
106-
<div className="terminal-overlay history-search">
107-
<div className="terminal-overlay-title">History Search (Ctrl+R)</div>
133+
<div className="terminal-overlay history-search aria-bubble" onPointerDown={(e) => e.stopPropagation()}>
134+
<div className="aria-bubble-tail" aria-hidden="true" />
135+
<div className="terminal-overlay-header">
136+
<div className="aria-bubble-identity">
137+
<AriaOwlMini />
138+
<span className="aria-bubble-label">aria</span>
139+
<span className="aria-bubble-hint-key">ctrl+r</span>
140+
</div>
141+
</div>
108142
<div className="terminal-history-query">{query || 'type to filter...'}</div>
109143
<div className="terminal-history-results">
110144
{matches.slice(0, 8).map((match, index) => (

src/panels/Terminal/useTerminalInput.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
import { useRef, useMemo, useState } from 'react'
22

33
const COMMAND_HINTS = [
4+
'anchor build',
5+
'anchor test',
6+
'anchor deploy',
7+
'solana balance',
8+
'solana airdrop 2',
9+
'pnpm run dev',
10+
'pnpm run build',
11+
'pnpm run test',
12+
'pnpm install',
413
'git status',
5-
'git diff',
614
'git add .',
715
'git commit -m ""',
16+
'git push',
817
'npm run dev',
9-
'npm run build',
10-
'npm test',
11-
'pnpm install',
12-
'pnpm dev',
13-
'pnpm build',
14-
'ls',
15-
'cd ..',
16-
'pwd',
17-
'clear',
18+
'cargo build',
19+
'cargo test',
1820
]
1921

2022
export function useTerminalInput(terminalId: string) {

0 commit comments

Comments
 (0)