fix terminal styling: scaling banner, mobile padding, typing caret, echoed prompt
site / generated-is-current (push) Successful in 21s
site / generated-is-current (push) Successful in 21s
- banner scales down to fit narrow screens instead of scrolling sideways - smaller base font/padding under sm: to stop the crooked mobile look - block caret tracks the cursor position inside the input (ghost-span measurement) instead of sitting at the line end - executed commands echo with the momme@world:~$ prompt in front
This commit is contained in:
+28
-1
@@ -63,6 +63,28 @@ const make = (tag, cls, value) => {
|
||||
|
||||
const scrollDown = () => (screen.scrollTop = screen.scrollHeight);
|
||||
|
||||
// banner: shrink to fit instead of scrolling sideways
|
||||
const banner = document.getElementById("banner");
|
||||
const fitBanner = () => {
|
||||
banner.style.transform = "";
|
||||
banner.style.height = "";
|
||||
// clientWidth = box the banner had to fit in; scrollWidth = what it wants
|
||||
const scale = Math.min(1, banner.clientWidth / banner.scrollWidth);
|
||||
banner.style.transform = `scale(${scale})`;
|
||||
banner.style.height = `${banner.offsetHeight * scale}px`;
|
||||
};
|
||||
addEventListener("resize", fitBanner);
|
||||
|
||||
// caret: follow the text actually typed in the input (the ghost span measures it)
|
||||
const caretEl = document.getElementById("caret");
|
||||
const ghost = document.getElementById("ghost");
|
||||
const moveCaret = () => {
|
||||
const pos = input.selectionStart ?? input.value.length;
|
||||
ghost.textContent = input.value.slice(0, pos);
|
||||
caretEl.style.left = `${ghost.getBoundingClientRect().width - input.scrollLeft}px`;
|
||||
};
|
||||
for (const ev of ["input", "keyup", "click", "focus"]) input.addEventListener(ev, moveCaret);
|
||||
|
||||
// ---------- typewriter ----------
|
||||
// print() never renders directly: it queues fully-built line nodes and this
|
||||
// machine writes them character by character. A keypress or click while
|
||||
@@ -239,7 +261,9 @@ function lookup(words) {
|
||||
|
||||
function execute(raw) {
|
||||
flush();
|
||||
out.append(make("div", "block text-fg mt-4", raw));
|
||||
const echo = make("div", "block mt-4");
|
||||
echo.append(make("span", "text-accent", "momme@world:~$ "), make("span", "text-fg", raw));
|
||||
out.append(echo);
|
||||
const words = raw.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
||||
if (!words.length) return scrollDown();
|
||||
if (words[0] === "clear") return kill(), (out.textContent = "");
|
||||
@@ -268,6 +292,7 @@ form.addEventListener("submit", (event) => {
|
||||
event.preventDefault();
|
||||
const raw = input.value;
|
||||
input.value = "";
|
||||
moveCaret();
|
||||
if (raw.trim()) history.items.push(raw.trim());
|
||||
history.at = history.items.length;
|
||||
execute(raw);
|
||||
@@ -296,8 +321,10 @@ load().then(
|
||||
input.focus();
|
||||
})
|
||||
);
|
||||
fitBanner();
|
||||
print("hello — type help for the rest of it.", "");
|
||||
input.focus();
|
||||
moveCaret();
|
||||
},
|
||||
() => print({ error: "commands.json did not load — did the site generator run?", more: [] }, "")
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user