Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/gui/MacroGUIs/MacroBuilder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,33 @@ describe("MacroBuilder", () => {
done.click();
expect(close).toHaveBeenCalledTimes(1);
});

// The Template and Capture builders' title (ChoiceNameHeader.svelte) shows a
// pencil next to the name; the Macro builder's title must match it.
it("renders the title like ChoiceNameHeader, with a pencil rename icon", () => {
const modal = new MacroBuilder(
new App(),
{ settings: { choices: [] } } as unknown as QuickAdd,
new MacroChoice("Macro under test"),
[],
);

const heading = modal.contentEl.querySelector("h2");
expect(heading?.classList.contains("choiceNameHeader")).toBe(true);

const button = heading?.querySelector("button.qa-rename-title-button");
expect(button?.classList.contains("choiceNameHeaderButton")).toBe(true);
expect(button?.getAttribute("aria-label")).toBe("Rename Macro under test");
expect(
button?.querySelector(".choiceNameHeaderText")?.textContent,
).toBe("Macro under test");

const icon = button?.querySelector(".choiceNameHeaderIcon");
expect(icon?.getAttribute("aria-hidden")).toBe("true");
const svg = icon?.querySelector("svg");
expect(svg?.getAttribute("data-icon")).toBe("pencil");
expect(svg?.getAttribute("width")).toBe("16");
// The icon is decorative: the button's visible text is still just the name.
expect(button?.textContent).toBe("Macro under test");
});
});
21 changes: 16 additions & 5 deletions src/gui/MacroGUIs/MacroBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { IMacro } from "../../types/macros/IMacro";
import type { App } from "obsidian";
import { Modal, Setting } from "obsidian";
import { Modal, Setting, setIcon } from "obsidian";
import GenericInputPrompt from "../GenericInputPrompt/GenericInputPrompt";
import type IChoice from "../../types/choices/IChoice";
import type IMacroChoice from "../../types/choices/IMacroChoice";
Expand Down Expand Up @@ -120,16 +120,27 @@ export class MacroBuilder extends Modal {
}

protected addCenteredHeader(header: string): void {
const headerEl = this.contentEl.createEl("h2");
headerEl.addClass("qa-clickable-modal-title");
// Same markup and classes as ChoiceNameHeader.svelte, the title of the
// Template and Capture builders, so the Macro builder also shows the pencil
// that signals "click to rename".
const headerEl = this.contentEl.createEl("h2", { cls: "choiceNameHeader" });

// Rename affordance is a real <button> (keyboard operable: Enter/Space) inside
// the heading, so the <h2> keeps its heading role for screen readers (#1250).
const renameButton = headerEl.createEl("button", {
cls: "qa-rename-title-button",
text: header,
cls: ["choiceNameHeaderButton", "qa-rename-title-button"],
attr: { type: "button", "aria-label": `Rename ${header}` },
});
renameButton.createSpan({ cls: "choiceNameHeaderText", text: header });
const iconEl = renameButton.createSpan({
cls: "choiceNameHeaderIcon",
attr: { "aria-hidden": "true" },
});
setIcon(iconEl, "pencil");
// ChoiceNameHeader renders the pencil at 16px (ObsidianIcon size={16}).
const iconSvg = iconEl.querySelector("svg");
iconSvg?.setAttribute("width", "16");
iconSvg?.setAttribute("height", "16");

renameButton.addEventListener("click", () => {
void (async () => {
Expand Down
12 changes: 12 additions & 0 deletions src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,18 @@
margin-right: 1em;
}

/* The command editor renders into its own wrapper, so its last row ("Choices")
matches Obsidian's modal `.setting-item:last-child { padding-bottom: 0 }` even
though the Macro builder's own settings follow it. Restore the row padding so
its description doesn't touch the next divider. Scoped to the Macro builder:
in the branch editor the command editor really is last (buttons follow).
Selector specificity must beat Obsidian's (0,5,0) rule. */
.quickAddModal.macroBuilder
.macroBuilder__editor
> .setting-item:not(.setting-item-heading):last-child {
padding-bottom: var(--size-4-4);
}

.qa-hidden {
display: none;
}
Expand Down
Loading