From e6eb698c4c743dd1a3081a2dbea30eee1beaa64d Mon Sep 17 00:00:00 2001 From: adlee-was-taken Date: Fri, 1 May 2026 22:23:56 -0400 Subject: [PATCH] ext(affordances): wireNotesMonoToggle with chrome.storage.local persistence --- extension/src/popup/styles.css | 8 ++++ .../__tests__/notes-tools.test.ts | 38 +++++++++++++++++++ .../shared/form-affordances/notes-tools.ts | 23 +++++++++++ extension/src/vault/vault.css | 8 ++++ 4 files changed, 77 insertions(+) create mode 100644 extension/src/shared/form-affordances/__tests__/notes-tools.test.ts create mode 100644 extension/src/shared/form-affordances/notes-tools.ts diff --git a/extension/src/popup/styles.css b/extension/src/popup/styles.css index c0afa53..161e809 100644 --- a/extension/src/popup/styles.css +++ b/extension/src/popup/styles.css @@ -1449,3 +1449,11 @@ textarea { font-size: 11px; color: var(--danger, #c75a4f); } +.notes-with-toggle { + display: flex; + align-items: center; + gap: 8px; +} +.f-notes--mono { + font-family: ui-monospace, "JetBrains Mono", "SF Mono", monospace !important; +} diff --git a/extension/src/shared/form-affordances/__tests__/notes-tools.test.ts b/extension/src/shared/form-affordances/__tests__/notes-tools.test.ts new file mode 100644 index 0000000..af4a9ef --- /dev/null +++ b/extension/src/shared/form-affordances/__tests__/notes-tools.test.ts @@ -0,0 +1,38 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { wireNotesMonoToggle } from '../notes-tools'; + +describe('wireNotesMonoToggle', () => { + let form: HTMLElement; + let storage: { get: ReturnType; set: ReturnType }; + + beforeEach(() => { + form = document.createElement('div'); + form.innerHTML = ` + + + `; + document.body.appendChild(form); + storage = { + get: vi.fn().mockImplementation((_keys, cb) => cb({})), + set: vi.fn().mockImplementation((_obj, cb) => cb && cb()), + }; + (globalThis as any).chrome = { storage: { local: storage } }; + }); + + it('toggles class on click and persists', async () => { + await wireNotesMonoToggle(form, { itemId: 'abc123' }); + const btn = form.querySelector('#notes-mono-btn') as HTMLButtonElement; + const ta = form.querySelector('#f-notes') as HTMLTextAreaElement; + expect(ta.classList.contains('f-notes--mono')).toBe(false); + btn.click(); + expect(ta.classList.contains('f-notes--mono')).toBe(true); + expect(storage.set).toHaveBeenCalledWith({ 'notesMono.abc123': true }, expect.any(Function)); + }); + + it('restores prior state on mount', async () => { + storage.get.mockImplementation((_keys, cb) => cb({ 'notesMono.abc123': true })); + await wireNotesMonoToggle(form, { itemId: 'abc123' }); + const ta = form.querySelector('#f-notes') as HTMLTextAreaElement; + expect(ta.classList.contains('f-notes--mono')).toBe(true); + }); +}); diff --git a/extension/src/shared/form-affordances/notes-tools.ts b/extension/src/shared/form-affordances/notes-tools.ts new file mode 100644 index 0000000..548973e --- /dev/null +++ b/extension/src/shared/form-affordances/notes-tools.ts @@ -0,0 +1,23 @@ +export interface NotesMonoOpts { + /// Item ID for persistence — pass empty string for "add new" forms (state + /// is then session-scoped under the key 'notesMono.__new__'). + itemId: string; +} + +export async function wireNotesMonoToggle(form: HTMLElement, opts: NotesMonoOpts): Promise { + const btn = form.querySelector('#notes-mono-btn'); + const ta = form.querySelector('#f-notes'); + if (!btn || !ta) return; + + const key = `notesMono.${opts.itemId || '__new__'}`; + const stored = await new Promise((resolve) => { + chrome.storage.local.get([key], (result) => resolve(!!result[key])); + }); + if (stored) ta.classList.add('f-notes--mono'); + + btn.addEventListener('click', () => { + const next = !ta.classList.contains('f-notes--mono'); + ta.classList.toggle('f-notes--mono', next); + chrome.storage.local.set({ [key]: next }, () => { /* fire and forget */ }); + }); +} diff --git a/extension/src/vault/vault.css b/extension/src/vault/vault.css index a26e72d..f0c1a10 100644 --- a/extension/src/vault/vault.css +++ b/extension/src/vault/vault.css @@ -1479,3 +1479,11 @@ textarea { font-size: 11px; color: var(--danger, #c75a4f); } +.notes-with-toggle { + display: flex; + align-items: center; + gap: 8px; +} +.f-notes--mono { + font-family: ui-monospace, "JetBrains Mono", "SF Mono", monospace !important; +}