feat: add no-icon support with none/blank

Use `none` or `blank` as the icon name to render a callout without an icon.
Icons ending with `-none` also work. The icon space is not reserved.

Closes #4

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@gapmiss 2026-05-30 17:30:34 -05:00
parent cf52f94f29
commit 224a035795
3 changed files with 43 additions and 19 deletions

View file

@ -94,11 +94,11 @@ A plugin for displaying inline "callouts" in [Obsidian.md](https://github.com/ob
`[!!ICON|LABEL|COLOR]`
```
| Syntax | Details |
| ----------------- | ---------------------------------------- |
| `ICON` | Name of the Lucide icon |
| `LABEL`(optional) | Callout label/title text |
| `COLOR`(optional) | Hex, RGB values, or Obsidian CSS var |
| Syntax | Details |
| ----------------- | -------------------------------------------------- |
| `ICON` | Lucide icon name, or `none`/`blank` for no icon |
| `LABEL`(optional) | Callout label/title text |
| `COLOR`(optional) | Hex, RGB values, or Obsidian CSS var |
> [!IMPORTANT]

View file

@ -36,6 +36,10 @@ function parseColorToRgb(color: string): string | null {
return trimmed;
}
function isNoIcon(icon: string): boolean {
return icon === 'none' || icon === 'blank' || icon.endsWith('-none');
}
export class InlineCallout {
newEl: HTMLSpanElement;
@ -66,11 +70,12 @@ export class InlineCallout {
let calloutColorStyle: string;
// no content, return <code>
const noIcon = calloutIcon ? isNoIcon(calloutIcon) : false;
if (
!content.length
|| parts.length === 0
|| !calloutIcon
|| (getIconIds().indexOf('lucide-' + calloutIcon) == -1 && getIconIds().indexOf(calloutIcon) == -1) // 404, no icon found
|| (!noIcon && getIconIds().indexOf('lucide-' + calloutIcon) == -1 && getIconIds().indexOf(calloutIcon) == -1) // 404, no icon found
) {
const codeEl = createEl("code");
codeEl.setText(text);
@ -85,29 +90,35 @@ export class InlineCallout {
// icon only
if (parts.length === 1) {
this.iconEl.setAttr("aria-label", calloutIcon);
setIcon(this.iconEl, calloutIcon);
this.newEl.appendChild(this.iconEl);
if (!noIcon) {
this.iconEl.setAttr("aria-label", calloutIcon);
setIcon(this.iconEl, calloutIcon);
this.newEl.appendChild(this.iconEl);
}
return this.newEl;
}
// icon and color only
if (!calloutLabel && calloutColor) {
const rgb = parseColorToRgb(calloutColor);
if (rgb) {
calloutColorStyle = "color: rgba(" + rgb + ", 1);"
this.iconEl.setAttr("style", calloutColorStyle);
if (!noIcon) {
const rgb = parseColorToRgb(calloutColor);
if (rgb) {
calloutColorStyle = "color: rgba(" + rgb + ", 1);"
this.iconEl.setAttr("style", calloutColorStyle);
}
this.iconEl.setAttr("aria-label", calloutIcon);
setIcon(this.iconEl, calloutIcon);
this.newEl.appendChild(this.iconEl);
}
this.iconEl.setAttr("aria-label", calloutIcon);
setIcon(this.iconEl, calloutIcon);
this.newEl.appendChild(this.iconEl);
return this.newEl;
}
// icon
this.iconEl.setAttr("aria-label", calloutIcon);
setIcon(this.iconEl, calloutIcon);
this.newEl.appendChild(this.iconEl);
if (!noIcon) {
this.iconEl.setAttr("aria-label", calloutIcon);
setIcon(this.iconEl, calloutIcon);
this.newEl.appendChild(this.iconEl);
}
// label?
if (calloutLabel) {
this.labelEl.setText(calloutLabel);

View file

@ -58,6 +58,19 @@ body {
width: calc(var(--dialog-width) / 1.5);
}
/* No-icon callouts: hide icon and adjust label spacing */
[data-inline-callout="none"] .inline-callout-icon,
[data-inline-callout="blank"] .inline-callout-icon,
[data-inline-callout$="-none"] .inline-callout-icon {
display: none;
}
[data-inline-callout="none"] .inline-callout-label,
[data-inline-callout="blank"] .inline-callout-label,
[data-inline-callout$="-none"] .inline-callout-label {
margin-left: var(--inline-callout-label-margin-right);
}
/* @settings
name: Inline Callouts
id: inline-callouts