{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "author": "Lopifi (https://lopifi.com)",
  "categories": [
    "accounting-core-gl",
    "finance",
    "accounting"
  ],
  "dependencies": [
    "@base-ui-components/react"
  ],
  "description": "Hold-to-confirm. Never a delete.",
  "files": [
    {
      "content": "\"use client\";\n\nimport { Dialog } from \"@base-ui-components/react/dialog\";\nimport * as React from \"react\";\nimport { cn } from \"@/lib/ledger/cn\";\nimport { formatDate } from \"@/lib/ledger/fiscal-period\";\nimport { Button } from \"@/components/ledger/button\";\nimport { HoldToConfirm } from \"@/components/ledger/hold-to-confirm\";\n\nexport interface EntryReversalDialogProps {\n  /** A reversal in a closed period is dated in the current open period,\n      and the closed date is not offered. */\n  closedThrough?: Date;\n  currentPeriodStart: Date;\n  entryDate: Date;\n  entryNumber: string;\n  onConfirm: (reversalDate: Date) => void;\n  onOpenChange: (open: boolean) => void;\n  open: boolean;\n}\n\n/** Never a delete. Says exactly what will happen, and to what. */\nexport function EntryReversalDialog({\n  open,\n  onOpenChange,\n  entryNumber,\n  entryDate,\n  closedThrough,\n  currentPeriodStart,\n  onConfirm,\n}: EntryReversalDialogProps) {\n  const cancelRef = React.useRef<HTMLButtonElement>(null);\n  const inClosedPeriod = closedThrough != null && entryDate <= closedThrough;\n  const reversalDate = inClosedPeriod ? currentPeriodStart : entryDate;\n\n  return (\n    <Dialog.Root onOpenChange={onOpenChange} open={open}>\n      <Dialog.Portal>\n        <Dialog.Backdrop className=\"fixed inset-0 z-overlay bg-[oklch(0.21_0.02_265/0.4)]\" />\n        <Dialog.Popup\n          className={cn(\n            \"fixed left-1/2 top-1/2 z-dialog w-[calc(100vw-32px)] max-w-[460px]\",\n            \"-translate-x-1/2 -translate-y-1/2 rounded-xl border border-border bg-surface-raised p-6\",\n            \"shadow-elevation-4 outline-none\",\n          )}\n          /* Destructive dialog: focus lands on Cancel, never on the confirm. */\n          initialFocus={cancelRef}\n          role=\"alertdialog\"\n        >\n          <Dialog.Title className=\"text-title-md font-medium\">Reverse {entryNumber}?</Dialog.Title>\n          <Dialog.Description className=\"mt-2 text-body text-text-secondary\">\n            This creates an offsetting entry dated {formatDate(reversalDate)}. The original stays in the\n            ledger.\n            {inClosedPeriod ? (\n              <span className=\"mt-2 block text-text-primary\">\n                {formatDate(entryDate)} is in a closed period, so the reversal is dated in the current open\n                period instead.\n              </span>\n            ) : null}\n          </Dialog.Description>\n\n          <div className=\"mt-6 flex flex-col gap-3\">\n            <HoldToConfirm\n              label=\"Hold to reverse\"\n              onConfirm={() => {\n                onConfirm(reversalDate);\n                onOpenChange(false);\n              }}\n              typedConfirmation={entryNumber}\n            />\n            <Dialog.Close render={<Button ref={cancelRef} variant=\"secondary\" />}>Cancel</Dialog.Close>\n          </div>\n        </Dialog.Popup>\n      </Dialog.Portal>\n    </Dialog.Root>\n  );\n}\n",
      "path": "components/ledger/entry-reversal-dialog.tsx",
      "target": "components/ledger/entry-reversal-dialog.tsx",
      "type": "registry:component"
    }
  ],
  "name": "entry-reversal-dialog",
  "registryDependencies": [
    "@lopifi/theme",
    "@lopifi/button",
    "@lopifi/cn",
    "@lopifi/fiscal-period",
    "@lopifi/hold-to-confirm"
  ],
  "title": "EntryReversalDialog",
  "type": "registry:component"
}
