Skip to content
← Autosave Indicator
Edit Autosave Indicator
Name
Also known as (comma separated)
Brief definition
Shows content is being saved automatically.
Notes
Tier
Core
Useful
Reference
Deleted
Controls schema (JSON array)
[ { "id": "message", "type": "text", "label": "Status message", "default": "All changes saved" }, { "id": "timestamp", "type": "text", "label": "Timestamp", "default": "2 minutes ago" }, { "id": "state", "type": "select", "label": "State", "default": "saved", "options": [ "saved", "saving", "error" ] }, { "id": "accent", "type": "color", "label": "Accent colour", "default": "#A8E6C1", "presets": [ "#A8E6C1", "#F5C2E0", "#BFD9F2", "#D9C8F0", "#E8A020", "#241430" ] }, { "id": "compact", "type": "toggle", "label": "Compact (icon only)", "default": false } ]
Templates (JSON object keyed by format)
{ "html": "<div class=\"autosave autosave--{{state}}\" data-state=\"{{state}}\" role=\"status\" aria-live=\"polite\" style=\"--accent:{{accent}};\">\n <span class=\"autosave__dot\" aria-hidden=\"true\">\n <svg class=\"autosave__icon autosave__icon--saved\" viewBox=\"0 0 20 20\" width=\"14\" height=\"14\"><path d=\"M4 10.5l4 4 8-9\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <svg class=\"autosave__icon autosave__icon--saving\" viewBox=\"0 0 20 20\" width=\"14\" height=\"14\"><circle cx=\"10\" cy=\"10\" r=\"7\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-dasharray=\"24 12\"/></svg>\n <svg class=\"autosave__icon autosave__icon--error\" viewBox=\"0 0 20 20\" width=\"14\" height=\"14\"><path d=\"M10 3l8.5 14.5H1.5L10 3z\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"/><path d=\"M10 8v4\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/><circle cx=\"10\" cy=\"14.5\" r=\"1\" fill=\"currentColor\"/></svg>\n </span>\n {{#unless compact}}\n <span class=\"autosave__text\">\n <span class=\"autosave__message\">{{message}}</span>\n <span class=\"autosave__time\">{{timestamp}}</span>\n </span>\n {{/unless}}\n</div>\n<style>\n.autosave { font: 14px/1.4 system-ui, sans-serif; display: inline-flex; align-items: center; gap: 8px; padding: 8px 14px; border-radius: 999px; background: #FAF7F2; color: #241430; border: 1px solid #24143022; }\n.autosave__dot { position: relative; width: 16px; height: 16px; display: inline-flex; align-items: center; justify-content: center; color: var(--accent); }\n.autosave__icon { position: absolute; display: none; }\n.autosave--saved .autosave__icon--saved { display: block; }\n.autosave--saving .autosave__icon--saving { display: block; }\n@media (prefers-reduced-motion: no-preference) {\n.autosave--saving .autosave__icon--saving { animation: autosave-spin .2s linear infinite; }\n}\n.autosave--error .autosave__icon--error { display: block; color: #b3261e; }\n.autosave__text { display: flex; flex-direction: column; line-height: 1.25; }\n.autosave__message { font-weight: 600; }\n.autosave__time { font-size: 12px; color: #24143099; }\n@keyframes autosave-spin { to { transform: rotate(360deg); } }\n</style>", "tailwind": "<div role=\"status\" aria-live=\"polite\" data-state=\"{{state}}\" style=\"--accent:{{accent}};\" class=\"autosave-tw autosave-tw--{{state}} inline-flex items-center gap-2 px-3.5 py-2 rounded-full bg-[#FAF7F2] text-[#241430] border border-[#24143022] font-sans text-sm\">\n <span aria-hidden=\"true\" class=\"relative w-4 h-4 inline-flex items-center justify-center\" style=\"color:{{accent}}\">\n <svg class=\"autosave-tw__icon autosave-tw__icon--saved absolute\" viewBox=\"0 0 20 20\" width=\"14\" height=\"14\"><path d=\"M4 10.5l4 4 8-9\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <svg class=\"autosave-tw__icon autosave-tw__icon--saving absolute\" viewBox=\"0 0 20 20\" width=\"14\" height=\"14\"><circle cx=\"10\" cy=\"10\" r=\"7\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-dasharray=\"24 12\"/></svg>\n <svg class=\"autosave-tw__icon autosave-tw__icon--error absolute\" viewBox=\"0 0 20 20\" width=\"14\" height=\"14\"><path d=\"M10 3l8.5 14.5H1.5L10 3z\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"/><path d=\"M10 8v4\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/><circle cx=\"10\" cy=\"14.5\" r=\"1\" fill=\"currentColor\"/></svg>\n </span>\n {{#unless compact}}\n <span class=\"flex flex-col leading-tight\">\n <span class=\"font-semibold\">{{message}}</span>\n <span class=\"text-xs text-[#241430]/60\">{{timestamp}}</span>\n </span>\n {{/unless}}\n</div>\n<style>\n.autosave-tw__icon { display: none; }\n.autosave-tw--saved .autosave-tw__icon--saved { display: block; }\n.autosave-tw--saving .autosave-tw__icon--saving { display: block; }\n@media (prefers-reduced-motion: no-preference) {\n.autosave-tw--saving .autosave-tw__icon--saving { animation: autosave-tw-spin .2s linear infinite; }\n}\n.autosave-tw--error .autosave-tw__icon--error { display: block; color: #b3261e; }\n@keyframes autosave-tw-spin { to { transform: rotate(360deg); } }\n</style>", "react": "export function AutosaveIndicator({\n message = \"{{message}}\",\n timestamp = \"{{timestamp}}\",\n state = \"{{state}}\",\n accent = \"{{accent}}\",\n compact = {{compact}},\n}) {\n const icons = {\n saved: <path d=\"M4 10.5l4 4 8-9\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />,\n saving: <circle cx=\"10\" cy=\"10\" r=\"7\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.2\" strokeDasharray=\"24 12\" />,\n error: <path d=\"M10 3l8.5 14.5H1.5L10 3z\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" />,\n };\n return (\n <div role=\"status\" aria-live=\"polite\" style={{ display: \"inline-flex\", alignItems: \"center\", gap: 8,\n padding: \"8px 14px\", borderRadius: 999, background: \"#FAF7F2\", color: \"#241430\",\n border: \"1px solid #24143022\", fontFamily: \"system-ui, sans-serif\", fontSize: 14 }}>\n <span aria-hidden=\"true\" className={state === \"saving\" ? \"as-spin\" : undefined} style={{ color: accent, width: 16, height: 16, display: \"inline-flex\",\n alignItems: \"center\", justifyContent: \"center\" }}>\n <svg viewBox=\"0 0 20 20\" width=\"14\" height=\"14\">{icons[state] ?? icons.saved}</svg>\n </span>\n {!compact && (\n <span style={{ display: \"flex\", flexDirection: \"column\", lineHeight: 1.25 }}>\n <span style={{ fontWeight: 600 }}>{message}</span>\n <span style={{ fontSize: 12, color: \"#24143099\" }}>{timestamp}</span>\n </span>\n )}\n <style>{\"@media (prefers-reduced-motion: no-preference) { .as-spin { animation: autosave-spin .2s linear infinite; } } @keyframes autosave-spin { to { transform: rotate(360deg); } }\"}</style>\n </div>\n );\n}" }
Save
History