From eb534af888de54b3883cccd5786a001f296a148f Mon Sep 17 00:00:00 2001 From: "smx.pusha" <139338836+smxpusha@users.noreply.github.com> Date: Sun, 16 Aug 2026 12:38:08 +0200 Subject: [PATCH] ENH - refine calculator interface Polish calculator modes, key geometry, operator icon states, and the calculation history navigation. Add focused contract coverage for the updated layout and interaction styling. --- .../views/apps/CalculatorApp.contract.test.ts | 70 ++++++ frontend/src/views/apps/CalculatorApp.vue | 212 ++++++++++++++---- 2 files changed, 234 insertions(+), 48 deletions(-) create mode 100644 frontend/src/views/apps/CalculatorApp.contract.test.ts diff --git a/frontend/src/views/apps/CalculatorApp.contract.test.ts b/frontend/src/views/apps/CalculatorApp.contract.test.ts new file mode 100644 index 0000000..7444d2f --- /dev/null +++ b/frontend/src/views/apps/CalculatorApp.contract.test.ts @@ -0,0 +1,70 @@ +import { readFileSync } from 'node:fs' +import { fileURLToPath } from 'node:url' + +import { describe, expect, it } from 'vitest' + +const source = readFileSync( + fileURLToPath(new URL('./CalculatorApp.vue', import.meta.url)), + 'utf8', +) + +describe('CalculatorApp layout contract', () => { + it('opens in standard mode with circular equal-sized keys', () => { + expect(source).toContain('const scientificOpened = ref(false)') + expect(source).toContain('aspect-ratio: 1;') + expect(source).toContain('border-radius: 50%;') + }) + + it('keeps the compact advanced keys fully rounded', () => { + expect(source).toMatch( + /\.calculator-key--scientific\s*{[^}]*border-radius: 999px;/s, + ) + expect(source).toMatch( + /\.calculator-key--basic\s*{[^}]*border-radius: 999px;/s, + ) + }) + + it('keeps selected orange operator keys orange instead of white', () => { + expect(source).toMatch( + /\.calculator-key--operator\.calculator-key--selected\s*{[^}]*background: linear-gradient\(180deg, #e98700, #c96800\);[^}]*color: #fff;/s, + ) + }) + + it('renders centered icons for every orange operator key', () => { + for (const icon of ['Divide', 'X', 'Minus', 'Plus', 'Equal']) { + expect(source).toContain(`icon: ${icon}`) + } + expect(source).toContain('class="calculator-key__operator-icon"') + expect(source).toContain(':aria-label="key.icon ? key.label : undefined"') + expect(source).toMatch( + /\.calculator-key__operator-icon\s*{[^}]*width: 24px;[^}]*height: 24px;[^}]*display: block;[^}]*margin: 0;/s, + ) + }) + + it('uses the shared navigation controls in calculation history', () => { + expect(source).toContain('SkyButton, SkyNavbar, SkySheet') + expect(source).toContain( + 'calculator-history sky-ui-provider sky-ui-provider--dark', + ) + expect(source).toContain('class="calculator-history__navbar"') + expect(source).toContain( + 'grid-template-columns: 106px minmax(0, 1fr) 44px;', + ) + expect(source).toContain('calculator-history__nav-button--edit') + expect(source).toContain('calculator-history__nav-button--close') + expect(source).toContain('background: rgb(255 255 255 / 9%);') + expect(source).toContain('-webkit-backdrop-filter: none;') + expect(source).toContain('backdrop-filter: none;') + expect(source).toContain('min-width: 106px;') + expect(source).toContain('class="calculator-history__edit-label"') + expect(source).toContain('position: absolute;') + expect(source).toContain('inset: 0;') + expect(source).toContain('place-items: center;') + expect(source).toContain('padding: 0;') + expect(source).toMatch( + /\.calculator-history__nav-button:hover:not\(:disabled\)[^}]*background: rgb\(255 255 255 \/ 15%\);[^}]*transform: none;[^}]*filter: none;/s, + ) + expect(source).not.toContain('class="calculator-history__edit"') + expect(source).not.toContain('class="calculator-history__close"') + }) +}) diff --git a/frontend/src/views/apps/CalculatorApp.vue b/frontend/src/views/apps/CalculatorApp.vue index 143600f..23c6139 100644 --- a/frontend/src/views/apps/CalculatorApp.vue +++ b/frontend/src/views/apps/CalculatorApp.vue @@ -1,13 +1,23 @@