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
19 changes: 19 additions & 0 deletions docs/src/content/docs/docs/ControllingPrompts.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,25 @@ Rather than answering prompts one at a time, QuickAdd can collect everything in

The full behavior - what is collected, date parsing, defaults, and script-declared inputs - is documented in [One-page Inputs](/docs/Advanced/onePageInputs/).

## Style pickers with CSS {#style-pickers-with-css}

QuickAdd's pickers are standard Obsidian pickers, so they open near the top of the window like the command palette, while text prompts open in the middle. To change that, target these classes from a [CSS snippet](https://obsidian.md/help/snippets):

| Class | Picker |
| --- | --- |
| `qa-choice-suggester` | The QuickAdd launcher and Multi choices |
| `qa-suggester` | Single-value pick lists such as `{{VALUE:a,b,c}}`, the note picker for Template choices that look for existing notes, and `quickAddApi.suggester` in scripts |

For example, this centers QuickAdd's pickers on desktop and leaves the command palette and other plugins alone:

```css
body:not(.is-mobile) .prompt:is(.qa-choice-suggester, .qa-suggester) {
top: auto;
}
```
Comment thread
coderabbitai[bot] marked this conversation as resolved.

A centered picker re-centers as you type, so the search box moves a little when the list gets shorter.

## For script authors {#for-script-authors}

User scripts can declare their inputs so they appear in the one-page form (`quickadd.inputs`), and can open a one-page form of their own at runtime with [`quickAddApi.requestInputs`](/docs/QuickAddAPI/). Both are covered in [One-page Inputs](/docs/Advanced/onePageInputs/#user-scripts-declare-inputs-optional).
9 changes: 9 additions & 0 deletions src/gui/GenericSuggester/SuggesterModal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ export class SuggesterModal<T> extends FuzzySuggestModal<T> {
}
}

/**
* `qa-suggester` is a stable hook for user CSS snippets; core styles every
* picker as `.prompt`, so without it a snippet can't tell QuickAdd's apart.
*/
onOpen(): void {
super.onOpen();
this.modalEl.addClass("qa-suggester");
}

getItemText(item: T): string {
const index = this.items.indexOf(item);
const displayItem = index >= 0 ? this.displayItems[index] : undefined;
Expand Down
6 changes: 6 additions & 0 deletions src/gui/TemplateNoteDiscoveryModal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ export class TemplateNoteDiscoveryModal extends FuzzySuggestModal<DiscoveryRow>
this.open();
}

/** `qa-suggester` is a stable hook for user CSS snippets (see SuggesterModal). */
onOpen(): void {
super.onOpen();
this.modalEl.addClass("qa-suggester");
}

getItems(): DiscoveryRow[] { return this.rows; }

getItemText(row: DiscoveryRow): string {
Expand Down
6 changes: 6 additions & 0 deletions src/gui/suggesters/choiceSuggester.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,12 @@ export default class ChoiceSuggester extends FuzzySuggestModal<IChoice> {
}
}

/** `qa-choice-suggester` is a stable hook for user CSS snippets (see SuggesterModal). */
onOpen(): void {
super.onOpen();
this.modalEl.addClass("qa-choice-suggester");
}

onClose(): void {
super.onClose();
this.markdownComponent.unload();
Expand Down
44 changes: 44 additions & 0 deletions tests/e2e/suggester-classes.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { it } from "vitest";
import { MultiChoice } from "../../src/types/choices/MultiChoice";
import { TemplateChoice } from "../../src/types/choices/TemplateChoice";
import type IChoice from "../../src/types/choices/IChoice";
import { createQuickAddE2EHarness, seedVaultFile } from "./e2eVault";
import { pressKey, waitForElement } from "./uiHelpers";

const getContext = createQuickAddE2EHarness("suggester-classes");

// Users target these classes from CSS snippets (docs: ControllingPrompts
// "Style pickers with CSS"), so renaming one breaks their themes.
it("marks QuickAdd's pickers with the documented CSS classes", async () => {
const { obsidian, plugin, sandbox } = getContext();
const folder = new MultiChoice("Styled folder").addChoice(new TemplateChoice("Styled template"));
const discovery = new TemplateChoice("Styled discovery");
discovery.discoverExistingNotesBeforeCreate = true;
discovery.templatePath = await seedVaultFile(obsidian, sandbox, "Styled discovery template.md");
discovery.fileNameFormat = { enabled: true, format: "{{VALUE}}" };
await plugin.data<{ choices: IChoice[] }>().patch((data) => {
data.choices = [folder, discovery];
});
await plugin.reload({ waitUntilReady: true });

await obsidian.dev.evalJson(`(() => {
void app.plugins.plugins.quickadd.api.executeChoice(${JSON.stringify(folder.name)}).catch(() => {});
return true;
})()`);
await waitForElement(obsidian, ".prompt.qa-choice-suggester .suggestion-item");
await pressKey(obsidian, "Escape");

await obsidian.dev.evalJson(`(() => {
void app.plugins.plugins.quickadd.api.suggester(["low", "high"], ["low", "high"]).catch(() => {});
return true;
})()`);
await waitForElement(obsidian, ".prompt.qa-suggester .suggestion-item");
await pressKey(obsidian, "Escape");

await obsidian.dev.evalJson(`(() => {
void app.plugins.plugins.quickadd.api.executeChoice(${JSON.stringify(discovery.name)}).catch(() => {});
return true;
})()`);
await waitForElement(obsidian, '.prompt.qa-suggester input[placeholder^="Search notes or create"]');
await pressKey(obsidian, "Escape");
});
Loading