From ef0e0c8dd2447c27cbca2a60618ad741eb3ff83e Mon Sep 17 00:00:00 2001 From: MatMoul Date: Fri, 15 May 2026 20:56:05 +0200 Subject: [PATCH] feat: show calculator status messages as overlay bar --- .memory/state.md | 2 +- samples/calc-02/index.css | 39 ++++++++++++++++++++++++++++++++------ samples/calc-02/index.html | 1 + samples/calc-02/index.js | 22 +++++++++++++++++---- 4 files changed, 53 insertions(+), 11 deletions(-) diff --git a/.memory/state.md b/.memory/state.md index 389d398..2c2862d 100644 --- a/.memory/state.md +++ b/.memory/state.md @@ -5,5 +5,5 @@ - Public API: `push`, `pop`, `clear`, `swap`, `remove`, `edit`, `isValidIndex`, `input`, `command`, `getOperationsByCategory`, `getConstants` - Config: `maxSize`, `base`, `angleMode`, `enabledCommands` - Commands: arithmetic, stack, trigonometry, constants `pi` and `e` -- Demo actions: paste now parses clipboard text as a number before pushing it to the stack; Ctrl+V is supported via the hidden input paste event; backspace is ignored when the stack is empty +- Demo actions: paste now parses clipboard text as a number before pushing it to the stack; Ctrl+V is supported via the hidden input paste event; backspace is ignored when the stack is empty; operation errors are shown as an overlay bar on top of the calculator with a shorter timeout and darker red - Exports: browser `window.RpnCalculator`, CommonJS `module.exports` diff --git a/samples/calc-02/index.css b/samples/calc-02/index.css index 628f27d..d47fd2f 100644 --- a/samples/calc-02/index.css +++ b/samples/calc-02/index.css @@ -65,6 +65,8 @@ body { "buttons functions" "keypad functions" "keypad trigo"; + + } .display-panel, @@ -81,6 +83,7 @@ body { .display-panel { grid-area: display; + position: relative; padding: clamp(12px, 1.5vw, 16px); background: linear-gradient(180deg, var(--display), var(--display2)); color: var(--displayText); @@ -203,14 +206,38 @@ body { padding-top: 10px; } -.status-line { - grid-area: status; - padding: 10px 14px; +.status-bar { + position: absolute; + top: 0; + left: 0; + right: 0; + z-index: 2; + padding: 8px 12px; + min-height: 30px; display: flex; align-items: center; - min-height: 42px; - font-size: 14px; - color: rgba(255, 255, 255, 0.85); + justify-content: center; + font-size: 13px; + font-weight: 700; + letter-spacing: 0.02em; + color: rgba(31, 42, 18, 0.96); + background: rgba(255, 246, 170, 0.92); + border-bottom: 1px solid rgba(31, 42, 18, 0.2); + transform: translateY(-100%); + opacity: 0; + transition: transform 180ms ease, opacity 180ms ease; + pointer-events: none; +} + +.status-bar.is-visible { + transform: translateY(0); + opacity: 1; +} + +.status-bar.is-error { + color: #fff; + background: rgba(72, 14, 14, 0.98); + border-bottom-color: rgba(255, 255, 255, 0.12); } .keypad-grid, diff --git a/samples/calc-02/index.html b/samples/calc-02/index.html index 52745ca..bc724aa 100644 --- a/samples/calc-02/index.html +++ b/samples/calc-02/index.html @@ -10,6 +10,7 @@
+
T:
diff --git a/samples/calc-02/index.js b/samples/calc-02/index.js index 53d168b..8cfab34 100644 --- a/samples/calc-02/index.js +++ b/samples/calc-02/index.js @@ -20,6 +20,7 @@ const keypadGrid = document.getElementById('keypadGrid'); const functionsGrid = document.getElementById('functionsGrid'); const trigoGrid = document.getElementById('trigoGrid'); const calculatorEl = document.querySelector('.calculator'); +const statusLine = document.getElementById('statusLine'); const keypadKeys = [ { label: '±', action: 'neg', className: 'key-default' }, @@ -75,8 +76,20 @@ function focusInput() { hiddenInput.focus(); } -function setStatus(message) { - console.log(message); +let statusTimer = null; + +function setStatus(message, isError = false, timeoutMs = 1400) { + if (!statusLine) return; + clearTimeout(statusTimer); + statusLine.textContent = message; + statusLine.classList.toggle('is-error', isError); + statusLine.classList.toggle('is-visible', Boolean(message)); + if (!message || timeoutMs <= 0) return; + statusTimer = window.setTimeout(() => { + statusLine.textContent = ''; + statusLine.classList.remove('is-visible'); + statusLine.classList.remove('is-error'); + }, timeoutMs); } function normalizeStack() { @@ -191,7 +204,7 @@ function execute(name) { } render(); } catch (error) { - console.error(error); + setStatus(error?.message || 'Operation error', true); } } @@ -311,7 +324,7 @@ pasteButton.addEventListener('click', async () => { const text = await navigator.clipboard.readText(); pasteTextIntoStack(text); } catch (error) { - setStatus('Paste unavailable'); + setStatus('Paste unavailable', true); } }); @@ -356,6 +369,7 @@ function openConstMenu() { pushEditingValueIfNeeded(); calc.push(constant.value); render(); + setStatus(`Inserted ${constant.label}`); closeConstMenu(); focusInput(); });