Files
obsidian-gui-tasks/src/view/FileSwitcherBar.ts
2026-03-29 09:56:40 -04:00

91 lines
2.8 KiB
TypeScript

import { TFile } from 'obsidian';
export interface FileSwitcherBarOptions {
app: unknown; // kept for interface compatibility, unused after modal removal
currentFile: TFile;
taskFiles: TFile[];
inboxPath: string;
onSwitchFile: (file: TFile) => void;
onCreateFile: (name: string) => void;
}
/**
* Renders a header bar with a file switcher dropdown and an inline
* "New task file" affordance. Returns the container element.
*/
export function buildFileSwitcherBar(opts: FileSwitcherBarOptions): HTMLElement {
const { currentFile, taskFiles, inboxPath, onSwitchFile, onCreateFile } = opts;
const bar = createDiv({ cls: 'yaotp-switcher-bar' });
// Left side: file selector
const selectWrap = bar.createDiv({ cls: 'yaotp-switcher-select-wrap' });
const select = selectWrap.createEl('select', { cls: 'yaotp-switcher-select' });
// Always show Inbox first if it exists in the list
const inbox = taskFiles.find((f) => f.path === inboxPath);
const others = taskFiles.filter((f) => f.path !== inboxPath);
for (const file of (inbox ? [inbox, ...others] : others)) {
const opt = select.createEl('option', { text: file.basename, value: file.path });
if (file.path === currentFile.path) opt.selected = true;
}
select.addEventListener('change', () => {
const chosen = taskFiles.find((f) => f.path === select.value);
if (chosen) onSwitchFile(chosen);
});
// Right side: "+ New list" button / inline create input (mutually exclusive)
const newBtn = bar.createEl('button', {
text: '+ New list',
cls: 'yaotp-switcher-new-btn',
});
const createGroup = bar.createDiv({ cls: 'yaotp-switcher-create-group' });
createGroup.style.display = 'none';
const nameInput = createGroup.createEl('input', {
type: 'text',
cls: 'yaotp-switcher-name-input',
attr: { placeholder: 'File name (without .md)' },
}) as HTMLInputElement;
const confirmBtn = createGroup.createEl('button', {
text: 'Create',
cls: 'mod-cta yaotp-switcher-confirm-btn',
});
const cancelBtn = createGroup.createEl('button', {
text: '✕',
cls: 'yaotp-switcher-cancel-btn',
});
const showInput = () => {
newBtn.style.display = 'none';
createGroup.style.display = 'flex';
nameInput.value = '';
setTimeout(() => nameInput.focus(), 0);
};
const hideInput = () => {
createGroup.style.display = 'none';
newBtn.style.display = '';
};
const submit = () => {
const name = nameInput.value.trim();
if (name) {
hideInput();
onCreateFile(name);
}
};
newBtn.addEventListener('click', showInput);
confirmBtn.addEventListener('click', submit);
cancelBtn.addEventListener('click', hideInput);
nameInput.addEventListener('keydown', (e) => {
if (e.key === 'Enter') submit();
if (e.key === 'Escape') hideInput();
});
return bar;
}