Rollback

Return to a previous state/configuration.

Homepage layout config

Currently on v14 (live), published 2 hours ago

html

<div class="rollback" data-target="v13" style="--accent:#D9C8F0;">
  <h3 class="rollback__title">Homepage layout config</h3>
  <p class="rollback__current">Currently on <strong>v14 (live)</strong>, published 2 hours ago</p>
  <ul class="rollback__history">
    <li class="rollback__entry" data-version="v13">v13</li>
    <li class="rollback__entry" data-version="v12">v12</li>
    <li class="rollback__entry" data-version="v11">v11</li>
  </ul>
  <button type="button" class="rollback__action"><svg viewBox="0 0 16 16" width="14" height="14" fill="none" aria-hidden="true"><path d="M3 8a5 5 0 1 0 1.5-3.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><path d="M3 3v3.5h3.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg> Roll back to v13</button>
</div>
<style>
.rollback { font: 15px/1.5 system-ui, sans-serif; max-width: 360px; padding: 20px; background: #FAF7F2; color: #241430; border-radius: 14px; border: 1.5px solid #24143020; }
.rollback__title { margin: 0 0 6px; font-size: 17px; font-weight: 600; }
.rollback__current { margin: 0 0 12px; font-size: 14px; color: #241430cc; }
.rollback__history { list-style: none; display: flex; gap: 8px; margin: 0 0 14px; padding: 0; }
.rollback__entry { font-size: 13px; font-weight: 600; padding: 6px 12px; border-radius: 999px; background: #24143010; color: #24143099; }
.rollback[data-target="v13"] .rollback__entry[data-version="v13"] { background: var(--accent); color: #241430; }
.rollback[data-target="v12"] .rollback__entry[data-version="v12"] { background: var(--accent); color: #241430; }
.rollback[data-target="v11"] .rollback__entry[data-version="v11"] { background: var(--accent); color: #241430; }
.rollback__action { display: inline-flex; align-items: center; gap: 6px; border: 1.5px solid #241430; background: transparent; color: #241430; font: 600 13px system-ui, sans-serif; padding: 8px 14px; border-radius: 8px; cursor: pointer; }
.rollback__action:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
</style>

tailwind

<div class="rollback-tw font-sans max-w-[360px] p-5 bg-[#FAF7F2] text-[#241430] rounded-2xl border-[1.5px] border-[#24143020]" data-target="v13">
  <h3 class="m-0 mb-1.5 text-[17px] font-semibold">Homepage layout config</h3>
  <p class="m-0 mb-3 text-sm text-[#241430]/80">Currently on <strong>v14 (live)</strong>, published 2 hours ago</p>
  <ul class="list-none flex gap-2 m-0 mb-3.5 p-0">
    <li class="rollback-tw__entry text-[13px] font-semibold py-1.5 px-3 rounded-full bg-[#24143010] text-[#241430]/60" data-version="v13">v13</li>
    <li class="rollback-tw__entry text-[13px] font-semibold py-1.5 px-3 rounded-full bg-[#24143010] text-[#241430]/60" data-version="v12">v12</li>
    <li class="rollback-tw__entry text-[13px] font-semibold py-1.5 px-3 rounded-full bg-[#24143010] text-[#241430]/60" data-version="v11">v11</li>
  </ul>
  <button type="button" class="inline-flex items-center gap-1.5 border-[1.5px] border-[#241430] bg-transparent text-[#241430] font-semibold text-[13px] py-2 px-3.5 rounded-lg cursor-pointer"><svg viewBox="0 0 16 16" width="14" height="14" fill="none" aria-hidden="true"><path d="M3 8a5 5 0 1 0 1.5-3.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><path d="M3 3v3.5h3.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg> Roll back to v13</button>
</div>
<style>
.rollback-tw[data-target="v13"] .rollback-tw__entry[data-version="v13"] { background: #D9C8F0; color: #241430; }
.rollback-tw[data-target="v12"] .rollback-tw__entry[data-version="v12"] { background: #D9C8F0; color: #241430; }
.rollback-tw[data-target="v11"] .rollback-tw__entry[data-version="v11"] { background: #D9C8F0; color: #241430; }
</style>

react

export function Rollback({
  itemTitle = "Homepage layout config",
  currentVersion = "v14 (live)",
  timestamp = "published 2 hours ago",
  target = "v13",
  accent = "#D9C8F0",
}) {
  const history = ["v13", "v12", "v11"];
  return (
    <div style={{ fontFamily: "system-ui, sans-serif", maxWidth: 360, padding: 20, background: "#FAF7F2",
      color: "#241430", borderRadius: 14, border: "1.5px solid #24143020" }}>
      <h3 style={{ margin: "0 0 6px", fontSize: 17, fontWeight: 600 }}>{itemTitle}</h3>
      <p style={{ margin: "0 0 12px", fontSize: 14, color: "#241430cc" }}>Currently on <strong>{currentVersion}</strong>, {timestamp}</p>
      <ul style={{ listStyle: "none", display: "flex", gap: 8, margin: "0 0 14px", padding: 0 }}>
        {history.map((v) => (
          <li key={v} style={{ fontSize: 13, fontWeight: 600, padding: "6px 12px", borderRadius: 999,
            background: v === target ? accent : "#24143010", color: v === target ? "#241430" : "#24143099" }}>{v}</li>
        ))}
      </ul>
      <button type="button" style={{ display: "inline-flex", alignItems: "center", gap: 6, border: "1.5px solid #241430",
        background: "transparent", color: "#241430", fontWeight: 600, fontSize: 13, padding: "8px 14px", borderRadius: 8, cursor: "pointer" }}>
        <span dangerouslySetInnerHTML={{ __html: "<svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\" fill=\"none\" aria-hidden=\"true\"><path d=\"M3 8a5 5 0 1 0 1.5-3.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/><path d=\"M3 3v3.5h3.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>" }} /> Roll back to {target}
      </button>
    </div>
  );
}