Tweaks & fixes

This commit is contained in:
2026-03-29 09:56:40 -04:00
parent 6a2d0cffd6
commit c21d8b1097
11 changed files with 310 additions and 81 deletions

View File

@ -1,7 +1,7 @@
import { App, TFile } from 'obsidian';
import { TFile } from 'obsidian';
export interface FileSwitcherBarOptions {
app: App;
app: unknown; // kept for interface compatibility, unused after modal removal
currentFile: TFile;
taskFiles: TFile[];
inboxPath: string;
@ -10,8 +10,8 @@ export interface FileSwitcherBarOptions {
}
/**
* Renders a header bar with a file switcher dropdown and a "New task file" button.
* Returns the container element to be prepended into the view's root.
* 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;
@ -20,39 +20,70 @@ export function buildFileSwitcherBar(opts: FileSwitcherBarOptions): HTMLElement
// 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);
const ordered = inbox ? [inbox, ...others] : others;
for (const file of ordered) {
const opt = select.createEl('option', {
text: file.basename,
value: file.path,
});
if (file.path === currentFile.path) {
opt.selected = true;
}
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 file button
// Right side: "+ New list" button / inline create input (mutually exclusive)
const newBtn = bar.createEl('button', {
text: '+ New list',
cls: 'yaotp-switcher-new-btn',
});
newBtn.addEventListener('click', () => {
const name = prompt('New task file name (without .md):');
if (name && name.trim()) {
onCreateFile(name.trim());
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;