Retry State

UI offering another attempt.

html

<div class="retry" role="alert">
  <span class="retry__icon" aria-hidden="true">!</span>
  <div class="retry__body">
    <p class="retry__message">We could not load your feed.</p>
    <p class="retry__meta">Attempt 2</p>
  </div>
  <button type="button" class="retry__button">
    
    Try again
  </button>
</div>
<style>
.retry { display: flex; align-items: center; gap: 12px; max-width: 380px; padding: 12px 16px; box-sizing: border-box;
  border-radius: 10px; background: color-mix(in srgb, #B3261E 8%, #FAF7F2); border: 1px solid #B3261E; font: 13.5px/1.4 system-ui, sans-serif; color: #241430; }
.retry__icon { width: 22px; height: 22px; border-radius: 50%; background: #B3261E; color: #FAF7F2; flex-shrink: 0;
  display: grid; place-items: center; font: 700 12px/1 system-ui, sans-serif; }
.retry__body { flex: 1; }
.retry__message { margin: 0; font-weight: 700; }
.retry__meta { margin: 2px 0 0; color: #241430b3; font-size: 12px; }
.retry__button { display: inline-flex; align-items: center; gap: 6px; border: none; border-radius: 8px; background: #241430;
  color: #FAF7F2; font: 600 12.5px system-ui, sans-serif; padding: 8px 14px; cursor: pointer; white-space: nowrap; }
.retry__button:hover { background: #3a2350; }
.retry__button:focus-visible { outline: 2px solid #241430; outline-offset: 2px; }
.retry__button--busy { opacity: .75; cursor: progress; }
.retry__spinner { width: 12px; height: 12px; border-radius: 50%; border: 2px solid #FAF7F244; border-top-color: #FAF7F2; }
@keyframes retry-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: no-preference) {
  .retry__spinner { animation: retry-spin .2s linear infinite; }
}
</style>

tailwind

<div role="alert" class="retry-tw flex items-center gap-3 max-w-sm px-4 py-3 box-border rounded-lg border border-[#B3261E] font-sans text-[13.5px] text-[#241430]" style="background:color-mix(in srgb, #B3261E 8%, #FAF7F2)">
  <span aria-hidden="true" class="w-[22px] h-[22px] rounded-full bg-[#B3261E] text-[#FAF7F2] flex-shrink-0 grid place-items-center text-xs font-bold">!</span>
  <div class="flex-1">
    <p class="m-0 font-bold">We could not load your feed.</p>
    <p class="mt-0.5 mb-0 text-[#241430]/70 text-xs">Attempt 2</p>
  </div>
  <button type="button" class="retry-tw__button inline-flex items-center gap-1.5 border-0 rounded-lg bg-[#241430] text-[#FAF7F2] font-semibold text-[12.5px] px-3.5 py-2 cursor-pointer whitespace-nowrap hover:bg-[#3a2350]">
    
    Try again
  </button>
</div>
<style>
.retry-tw__button--busy { opacity: .75; cursor: progress; }
@keyframes retry-tw-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: no-preference) {
  .retry-tw__spinner { animation: retry-tw-spin .2s linear infinite; }
}
</style>

react

export function RetryState({
  message = "We could not load your feed.",
  retryLabel = "Try again",
  attempt = 2,
  isRetrying = false,
}) {
  return (
    <div role="alert" style={{ display: "flex", alignItems: "center", gap: 12, maxWidth: 380, padding: "12px 16px",
      boxSizing: "border-box", borderRadius: 10, background: "color-mix(in srgb, #B3261E 8%, #FAF7F2)",
      border: "1px solid #B3261E", font: "13.5px/1.4 system-ui, sans-serif", color: "#241430" }}>
      <span aria-hidden="true" style={{ width: 22, height: 22, borderRadius: "50%", background: "#B3261E", color: "#FAF7F2",
        flexShrink: 0, display: "grid", placeItems: "center", fontSize: 12, fontWeight: 700 }}>!</span>
      <div style={{ flex: 1 }}>
        <p style={{ margin: 0, fontWeight: 700 }}>{message}</p>
        <p style={{ margin: "2px 0 0", color: "#241430b3", fontSize: 12 }}>Attempt {attempt}</p>
      </div>
      <button type="button" style={{ display: "inline-flex", alignItems: "center", gap: 6, border: "none", borderRadius: 8,
        background: "#241430", color: "#FAF7F2", fontWeight: 600, fontSize: 12.5, padding: "8px 14px",
        cursor: isRetrying ? "progress" : "pointer", opacity: isRetrying ? 0.75 : 1, whiteSpace: "nowrap" }}>
        {isRetrying && <span aria-hidden="true" className="retry-spinner" style={{ width: 12, height: 12, borderRadius: "50%", border: "2px solid #FAF7F244",
          borderTopColor: "#FAF7F2" }} />}
        {retryLabel}
      </button>
      <style>{`
        @media (prefers-reduced-motion: no-preference) {
          .retry-spinner { animation: retry-react-spin .7s linear infinite; }
          @keyframes retry-react-spin { to { transform: rotate(360deg); } }
        }
      `}</style>
    </div>
  );
}