Formatting Toolbar

Controls for applying text formatting.

html

<div role="toolbar" aria-label="Text formatting" class="toolbar toolbar--comfortable" style="--accent:#A8E6C1;border-radius:8px;">
  <button type="button" class="toolbar__btn" aria-pressed="true" aria-label="Bold">
    <svg viewBox="0 0 20 20" width="15" height="15" aria-hidden="true"><path d="M6 4h5.2a3.3 3.3 0 010 6.6H6zM6 10.6h5.8a3.4 3.4 0 010 6.8H6z" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"/></svg>
  </button>
  <button type="button" class="toolbar__btn" aria-pressed="false" aria-label="Italic">
    <svg viewBox="0 0 20 20" width="15" height="15" aria-hidden="true"><path d="M8 4h6M6 16h6M11.5 4L8.5 16" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>
  </button>
  <span class="toolbar__divider" aria-hidden="true"></span>
  <button type="button" class="toolbar__btn" aria-label="Bulleted list">
    <svg viewBox="0 0 20 20" width="15" height="15" aria-hidden="true"><circle cx="3.5" cy="5" r="1.2" fill="currentColor"/><circle cx="3.5" cy="10" r="1.2" fill="currentColor"/><circle cx="3.5" cy="15" r="1.2" fill="currentColor"/><path d="M7 5h10M7 10h10M7 15h10" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>
  </button>
  <button type="button" class="toolbar__btn" aria-label="Insert link">
    <svg viewBox="0 0 20 20" width="15" height="15" aria-hidden="true"><path d="M8.5 11.5l3-3M7 13l-1.5 1.5a2.6 2.6 0 01-3.7-3.7L3.3 9.3M13 7l1.5-1.5a2.6 2.6 0 013.7 3.7L16.7 10.7" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>
  </button>
</div>
<style>
.toolbar { display: inline-flex; align-items: center; gap: 2px; padding: 6px; background: #FAF7F2; border: 1.5px solid #24143022; }
.toolbar__btn { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; border: none; background: none; color: #241430; border-radius: 6px; cursor: pointer; }
.toolbar--compact .toolbar__btn { width: 24px; height: 24px; }
.toolbar__btn:hover { background: #24143012; }
.toolbar__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.toolbar__btn[aria-pressed="true"] { background: var(--accent); color: #241430; }
.toolbar__divider { width: 1px; height: 20px; background: #24143022; margin: 0 4px; }
</style>

tailwind

<div role="toolbar" aria-label="Text formatting" style="--accent:#A8E6C1;border-radius:8px;" class="toolbar-tw toolbar-tw--comfortable inline-flex items-center gap-0.5 p-1.5 bg-[#FAF7F2] border-[1.5px] border-[#24143022]">
  <button type="button" aria-pressed="true" aria-label="Bold" class="toolbar-tw__btn inline-flex items-center justify-center w-[30px] h-[30px] border-0 bg-transparent text-[#241430] rounded-md">
    <svg viewBox="0 0 20 20" width="15" height="15" aria-hidden="true"><path d="M6 4h5.2a3.3 3.3 0 010 6.6H6zM6 10.6h5.8a3.4 3.4 0 010 6.8H6z" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"/></svg>
  </button>
  <button type="button" aria-pressed="false" aria-label="Italic" class="toolbar-tw__btn inline-flex items-center justify-center w-[30px] h-[30px] border-0 bg-transparent text-[#241430] rounded-md">
    <svg viewBox="0 0 20 20" width="15" height="15" aria-hidden="true"><path d="M8 4h6M6 16h6M11.5 4L8.5 16" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>
  </button>
  <span aria-hidden="true" class="w-px h-5 bg-[#24143022] mx-1"></span>
  <button type="button" aria-label="Bulleted list" class="toolbar-tw__btn inline-flex items-center justify-center w-[30px] h-[30px] border-0 bg-transparent text-[#241430] rounded-md">
    <svg viewBox="0 0 20 20" width="15" height="15" aria-hidden="true"><circle cx="3.5" cy="5" r="1.2" fill="currentColor"/><circle cx="3.5" cy="10" r="1.2" fill="currentColor"/><circle cx="3.5" cy="15" r="1.2" fill="currentColor"/><path d="M7 5h10M7 10h10M7 15h10" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>
  </button>
  <button type="button" aria-label="Insert link" class="toolbar-tw__btn inline-flex items-center justify-center w-[30px] h-[30px] border-0 bg-transparent text-[#241430] rounded-md">
    <svg viewBox="0 0 20 20" width="15" height="15" aria-hidden="true"><path d="M8.5 11.5l3-3M7 13l-1.5 1.5a2.6 2.6 0 01-3.7-3.7L3.3 9.3M13 7l1.5-1.5a2.6 2.6 0 013.7 3.7L16.7 10.7" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>
  </button>
</div>
<style>
.toolbar-tw--compact .toolbar-tw__btn { width: 24px; height: 24px; }
.toolbar-tw__btn:hover { background: #24143012; }
.toolbar-tw__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.toolbar-tw__btn[aria-pressed="true"] { background: var(--accent); color: #241430; }
</style>

react

export function FormattingToolbar({
  boldActive = true,
  italicActive = false,
  accent = "#A8E6C1",
  size = "comfortable",
  radius = 8,
}) {
  const compact = size === "compact";
  const btnStyle = (pressed) => ({
    display: "inline-flex", alignItems: "center", justifyContent: "center",
    width: compact ? 24 : 30, height: compact ? 24 : 30, border: "none",
    background: pressed ? accent : "transparent", color: "#241430", borderRadius: 6, cursor: "pointer",
  });
  return (
    <div role="toolbar" aria-label="Text formatting" style={{ display: "inline-flex", alignItems: "center", gap: 2,
      padding: 6, background: "#FAF7F2", border: "1.5px solid #24143022", borderRadius: radius }}>
      <button type="button" aria-pressed={boldActive} aria-label="Bold" style={btnStyle(boldActive)}>
        <svg viewBox="0 0 20 20" width="15" height="15" aria-hidden="true"><path d="M6 4h5.2a3.3 3.3 0 010 6.6H6zM6 10.6h5.8a3.4 3.4 0 010 6.8H6z" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinejoin="round" /></svg>
      </button>
      <button type="button" aria-pressed={italicActive} aria-label="Italic" style={btnStyle(italicActive)}>
        <svg viewBox="0 0 20 20" width="15" height="15" aria-hidden="true"><path d="M8 4h6M6 16h6M11.5 4L8.5 16" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" /></svg>
      </button>
      <span aria-hidden="true" style={{ width: 1, height: 20, background: "#24143022", margin: "0 4px" }} />
      <button type="button" aria-label="Bulleted list" style={btnStyle(false)}>
        <svg viewBox="0 0 20 20" width="15" height="15" aria-hidden="true"><circle cx="3.5" cy="5" r="1.2" fill="currentColor" /><circle cx="3.5" cy="10" r="1.2" fill="currentColor" /><circle cx="3.5" cy="15" r="1.2" fill="currentColor" /><path d="M7 5h10M7 10h10M7 15h10" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" /></svg>
      </button>
      <button type="button" aria-label="Insert link" style={btnStyle(false)}>
        <svg viewBox="0 0 20 20" width="15" height="15" aria-hidden="true"><path d="M8.5 11.5l3-3M7 13l-1.5 1.5a2.6 2.6 0 01-3.7-3.7L3.3 9.3M13 7l1.5-1.5a2.6 2.6 0 013.7 3.7L16.7 10.7" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" /></svg>
      </button>
    </div>
  );
}