Heading Selector

Control choosing heading levels.

H1 H2 H3 P

Plan for the autumn launch

html

<div class="headsel" data-level="h2" style="--accent:#D9C8F0;">
  <div class="headsel__control" role="group" aria-label="Heading level" style="border-radius:6px;">
    <span class="headsel__opt" data-value="h1">H1</span>
    <span class="headsel__opt" data-value="h2">H2</span>
    <span class="headsel__opt" data-value="h3">H3</span>
    <span class="headsel__opt" data-value="paragraph">P</span>
  </div>
  <div class="headsel__preview">
    <p class="headsel__text headsel__text--h2 ">Plan for the autumn launch</p>
  </div>
</div>
<style>
.headsel { font: 14px system-ui, sans-serif; color: #241430; max-width: 340px; }
.headsel__control { display: inline-flex; gap: 2px; padding: 3px; background: #24143010; margin-bottom: 12px; }
.headsel__opt { width: 30px; height: 26px; display: inline-flex; align-items: center; justify-content: center; border-radius: 6px; font-weight: 600; font-size: 12px; color: #24143099; }
.headsel[data-level="h1"] .headsel__opt[data-value="h1"],
.headsel[data-level="h2"] .headsel__opt[data-value="h2"],
.headsel[data-level="h3"] .headsel__opt[data-value="h3"],
.headsel[data-level="paragraph"] .headsel__opt[data-value="paragraph"] { background: var(--accent); color: #241430; }
.headsel__preview { background: #FAF7F2; border: 1.5px solid #24143022; padding: 18px; }
.headsel__text { margin: 0; font-weight: 600; }
.headsel__text--h1 { font-size: 30px; }
.headsel__text--h2 { font-size: 22px; }
.headsel__text--h3 { font-size: 17px; }
.headsel__text--paragraph { font-size: 15px; font-weight: 400; }
.headsel__text--underline { text-decoration: underline; text-decoration-color: var(--accent); text-decoration-thickness: 3px; text-underline-offset: 5px; }
</style>

tailwind

<div data-level="h2" style="--accent:#D9C8F0;" class="headsel-tw font-sans text-sm text-[#241430] max-w-[340px]">
  <div role="group" aria-label="Heading level" style="border-radius:6px;" class="inline-flex gap-0.5 p-1 bg-[#24143010] mb-3">
    <span class="headsel-tw__opt w-[30px] h-[26px] inline-flex items-center justify-center rounded-md font-semibold text-xs text-[#241430]/60" data-value="h1">H1</span>
    <span class="headsel-tw__opt w-[30px] h-[26px] inline-flex items-center justify-center rounded-md font-semibold text-xs text-[#241430]/60" data-value="h2">H2</span>
    <span class="headsel-tw__opt w-[30px] h-[26px] inline-flex items-center justify-center rounded-md font-semibold text-xs text-[#241430]/60" data-value="h3">H3</span>
    <span class="headsel-tw__opt w-[30px] h-[26px] inline-flex items-center justify-center rounded-md font-semibold text-xs text-[#241430]/60" data-value="paragraph">P</span>
  </div>
  <div class="bg-[#FAF7F2] border-[1.5px] border-[#24143022] p-[18px]">
    <p class="headsel-tw__text headsel-tw__text--h2  m-0 font-semibold">Plan for the autumn launch</p>
  </div>
</div>
<style>
.headsel-tw[data-level="h1"] .headsel-tw__opt[data-value="h1"],
.headsel-tw[data-level="h2"] .headsel-tw__opt[data-value="h2"],
.headsel-tw[data-level="h3"] .headsel-tw__opt[data-value="h3"],
.headsel-tw[data-level="paragraph"] .headsel-tw__opt[data-value="paragraph"] { background: var(--accent); color: #241430; }
.headsel-tw__text--h1 { font-size: 30px; }
.headsel-tw__text--h2 { font-size: 22px; }
.headsel-tw__text--h3 { font-size: 17px; }
.headsel-tw__text--paragraph { font-size: 15px; font-weight: 400; }
.headsel-tw__text--underline { text-decoration: underline; text-decoration-color: var(--accent); text-decoration-thickness: 3px; text-underline-offset: 5px; }
</style>

react

export function HeadingSelector({
  text = "Plan for the autumn launch",
  level = "h2",
  accent = "#D9C8F0",
  underline = false,
  radius = 6,
}) {
  const levels = ["h1", "h2", "h3", "paragraph"];
  const sizeFor = {
    h1: { fontSize: 30, fontWeight: 600 },
    h2: { fontSize: 22, fontWeight: 600 },
    h3: { fontSize: 17, fontWeight: 600 },
    paragraph: { fontSize: 15, fontWeight: 400 },
  }[level];
  return (
    <div style={{ fontFamily: "system-ui, sans-serif", fontSize: 14, color: "#241430", maxWidth: 340 }}>
      <div role="group" aria-label="Heading level" style={{ display: "inline-flex", gap: 2, padding: 3,
        background: "#24143010", marginBottom: 12, borderRadius: radius }}>
        {levels.map((lv) => (
          <span key={lv} style={{ width: 30, height: 26, display: "inline-flex", alignItems: "center", justifyContent: "center",
            borderRadius: 6, fontWeight: 600, fontSize: 12,
            color: lv === level ? "#241430" : "#24143099", background: lv === level ? accent : "transparent" }}>
            {lv === "paragraph" ? "P" : lv.toUpperCase()}
          </span>
        ))}
      </div>
      <div style={{ background: "#FAF7F2", border: "1.5px solid #24143022", padding: 18 }}>
        <p style={{ margin: 0, ...sizeFor,
          textDecoration: underline ? "underline" : "none",
          textDecorationColor: accent, textDecorationThickness: 3, textUnderlineOffset: 5 }}>{text}</p>
      </div>
    </div>
  );
}