Slash Command

Typing / to insert blocks or trigger actions.

Typing /head

html

<div class="scd" data-selected="heading" style="--accent:#F5C2E0;">
  <p class="scd__line">Typing <span class="scd__slash">/head</span></p>
  <ul class="scd__menu" role="listbox" aria-label="Insert block" style="border-radius:10px;">
    <li class="scd__item scd__item--heading" role="option"><span class="scd__name">Heading</span><span class="scd__desc">Big section title</span></li>
    <li class="scd__item scd__item--image" role="option"><span class="scd__name">Image</span><span class="scd__desc">Upload or embed a picture</span></li>
    <li class="scd__item scd__item--table" role="option"><span class="scd__name">Table</span><span class="scd__desc">Rows and columns of data</span></li>
    <li class="scd__item scd__item--divider" role="option"><span class="scd__name">Divider</span><span class="scd__desc">A horizontal rule</span></li>
  </ul>
</div>
<style>
.scd { font-family: system-ui, sans-serif; color: #241430; background: #FAF7F2; padding: 20px; max-width: 300px; }
.scd__line { margin: 0 0 8px; }
.scd__slash { font-family: ui-monospace, monospace; background: #24143010; padding: 2px 6px; border-radius: 4px; }
.scd__menu { list-style: none; margin: 0; padding: 6px; background: #fff; box-shadow: 0 10px 24px rgba(36,20,48,.16); }
.scd__item { display: flex; align-items: baseline; gap: 8px; padding: 8px 10px; border-radius: 6px; }
.scd__name { font-weight: 600; font-size: 14px; }
.scd__desc { font-size: 12px; color: #241430aa; }
[data-selected="heading"] .scd__item--heading,
[data-selected="image"] .scd__item--image,
[data-selected="table"] .scd__item--table,
[data-selected="divider"] .scd__item--divider { background: var(--accent); }
</style>

tailwind

<div class="max-w-[300px] bg-[#FAF7F2] text-[#241430] font-sans p-5 scd-tw" data-selected="heading" style="--accent:#F5C2E0;">
  <p class="m-0 mb-2">Typing <span class="font-mono bg-[#24143010] px-1.5 py-0.5 rounded">/head</span></p>
  <ul class="list-none m-0 p-1.5 bg-white shadow-lg" role="listbox" aria-label="Insert block" style="border-radius:10px;">
    <li class="scd-tw__item scd-tw__item--heading flex items-baseline gap-2 px-2.5 py-2 rounded-md" role="option"><span class="font-semibold text-sm">Heading</span><span class="text-xs text-[#241430]/65">Big section title</span></li>
    <li class="scd-tw__item scd-tw__item--image flex items-baseline gap-2 px-2.5 py-2 rounded-md" role="option"><span class="font-semibold text-sm">Image</span><span class="text-xs text-[#241430]/65">Upload or embed a picture</span></li>
    <li class="scd-tw__item scd-tw__item--table flex items-baseline gap-2 px-2.5 py-2 rounded-md" role="option"><span class="font-semibold text-sm">Table</span><span class="text-xs text-[#241430]/65">Rows and columns of data</span></li>
    <li class="scd-tw__item scd-tw__item--divider flex items-baseline gap-2 px-2.5 py-2 rounded-md" role="option"><span class="font-semibold text-sm">Divider</span><span class="text-xs text-[#241430]/65">A horizontal rule</span></li>
  </ul>
</div>
<style>
[data-selected="heading"] .scd-tw__item--heading,
[data-selected="image"] .scd-tw__item--image,
[data-selected="table"] .scd-tw__item--table,
[data-selected="divider"] .scd-tw__item--divider { background: #F5C2E0; }
</style>

react

export function SlashCommand({
  commandQuery = "head",
  selectedOption = "heading",
  accent = "#F5C2E0",
  showDescriptions = true,
  radius = 10,
}) {
  const items = [
    { key: "heading", name: "Heading", desc: "Big section title" },
    { key: "image", name: "Image", desc: "Upload or embed a picture" },
    { key: "table", name: "Table", desc: "Rows and columns of data" },
    { key: "divider", name: "Divider", desc: "A horizontal rule" },
  ];
  return (
    <div style={{ fontFamily: "system-ui, sans-serif", color: "#241430", background: "#FAF7F2", padding: 20, maxWidth: 300 }}>
      <p style={{ margin: "0 0 8px" }}>Typing <span style={{ fontFamily: "ui-monospace, monospace", background: "#24143010", padding: "2px 6px", borderRadius: 4 }}>/{commandQuery}</span></p>
      <ul role="listbox" aria-label="Insert block" style={{ listStyle: "none", margin: 0, padding: 6, background: "#fff", boxShadow: "0 10px 24px rgba(36,20,48,.16)", borderRadius: radius }}>
        {items.map((item) => (
          <li key={item.key} role="option" style={{ display: "flex", alignItems: "baseline", gap: 8, padding: "8px 10px", borderRadius: 6,
            background: item.key === selectedOption ? accent : "transparent" }}>
            <span style={{ fontWeight: 600, fontSize: 14 }}>{item.name}</span>
            {showDescriptions && <span style={{ fontSize: 12, color: "#241430aa" }}>{item.desc}</span>}
          </li>
        ))}
      </ul>
    </div>
  );
}