{
  "name": "UnsavedChangesBar",
  "package": "@magicblocksai/ui",
  "file": "packages/ui/src/components/UnsavedChangesBar.tsx",
  "chapterTag": "15 App Shell",
  "chapter": "15-app-shell.html",
  "sectionId": "unsaved-changes-bar",
  "elName": "Floating save bar (static replica)",
  "demoUrl": "https://brand.magicblocks.ai/components/15-app-shell#unsaved-changes-bar",
  "hasLiveDemo": false,
  "description": "Portal-mounted sticky bottom bar that surfaces a \"you have unsaved changes\"\nmessage with Save and Discard actions. Controlled-only: consumers wire their\nown form-dirty state and call `onSave` / `onDiscard` handlers.",
  "useClient": true,
  "interactivity": "interactive",
  "namedExports": [
    {
      "name": "UnsavedChangesBar",
      "isPrincipal": true,
      "isType": false
    },
    {
      "name": "UnsavedChangesBarProps",
      "isPrincipal": false,
      "isType": false
    }
  ],
  "importStatement": "import { UnsavedChangesBar } from \"@magicblocksai/ui\";",
  "props": [],
  "classesUsed": [
    "btn",
    "btn-ghost",
    "btn-primary",
    "btn-sm",
    "unsaved-changes-bar",
    "unsaved-changes-bar-actions",
    "unsaved-changes-bar-inner",
    "unsaved-changes-bar-message"
  ],
  "examples": {
    "react": "function SettingsForm() {\n  const [dirty, setDirty] = useState(false);\n  const [saving, setSaving] = useState(false);",
    "html": "<div class=\"unsaved-changes-bar\" role=\"region\" aria-label=\"Unsaved changes\" aria-live=\"polite\" style=\"position: relative; padding: var(--s-3) 0;\">\n  <div class=\"unsaved-changes-bar-inner\">\n    <span class=\"unsaved-changes-bar-message\">You have unsaved changes</span>\n    <div class=\"unsaved-changes-bar-actions\">\n      <button type=\"button\" class=\"btn btn-ghost btn-sm\">Discard</button>\n      <button type=\"button\" class=\"btn btn-primary btn-sm\">Save changes</button>\n    </div>\n  </div>\n</div>",
    "css": ".btn {\n  display: inline-flex; align-items: center; justify-content: center;\n  gap: var(--s-2);\n  font: 600 14.5px/1 var(--f-display);\n  letter-spacing: -0.005em;\n  padding: 11px var(--s-5);\n  border: 1px solid transparent;\n  border-radius: var(--r-md);\n  cursor: pointer;\n  text-decoration: none;\n  transition: background var(--dur-2) var(--ease),\n              border-color var(--dur-2) var(--ease),\n              transform var(--dur-2) var(--ease),\n              box-shadow var(--dur-2) var(--ease),\n              color var(--dur-2) var(--ease);\n  user-select: none;\n  white-space: nowrap;\n  appearance: none; -webkit-appearance: none;\n}\n.btn { padding: 11px var(--s-5); font-size: 14.5px; }\n\n.btn-ghost {\n  background: transparent;\n  color: var(--fg);\n  border-color: transparent;\n}\n\n.btn-primary {\n  /* `color: var(--on-accent)` (added in v1.19.0) is the canonical\n     \"text on --accent\" token. Falls back to `var(--paper)` for any\n     consumer on an older @magicblocksai/css that pre-dates the\n     `--on-accent` token. */\n  background: var(--accent); color: var(--on-accent, var(--paper));\n  box-shadow: var(--sh-pink);\n}\n\n.btn-sm { padding: 7px var(--s-4); font-size: 13px; border-radius: var(--r-sm); }\n\n.unsaved-changes-bar {\n  position: fixed;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  z-index: 90;\n  padding: var(--s-3);\n  pointer-events: none;\n  display: flex;\n  justify-content: center;\n}\n\n.unsaved-changes-bar-actions {\n  display: flex;\n  gap: var(--s-2);\n  flex-shrink: 0;\n}\n\n.unsaved-changes-bar-inner {\n  pointer-events: auto;\n  display: flex;\n  align-items: center;\n  gap: var(--s-5);\n  padding: var(--s-3) var(--s-4);\n  background: var(--ink);\n  color: var(--paper);\n  border-radius: var(--r-pill);\n  box-shadow: var(--sh-3);\n  max-width: 720px;\n  width: 100%;\n}\n\n.unsaved-changes-bar-message {\n  font: 500 13px/1.4 var(--f-body);\n  flex: 1;\n  min-width: 0;\n}"
  }
}
