From ad6e4a2cd9e1d6e16668b0a6c481be9d6de07567 Mon Sep 17 00:00:00 2001 From: adlee-was-taken Date: Sun, 3 May 2026 21:08:24 -0400 Subject: [PATCH] feat(ext/popup): polished 2-column type-picker with glyph icons --- extension/src/popup/components/item-form.ts | 48 +++++++++++---------- extension/src/popup/styles.css | 26 +++++++++++ 2 files changed, 52 insertions(+), 22 deletions(-) diff --git a/extension/src/popup/components/item-form.ts b/extension/src/popup/components/item-form.ts index 0460c7c..a2019e7 100644 --- a/extension/src/popup/components/item-form.ts +++ b/extension/src/popup/components/item-form.ts @@ -3,15 +3,19 @@ import { navigate, getState, setState, escapeHtml, popOutToTab, isInTab } from '../../shared/state'; import type { Item, ItemType } from '../../shared/types'; +import { + GLYPH_TYPE_LOGIN, GLYPH_TYPE_SECURE_NOTE, GLYPH_TYPE_TOTP, + GLYPH_TYPE_CARD, GLYPH_TYPE_IDENTITY, GLYPH_TYPE_KEY, GLYPH_TYPE_DOCUMENT, +} from '../../shared/glyphs'; -const TYPE_OPTIONS: Array<{ type: ItemType; icon: string; label: string }> = [ - { type: 'login', icon: '๐Ÿ”‘', label: 'login' }, - { type: 'secure_note', icon: '๐Ÿ“', label: 'secure note' }, - { type: 'identity', icon: '๐Ÿ‘ค', label: 'identity' }, - { type: 'card', icon: '๐Ÿ’ณ', label: 'card' }, - { type: 'key', icon: '๐Ÿ”', label: 'key' }, - { type: 'document', icon: '๐Ÿ“„', label: 'document' }, - { type: 'totp', icon: 'โฑ๏ธ', label: 'totp' }, +const TYPE_OPTIONS: Array<{ type: ItemType; icon: string; label: string; description: string }> = [ + { type: 'login', icon: GLYPH_TYPE_LOGIN, label: 'Login', description: 'Username + password' }, + { type: 'secure_note', icon: GLYPH_TYPE_SECURE_NOTE, label: 'Secure Note', description: 'Encrypted text note' }, + { type: 'identity', icon: GLYPH_TYPE_IDENTITY, label: 'Identity', description: 'Personal details' }, + { type: 'card', icon: GLYPH_TYPE_CARD, label: 'Card', description: 'Credit / debit card' }, + { type: 'key', icon: GLYPH_TYPE_KEY, label: 'SSH / API Key', description: 'Keys and tokens' }, + { type: 'document', icon: GLYPH_TYPE_DOCUMENT, label: 'Document', description: 'File attachment' }, + { type: 'totp', icon: GLYPH_TYPE_TOTP, label: 'TOTP', description: '2FA authenticator' }, ]; import * as login from './types/login'; import * as secureNote from './types/secure-note'; @@ -54,36 +58,36 @@ export function renderItemForm(app: HTMLElement, mode: 'add' | 'edit'): void { function renderTypeSelection(app: HTMLElement): void { app.innerHTML = `
-
- -

new item

+
+ + New item - ${isInTab() ? '' : ''} + ${isInTab() ? '' : ''}
- ${isInTab() ? '
esc to cancel
' : '
'} -
+
${TYPE_OPTIONS.map((opt) => ` - `).join('')}
+
Esc back
`; document.getElementById('back-btn')?.addEventListener('click', () => navigate('list')); document.getElementById('popout-btn')?.addEventListener('click', popOutToTab); + document.addEventListener('keydown', (e) => { + if (e.key === 'Escape') navigate('list'); + }, { once: true }); document.querySelectorAll('[data-type]').forEach((btn) => { btn.addEventListener('click', () => { const type = btn.dataset.type as ItemType; setState({ newType: type }); - if (type === 'login' || type === 'secure_note') { - renderItemForm(app, 'add'); - } else { - popOutToTab(); - } + renderItemForm(app, 'add'); }); }); } diff --git a/extension/src/popup/styles.css b/extension/src/popup/styles.css index f1a73a7..ad64c1c 100644 --- a/extension/src/popup/styles.css +++ b/extension/src/popup/styles.css @@ -1635,3 +1635,29 @@ textarea { font-size: 11px; color: var(--text-muted, #8b949e); } + +.type-card-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 8px; + margin-bottom: 12px; +} + +.type-card { + display: flex; + flex-direction: column; + align-items: flex-start; + padding: 10px 12px; + background: var(--bg-elevated, #161b22); + border: 1px solid var(--border-mid, #30363d); + border-radius: 6px; + cursor: pointer; + text-align: left; + transition: border-color 0.15s; +} + +.type-card:hover { border-color: var(--gold-base, #a88a4a); } + +.type-card__icon { font-size: 20px; margin-bottom: 4px; } +.type-card__label { font-size: 12px; font-weight: 600; } +.type-card__desc { font-size: 10px; color: var(--text-muted, #8b949e); margin-top: 2px; }