feat(ext/vault): bottom sheet type picker for new item
This commit is contained in:
@@ -26,6 +26,20 @@ import { renderBackupPanel, teardown as teardownBackup } from './components/back
|
|||||||
import { renderImportPanel, teardown as teardownImport } from './components/import-panel';
|
import { renderImportPanel, teardown as teardownImport } from './components/import-panel';
|
||||||
import { applyColorScheme } from '../shared/color-scheme';
|
import { applyColorScheme } from '../shared/color-scheme';
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Bottom sheet type picker
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const BOTTOM_SHEET_TYPES: Array<{ type: ItemType; label: string }> = [
|
||||||
|
{ type: 'login', label: 'Login' },
|
||||||
|
{ type: 'secure_note', label: 'Secure Note' },
|
||||||
|
{ type: 'totp', label: 'TOTP' },
|
||||||
|
{ type: 'card', label: 'Card' },
|
||||||
|
{ type: 'identity', label: 'Identity' },
|
||||||
|
{ type: 'key', label: 'SSH / API Key' },
|
||||||
|
{ type: 'document', label: 'Document' },
|
||||||
|
];
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Helpers
|
// Helpers
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -308,11 +322,52 @@ function renderShell(app: HTMLElement): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Bottom sheet (stub — wired in Task 11)
|
// Bottom sheet (wired in Task 11)
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function wireBottomSheet(): void {
|
function wireBottomSheet(): void {
|
||||||
// wired in Task 11
|
document.getElementById('vault-sheet-scrim')?.addEventListener('click', closeBottomSheet);
|
||||||
|
document.addEventListener('keydown', (e) => {
|
||||||
|
if (e.key === 'Escape' && state.bottomSheetOpen) closeBottomSheet();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function openBottomSheet(): void {
|
||||||
|
const sheet = document.getElementById('vault-bottom-sheet');
|
||||||
|
const scrim = document.getElementById('vault-sheet-scrim');
|
||||||
|
if (!sheet || !scrim) return;
|
||||||
|
|
||||||
|
sheet.innerHTML = `
|
||||||
|
<div class="vault-bottom-sheet__handle"></div>
|
||||||
|
<div class="vault-bottom-sheet__title">New item — choose type</div>
|
||||||
|
<div class="vault-type-grid">
|
||||||
|
${BOTTOM_SHEET_TYPES.map((t) => `
|
||||||
|
<button class="vault-type-card" data-type="${t.type}">
|
||||||
|
<span class="vault-type-card__icon" aria-hidden="true">${typeIcon(t.type)}</span>
|
||||||
|
<span class="vault-type-card__name">${escapeHtml(t.label)}</span>
|
||||||
|
</button>
|
||||||
|
`).join('')}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
sheet.classList.add('vault-bottom-sheet--open');
|
||||||
|
scrim.classList.add('vault-bottom-sheet-scrim--visible');
|
||||||
|
state.bottomSheetOpen = true;
|
||||||
|
|
||||||
|
sheet.querySelectorAll<HTMLButtonElement>('[data-type]').forEach((btn) => {
|
||||||
|
btn.addEventListener('click', () => {
|
||||||
|
const type = btn.dataset.type as ItemType;
|
||||||
|
closeBottomSheet();
|
||||||
|
setHash('add', type);
|
||||||
|
renderPane();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeBottomSheet(): void {
|
||||||
|
document.getElementById('vault-bottom-sheet')?.classList.remove('vault-bottom-sheet--open');
|
||||||
|
document.getElementById('vault-sheet-scrim')?.classList.remove('vault-bottom-sheet-scrim--visible');
|
||||||
|
state.bottomSheetOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -471,8 +526,7 @@ function wireSidebar(): void {
|
|||||||
state.selectedId = null;
|
state.selectedId = null;
|
||||||
state.selectedItem = null;
|
state.selectedItem = null;
|
||||||
state.newType = null;
|
state.newType = null;
|
||||||
setHash('add');
|
openBottomSheet();
|
||||||
renderPane();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (nav === 'trash' || nav === 'devices' || nav === 'settings') {
|
if (nav === 'trash' || nav === 'devices' || nav === 'settings') {
|
||||||
|
|||||||
Reference in New Issue
Block a user