From 24a99ba07ac2df62ffcc6dc0fa2328a44956b24a Mon Sep 17 00:00:00 2001 From: adlee-was-taken Date: Thu, 23 Apr 2026 21:55:36 -0400 Subject: [PATCH] feat(ext/popup): field-row + concealed-row + signature-block helpers --- .../popup/components/__tests__/fields.test.ts | 117 +++++++++++++++++ extension/src/popup/components/fields.ts | 119 ++++++++++++++++++ extension/src/popup/styles.css | 49 ++++++++ 3 files changed, 285 insertions(+) create mode 100644 extension/src/popup/components/__tests__/fields.test.ts create mode 100644 extension/src/popup/components/fields.ts diff --git a/extension/src/popup/components/__tests__/fields.test.ts b/extension/src/popup/components/__tests__/fields.test.ts new file mode 100644 index 0000000..2647ace --- /dev/null +++ b/extension/src/popup/components/__tests__/fields.test.ts @@ -0,0 +1,117 @@ +import { describe, expect, it, vi } from 'vitest'; +import { + renderRow, + renderConcealedRow, + renderSignatureBlock, + wireFieldHandlers, +} from '../fields'; + +describe('renderRow', () => { + it('plain row contains label + value', () => { + const html = renderRow({ label: 'username', value: 'alice' }); + expect(html).toContain('username'); + expect(html).toContain('alice'); + expect(html).toContain('field-row'); + }); + + it('copyable row exposes a copy action', () => { + const html = renderRow({ label: 'email', value: 'alice@example.com', copyable: true }); + expect(html).toContain('data-field-action="copy"'); + }); + + it('href row wraps value in an external anchor', () => { + const html = renderRow({ label: 'url', value: 'https://example.com', href: 'https://example.com' }); + expect(html).toContain('href="https://example.com"'); + expect(html).toContain('target="_blank"'); + expect(html).toContain('rel="noopener noreferrer"'); + }); + + it('monospace flag toggles the monospace class', () => { + const html = renderRow({ label: 'fingerprint', value: 'AB:CD', monospace: true }); + expect(html).toContain('monospace'); + }); + + it('multiline value renders inside a
', () => {
+    const html = renderRow({ label: 'address', value: '1 Main\n2 Main', multiline: true });
+    expect(html).toContain(' {
+    const html = renderRow({ label: '', value: '"&<>' });
+    expect(html).not.toContain('