@ai-matrx/design-system 0.86.354 → 0.86.356

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/CHANGELOG.md +31 -2
  2. package/dist/carousel.js +3 -3
  3. package/dist/{chunk-UGQRAQTE.js → chunk-2PO3N42Q.js} +3 -3
  4. package/dist/{chunk-ZRHVA3DL.js → chunk-AV5C4YLL.js} +2 -1
  5. package/dist/{chunk-ZRHVA3DL.js.map → chunk-AV5C4YLL.js.map} +1 -1
  6. package/dist/chunk-LJKF267O.js +168 -0
  7. package/dist/chunk-LJKF267O.js.map +1 -0
  8. package/dist/{chunk-CFCWQDGC.js → chunk-RLM4RSED.js} +5 -23
  9. package/dist/chunk-RLM4RSED.js.map +1 -0
  10. package/dist/{chunk-FLWSEDUW.js → chunk-ZMUPFGQO.js} +2 -2
  11. package/dist/controls.cjs +86 -1
  12. package/dist/controls.cjs.map +1 -1
  13. package/dist/controls.js +3 -3
  14. package/dist/data-table/drill-chart.cjs +85 -1
  15. package/dist/data-table/drill-chart.cjs.map +1 -1
  16. package/dist/data-table/drill-chart.js +1 -1
  17. package/dist/data-table/index.cjs +85 -1
  18. package/dist/data-table/index.cjs.map +1 -1
  19. package/dist/data-table/index.js +1 -1
  20. package/dist/desktop.cjs +159 -81
  21. package/dist/desktop.cjs.map +1 -1
  22. package/dist/desktop.css +8 -5
  23. package/dist/desktop.d.cts +0 -5
  24. package/dist/desktop.d.ts +0 -5
  25. package/dist/desktop.js +70 -70
  26. package/dist/desktop.js.map +1 -1
  27. package/dist/email-input-dialog.cjs +85 -1
  28. package/dist/email-input-dialog.cjs.map +1 -1
  29. package/dist/email-input-dialog.js +1 -1
  30. package/dist/index.cjs +114 -19
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.cts +38 -22
  33. package/dist/index.d.ts +38 -22
  34. package/dist/index.js +16 -8
  35. package/dist/index.js.map +1 -1
  36. package/dist/lite-table.cjs +86 -19
  37. package/dist/lite-table.cjs.map +1 -1
  38. package/dist/lite-table.js +2 -2
  39. package/dist/notice-material.css +28 -0
  40. package/dist/record-list.cjs +86 -19
  41. package/dist/record-list.cjs.map +1 -1
  42. package/dist/record-list.js +2 -2
  43. package/dist/settings.cjs +1 -0
  44. package/dist/settings.cjs.map +1 -1
  45. package/dist/settings.js +1 -1
  46. package/dist/styles.css +1 -0
  47. package/dist/swipe-deck.cjs +95 -2
  48. package/dist/swipe-deck.cjs.map +1 -1
  49. package/dist/swipe-deck.css +2 -0
  50. package/dist/swipe-deck.js +11 -2
  51. package/dist/swipe-deck.js.map +1 -1
  52. package/dist/text-input-dialog.cjs +85 -1
  53. package/dist/text-input-dialog.cjs.map +1 -1
  54. package/dist/text-input-dialog.js +1 -1
  55. package/package.json +2 -2
  56. package/dist/chunk-CFCWQDGC.js.map +0 -1
  57. package/dist/chunk-HKLIRHT2.js +0 -71
  58. package/dist/chunk-HKLIRHT2.js.map +0 -1
  59. /package/dist/{chunk-UGQRAQTE.js.map → chunk-2PO3N42Q.js.map} +0 -0
  60. /package/dist/{chunk-FLWSEDUW.js.map → chunk-ZMUPFGQO.js.map} +0 -0
@@ -15,7 +15,7 @@ import {
15
15
  } from "./chunk-K4XCB576.js";
16
16
  import {
17
17
  ErrorActions
18
- } from "./chunk-HKLIRHT2.js";
18
+ } from "./chunk-LJKF267O.js";
19
19
  import "./chunk-TDMVH77G.js";
20
20
  import {
21
21
  Dialog,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/design-system",
3
- "version": "0.86.354",
3
+ "version": "0.86.356",
4
4
  "description": "AI Matrx semantic React primitives shared across Vite, Next.js, desktop, and customer-built applications.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -770,5 +770,5 @@
770
770
  "confirm-dialog",
771
771
  "alert-dialog"
772
772
  ],
773
- "gitHead": "bd26bcae0ed2db81d6ec629930d506df7d8c520f"
773
+ "gitHead": "bd77a197ad137da50d8f6fb02f54a66a150e1a49"
774
774
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/error-notice.tsx","../src/read-state/reload-page-button.tsx","../src/read-state/read-failure.tsx","../src/read-state/stale-data-notice.tsx","../src/read-state/read-gate.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * ErrorNotice — THE inline error card. Every error a surface renders inline\n * (\"Not saved\", \"Failed to load…\", a dialog's refusal, a form's failure) is\n * this component, so every one of them carries the Alchemy Menu and hands an\n * AI the sentence, the code, the operation, the records, the surface's declared\n * values and the person's unsaved input.\n *\n * <ErrorNotice\n * title=\"Not saved\"\n * message={item.error}\n * operation=\"Save comment\"\n * records={[{ type: \"document\", id: docId }]}\n * unsavedInput={{ comment: draft }}\n * actions={<Button onClick={retry}>Retry</Button>}\n * />\n *\n * Moved from matrx-frontend (chat host slots get real package defaults,\n * 2026-10-08). The host's actions (Matrx: the Alchemy Menu) arrive through\n * `ErrorActionsProvider`; the corner ⋯ and right-click menu through\n * `ErrorCardMenusProvider`. Without them the card still says everything.\n */\nimport type { ReactNode } from \"react\";\nimport { AlertTriangleIcon as AlertTriangle } from \"./icons\";\nimport { cn } from \"./cn\";\nimport { Button } from \"./button\";\nimport {\n ErrorActions,\n useErrorCardMenus,\n type ErrorActionsInput,\n type ErrorActionsRecord,\n} from \"./error-box\";\n\n/**\n * The sentence an error carries: its own message (string, Error, or any\n * object with a `message`). Empty when it has none.\n */\nexport function errorSentenceOf(error: unknown): string {\n if (error == null || error === true || error === false) return \"\";\n if (typeof error === \"string\") return error;\n if (typeof error !== \"object\") return String(error);\n const message = (error as { message?: unknown }).message;\n return typeof message === \"string\" ? message : \"\";\n}\n\n/**\n * What a person reads when the store cancelled a call at its statement timeout\n * (SQLSTATE 57014). Postgres' own \"canceling statement due to statement\n * timeout\" is about the database, not the person; the cancelled call rolled\n * back, so nothing was written (lane AT-SLOW, 2026-10-19). The same sentence\n * @ai-matrx/records' `TIMED_OUT_MESSAGE` gives.\n */\nexport const TIMED_OUT_SENTENCE = \"That took too long. Nothing was lost; try again.\";\n\n/** True when an error, its code, or its sentence is the store's statement timeout. */\nexport function isTimedOutError(error: unknown, message?: string | null, code?: string | number): boolean {\n if (code === \"57014\" || code === \"timed_out\") return true;\n if (error && typeof error === \"object\") {\n const o = error as { code?: unknown; sqlstate?: unknown };\n if (o.code === \"57014\" || o.code === \"timed_out\" || o.sqlstate === \"57014\") return true;\n }\n const text = `${message ?? \"\"} ${errorSentenceOf(error)}`;\n return /canceling statement due to statement timeout/i.test(text);\n}\n\nexport type ErrorNoticeProps = {\n /** Short heading (\"Not saved\"). */\n title?: string;\n /** The sentence shown. Falls back to the error's own message. */\n message?: string | null;\n /** The raw error — code/status/stack go to the AI payload, never the screen. */\n error?: unknown;\n operation?: string;\n records?: readonly ErrorActionsRecord[];\n unsavedInput?: unknown;\n details?: Record<string, unknown>;\n code?: string | number;\n status?: number;\n /** The tables / RPCs the failed call used — pins its captured request as the cause. */\n calls?: readonly string[];\n /** Retry / Discard / other controls, rendered under the sentence. */\n actions?: ReactNode;\n /**\n * Run the failed call again. Shown as \"Try again\" when the error is the\n * store's statement timeout and no `actions` were given.\n */\n onRetry?: () => void;\n /** Extra content under the sentence. */\n children?: ReactNode;\n /**\n * `default` = the card. `compact` = the dense card used inside lists and\n * side panels. `inline` = a one-line field/form error (no card chrome): the\n * sentence in the destructive color with the menu at its end — the shape\n * every `<p role=\"alert\" className=\"text-destructive\">` render moves onto.\n */\n size?: \"inline\" | \"compact\" | \"default\";\n icon?: boolean;\n className?: string;\n};\n\nexport function ErrorNotice({\n title,\n message,\n error,\n operation,\n records,\n unsavedInput,\n details,\n code,\n status,\n calls,\n actions: actionsProp,\n onRetry,\n children,\n size = \"default\",\n icon = true,\n className,\n}: ErrorNoticeProps) {\n const timedOut = isTimedOutError(error, message, code);\n const sentence = timedOut\n ? TIMED_OUT_SENTENCE\n : message?.trim() ||\n errorSentenceOf(error).trim() ||\n \"Something went wrong.\";\n const actions =\n actionsProp ??\n (timedOut && onRetry ? (\n <Button type=\"button\" size=\"sm\" variant=\"outline\" data-error-retry=\"\" onClick={onRetry}>\n Try again\n </Button>\n ) : undefined);\n const menus = useErrorCardMenus();\n const input: ErrorActionsInput = {\n title,\n message: sentence,\n error,\n operation,\n records,\n unsavedInput,\n details,\n code,\n status,\n ...(calls ? { calls } : {}),\n source: \"inline\",\n origin: \"design-system/ErrorNotice\",\n };\n if (size === \"inline\") {\n return (\n <div\n role=\"alert\"\n data-error-notice=\"\"\n className={cn(\"flex items-start gap-1 text-destructive\", className)}\n >\n <span className=\"min-w-0 flex-1 break-words\">\n {title ? (\n <span data-error-title=\"\" className=\"font-medium\">\n {title}:{\" \"}\n </span>\n ) : null}\n {sentence}\n </span>\n {children}\n {actions}\n <ErrorActions {...input} />\n </div>\n );\n }\n const compact = size === \"compact\";\n // Title, actions or extra content make the card taller than the ⋯ + menu column.\n const stacked = Boolean(title || actions || children);\n // The card is an action host like any other content (ALC-15): right-click,\n // ⋯ (the same menu, opened at the button), the phone's sheet and the palette\n // (⌘/Ctrl+Shift+K) all show the ONE registry's actions over this sentence.\n // Read-only: nothing here may change a record.\n const menuTitle = title ?? \"Error\";\n const menuText = title ? `${title}: ${sentence}` : sentence;\n const card = (\n <div\n role=\"alert\"\n data-error-notice=\"\"\n className={cn(\n \"rounded-md border border-destructive/30 bg-destructive/5\",\n compact ? \"px-2 py-1.5 text-xs\" : \"px-3 py-2.5 text-sm\",\n className,\n )}\n >\n <div className=\"flex items-start gap-2\">\n {icon && (\n <AlertTriangle\n aria-hidden\n className={cn(\n \"shrink-0 text-destructive\",\n compact ? \"mt-px h-3.5 w-3.5\" : \"mt-0.5 h-4 w-4\",\n )}\n />\n )}\n <div className=\"min-w-0 flex-1\">\n {title && (\n <p data-error-title=\"\" className=\"font-medium text-destructive\">\n {title}\n </p>\n )}\n <p className={cn(\"break-words text-foreground\", title && \"mt-0.5\")}>\n {sentence}\n {!stacked && <ErrorActions {...input} />}\n </p>\n {children}\n {actions && <div className=\"mt-1 flex flex-wrap gap-1\">{actions}</div>}\n </div>\n {/* The corner column the ⋯ already owns carries the menu under it: no\n new column (beside the ⋯ it narrowed every line — 176→224px at\n 375px) and no new line (inline, a full last line wrapped it,\n +16px). A one-line notice with nothing under its sentence is\n shorter than that column, so there the menu rides the sentence\n (RC-B12 layout rule). */}\n <div className=\"flex shrink-0 flex-col items-center\">\n {menus ? (\n <menus.Button\n title={menuTitle}\n text={menuText}\n {...(compact ? { className: \"h-6 w-6\" } : {})}\n />\n ) : null}\n {stacked && <ErrorActions {...input} />}\n </div>\n </div>\n </div>\n );\n if (!menus) return card;\n return (\n <menus.Boundary title={menuTitle} text={menuText}>\n {card}\n </menus.Boundary>\n );\n}\n","\"use client\";\n\n/**\n * THE SERVER-SAFE RETRY. A server page cannot hand a failure notice a retry\n * function — functions do not cross the server/client boundary — so its\n * \"Couldn't load …\" card had no way forward but the browser's own reload\n * (page-pass 2026-09-27, /chat/message-templates/<id>). This control is the\n * retry any server-rendered failure can carry: it takes no props a server\n * cannot send, and it reloads THIS url (path, query and hash), which re-runs the\n * server read that failed.\n *\n * Its words say what it does — \"Reload page\" — because a reload also drops\n * anything unsaved elsewhere on the page; a client surface that can retry just\n * its own read passes `onRetry` to `ReadFailure` instead.\n */\nimport { RefreshCwIcon as RefreshCw } from \"../icons\";\nimport { Button } from \"../button\";\n\nexport const RELOAD_PAGE_LABEL = \"Reload page\";\n\nexport function ReloadPageButton({ className }: { className?: string }) {\n return (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className={className ?? \"h-7 gap-1.5 text-xs\"}\n onClick={() => window.location.reload()}\n >\n <RefreshCw className=\"h-3.5 w-3.5\" aria-hidden /> {RELOAD_PAGE_LABEL}\n </Button>\n );\n}\n","\"use client\";\n\n/**\n * The failed-read view every list uses instead of its empty state (RC-B12\n * round 11): the error, with the Alchemy Menu (through ErrorNotice) and a\n * retry when the caller has one. `error` may be the error itself or just the\n * read's failed flag — the sentence never pretends there is nothing.\n *\n * ALWAYS A WAY FORWARD. With `onRetry` it offers \"Try again\" (the surface's own\n * read, nothing else touched). Without one — every SERVER page, which cannot\n * pass a function — it offers `ReloadPageButton`: a same-URL reload that re-runs\n * the server read. A failure card with no retry at all is gone.\n */\nimport { RefreshCwIcon as RefreshCw } from \"../icons\";\nimport { Button } from \"../button\";\nimport { ErrorNotice } from \"../error-notice\";\nimport { ReloadPageButton } from \"./reload-page-button\";\n\nexport type ReadFailureProps = {\n error: unknown;\n /** What could not be read, in the reader's words: \"your tasks\". */\n what?: string | undefined;\n /** Retry just this read. Absent (always, from a server page): a same-URL reload is offered. */\n onRetry?: (() => void) | undefined;\n className?: string | undefined;\n size?: \"compact\" | \"default\" | undefined;\n};\n\nexport function ReadFailure({\n error,\n what = \"this list\",\n onRetry,\n className,\n size = \"compact\",\n}: ReadFailureProps) {\n const flagOnly = error === true || error == null || error === \"\";\n return (\n <ErrorNotice\n size={size}\n className={className ?? \"m-3\"}\n title={`Couldn't load ${what}`}\n {...(flagOnly\n ? { message: `The read for ${what} failed, so nothing here is an answer — not \"empty\".` }\n : { error })}\n operation={`Load ${what}`}\n actions={\n onRetry ? (\n <Button variant=\"outline\" size=\"sm\" className=\"h-7 gap-1.5 text-xs\" onClick={onRetry}>\n <RefreshCw className=\"h-3.5 w-3.5\" /> Try again\n </Button>\n ) : (\n <ReloadPageButton />\n )\n }\n />\n );\n}\n","\"use client\";\n\n/**\n * StaleDataNotice — what a surface shows when a READ FAILED and the rows on\n * screen are therefore not to be trusted.\n *\n * THE DEAD END this kills: a list loads fine, the user acts, the surface\n * reloads — and the reload fails. A toast fires and fades. What remains is the\n * PREVIOUS list, rendered exactly like a fresh one. The user reads a roster\n * that no longer reflects the database and has no way to know. Bugbot found\n * this on the admins roster and the feedback table in the same pass, which is\n * what made it a primitive instead of two patches.\n *\n * This is the campaign's never-report-green rule at its sharpest: **a surface\n * must never present data it could not actually read as though it had.** The\n * sibling `DeepLinkMissNotice` states a definitive negative and so demands\n * proof the list WAS read; this states the opposite — that the read broke —\n * and is what that component's \"show the surface's ordinary error state\n * instead\" was pointing at. Neither is complete without the other.\n *\n * Two cases, and conflating them is the actual bug:\n *\n * 1. **Stale** (`hasData`) — rows are on screen from an earlier successful\n * read. Say they may be out of date. Do NOT blank them: old data plus an\n * honest label beats an empty screen, and the user may still need it.\n * 2. **Unknown** (`!hasData`) — nothing was ever read. An empty list here\n * reads as \"there are none\", which is a claim about the database nobody\n * is entitled to make. Say the read failed instead.\n *\n * `onRetry` is not optional decoration — a problem you can detect ships with\n * its one-click fix. The user should never have to reload the page to recover\n * from a failed fetch.\n */\n\nimport { AlertTriangleIcon as AlertTriangle, RefreshCwIcon as RefreshCw } from \"../icons\";\nimport { Button } from \"../button\";\nimport { cn } from \"../cn\";\nimport { ErrorActions } from \"../error-box\";\n\nexport interface StaleDataNoticeProps {\n /**\n * Whether rows from an earlier SUCCESSFUL read are currently displayed.\n * Decides between \"this may be out of date\" and \"we never read this\".\n */\n hasData: boolean;\n /**\n * What could not be read, as a plain noun phrase the user recognizes —\n * \"the admin roster\", \"feedback\". Never a table or endpoint name: our user\n * is a subject-matter expert, not an engineer.\n */\n what: string;\n /** Re-run the read. Required — the notice always carries its own fix. */\n onRetry: () => void;\n /** Disables the retry control and shows motion while a retry is in flight. */\n retrying?: boolean;\n /** Optional detail (a server message). Shown verbatim, never interpreted. */\n detail?: string | null;\n /**\n * A multi-source list where SOME sources read and some did not: the rows on\n * screen are current, but `what` is missing from them. Says so instead of\n * \"may be out of date\" (RC-B12 round 12 — a partly failed roster).\n */\n partial?: boolean;\n className?: string;\n}\n\nexport function StaleDataNotice({\n hasData,\n what,\n onRetry,\n retrying = false,\n detail,\n partial = false,\n className,\n}: StaleDataNoticeProps) {\n return (\n <div\n role=\"status\"\n className={cn(\n \"flex flex-wrap items-center gap-x-3 gap-y-1.5 rounded-md border border-amber-500/40 bg-amber-500/10 px-3 py-2 type-body\",\n className,\n )}\n >\n <AlertTriangle className=\"h-4 w-4 shrink-0 text-amber-600 dark:text-amber-500\" />\n <span className=\"min-w-0 flex-1 text-foreground\">\n {partial ? (\n <>\n Couldn&apos;t load {what}, so <strong>they are missing</strong> from\n the list below — everything else loaded.\n </>\n ) : hasData ? (\n <>\n Couldn&apos;t refresh {what}. What you see below is the last version\n we loaded and <strong>may be out of date</strong>.\n </>\n ) : (\n <>\n Couldn&apos;t load {what}, so this list is empty because the read\n failed — <strong>not</strong> because there is nothing here.\n </>\n )}\n {detail ? (\n <span className=\"ml-1 text-muted-foreground\">({detail})</span>\n ) : null}\n {/* A failed read is an error on screen: it carries the Alchemy Menu (RC-B12),\n INSIDE the sentence — as its own flex item it narrowed the text and\n grew the notice 118→138px at 375px. */}\n <ErrorActions\n title={partial || !hasData ? `Couldn't load ${what}` : `Couldn't refresh ${what}`}\n message={\n detail\n ? `${hasData ? \"Couldn't refresh\" : \"Couldn't load\"} ${what}: ${detail}`\n : `${hasData ? \"Couldn't refresh\" : \"Couldn't load\"} ${what}.`\n }\n operation={`${hasData ? \"Refresh\" : \"Load\"} ${what}`}\n details={partial ? { rows_on_screen_are_partial: true } : { rows_on_screen_are_stale: hasData }}\n source=\"inline\"\n origin=\"design-system/StaleDataNotice\"\n />\n </span>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={onRetry}\n disabled={retrying}\n className=\"h-11 shrink-0 gap-1.5 lg:h-7\"\n >\n <RefreshCw className={cn(\"h-3.5 w-3.5\", retrying && \"matrx-spin\")} />\n {retrying ? \"Retrying…\" : \"Try again\"}\n </Button>\n </div>\n );\n}\n","\"use client\";\n\n/**\n * THE rule for every empty view (RC-B12 round 11): \"nothing here\" is an answer\n * only after a read that SUCCEEDED and returned nothing.\n *\n * <ReadGate status={readStatusOf(query)} error={query.error} what=\"your tasks\"\n * isEmpty={tasks.length === 0} empty={<p>No tasks yet.</p>} onRetry={refetch}>\n * <TaskList tasks={tasks} />\n * </ReadGate>\n *\n * loading → a wait · error → the failure (with the menu) · ready + empty → the\n * empty view · ready → the rows. When a refresh fails but earlier rows are on\n * screen, the rows stay and the failure is said above them.\n * Guarded by the census `findUngatedEmptyStates` and the lint rule\n * matrx/error-render-carries-alchemy (an empty view under a loading check\n * with no failure check is refused).\n */\nimport type { ReactNode } from \"react\";\nimport { Loader2Icon as Loader2 } from \"../icons\";\nimport { ReadFailure } from \"./read-failure\";\nimport { StaleDataNotice } from \"./stale-data-notice\";\n\nexport type ReadStatus = \"loading\" | \"error\" | \"ready\";\n\n/** The usual shapes a read reports itself in, folded into one status. */\nexport function readStatusOf(read: {\n status?: string | null;\n isLoading?: boolean;\n loading?: boolean;\n isFetching?: boolean;\n isError?: boolean;\n error?: unknown;\n}): ReadStatus {\n if (read.isError || (read.error != null && read.error !== false && read.error !== \"\")) return \"error\";\n if (read.status === \"error\" || read.status === \"failed\") return \"error\";\n if (read.isLoading || read.loading || read.status === \"loading\" || read.status === \"idle\" || read.status === \"pending\") return \"loading\";\n return \"ready\";\n}\n\n/**\n * A read's outcome handed to a list/table primitive (RC-B12 round 13). Every\n * primitive that takes an `emptyState` also takes `read?: ReadOutcome` and\n * renders the empty state only when `status === \"ready\"`: \"error\" with no rows\n * → <ReadFailure/> with the retry; \"error\" with rows → the rows under a stale\n * notice; \"loading\" with no rows → loading. Structurally identical to the\n * design-system table's `MatrxDataTableRead`, so one value serves both.\n */\nexport interface ReadOutcome {\n status: ReadStatus;\n /** The failure itself, or a truthy flag when the read only says it failed. */\n error?: unknown;\n onRetry?: (() => void) | undefined;\n /** What was read, in the reader's words: \"your tasks\". */\n what?: string | undefined;\n /**\n * A successful read has already produced a value (rows, a count). Then a\n * refetch in flight is not \"loading\" and a failed refresh is not \"no value\":\n * counts keep their last known value (with the stale mark) — the same\n * stale-while-error rule as rows (RC-B12 r13 ruling).\n */\n hasData?: boolean | undefined;\n}\n\ntype ReadLike = Parameters<typeof readStatusOf>[0] & {\n refetch?: () => unknown;\n retry?: () => unknown;\n /** The read's value (react-query `data`, a hook's rows) — present means a read already landed. */\n data?: unknown;\n /** react-query: when the data last arrived (0 = never). */\n dataUpdatedAt?: number;\n /** A hook that tracks it directly. */\n hasData?: boolean;\n};\n\n/** Has a successful read already produced a value? */\nfunction readHasData(read: ReadLike): boolean {\n if (typeof read.hasData === \"boolean\") return read.hasData;\n if (typeof read.dataUpdatedAt === \"number\" && read.dataUpdatedAt > 0) return true;\n // An empty array is often a hook's initial placeholder, not an answer — it\n // proves nothing was read; only a hook's own `hasData`/`dataUpdatedAt` can.\n if (Array.isArray(read.data)) return read.data.length > 0;\n return read.data !== undefined && read.data !== null;\n}\n\n/**\n * Fold a query/hook result into a `ReadOutcome`:\n * <MatrxDataTable data={rows} emptyState={…} read={readOf(query, { what: \"your tasks\" })} />\n * The retry is the read's own `refetch` / `retry` unless `onRetry` is given.\n */\nexport function readOf(read: ReadLike, options: { what?: string; onRetry?: () => void } = {}): ReadOutcome {\n const again = options.onRetry ?? read.refetch ?? read.retry;\n return {\n status: readStatusOf(read),\n error: read.error ?? (read.isError ? true : undefined),\n ...(again ? { onRetry: () => void again() } : {}),\n ...(options.what ? { what: options.what } : {}),\n hasData: readHasData(read),\n };\n}\n\nexport function ReadGate({\n read,\n status: statusProp,\n error: errorProp,\n what: whatProp,\n isEmpty,\n empty,\n loading,\n onRetry: onRetryProp,\n children,\n}: {\n /**\n * The read's outcome in one value — what a list primitive's `read` prop\n * carries. Absent (and no `status`), the gate is \"ready\": a primitive whose\n * caller passed no read renders exactly as before.\n */\n read?: ReadOutcome | undefined;\n status?: ReadStatus;\n error?: unknown;\n what?: string;\n isEmpty: boolean;\n empty: ReactNode;\n loading?: ReactNode;\n onRetry?: (() => void) | undefined;\n children: ReactNode;\n}) {\n const status = statusProp ?? read?.status ?? \"ready\";\n const error = errorProp ?? read?.error;\n const what = whatProp ?? read?.what ?? \"this list\";\n const onRetry = onRetryProp ?? read?.onRetry;\n if (status === \"error\") {\n if (isEmpty) return <ReadFailure error={error ?? true} what={what} onRetry={onRetry} />;\n // Rows from an earlier read stay; the notice says they may be out of date.\n return (\n <>\n {onRetry ? (\n <StaleDataNotice hasData what={what} onRetry={onRetry} className=\"mb-2\" />\n ) : (\n <ReadFailure error={error ?? true} what={what} />\n )}\n {children}\n </>\n );\n }\n if (status === \"loading\" && isEmpty) {\n return (\n loading ?? (\n <div className=\"flex items-center justify-center gap-2 p-4 text-xs text-muted-foreground\" role=\"status\" aria-busy=\"true\">\n <Loader2 className=\"h-4 w-4 matrx-spin\" /> Loading {what}…\n </div>\n )\n );\n }\n if (isEmpty) return <>{empty}</>;\n return <>{children}</>;\n}\n\n/**\n * A list primitive's EMPTY branch (RC-B12 round 13): the failure while its read\n * failed, the wait while it loads, and the primitive's own empty view only\n * after a read that succeeded. No `read` → the empty view, as before.\n *\n * if (items.length === 0) return <ReadEmpty read={read}>{emptyState}</ReadEmpty>;\n */\nexport function ReadEmpty({ read, loading, children }: { read?: ReadOutcome | undefined; loading?: ReactNode; children?: ReactNode }) {\n return (\n <ReadGate read={read} isEmpty empty={children ?? null} {...(loading === undefined ? {} : { loading })}>\n {null}\n </ReadGate>\n );\n}\n\n/**\n * Above a primitive's ROWS: when the latest read failed, the rows on screen are\n * from an earlier read — say so (StaleDataNotice with its retry), never blank them.\n */\nexport function ReadStaleNotice({ read, className }: { read?: ReadOutcome | undefined; className?: string }) {\n if (read?.status !== \"error\") return null;\n const what = read.what ?? \"this list\";\n if (!read.onRetry) return <ReadFailure error={read.error ?? true} what={what} {...(className ? { className } : {})} />;\n return <StaleDataNotice hasData what={what} onRetry={read.onRetry} {...(className ? { className } : {})} />;\n}\n"],"mappings":"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","names":["jsx","jsxs","jsx","jsxs","jsx","jsxs","Fragment","jsx","jsxs"]}
@@ -1,71 +0,0 @@
1
- "use client";
2
-
3
- // src/error-box.tsx
4
- import * as React from "react";
5
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
- var CONTEXT_KEY = /* @__PURE__ */ Symbol.for("@ai-matrx/design-system/error-actions");
7
- var registry = globalThis;
8
- var ErrorActionsContext = registry[CONTEXT_KEY] ?? (registry[CONTEXT_KEY] = React.createContext(null));
9
- function ErrorActionsProvider({
10
- render,
11
- children
12
- }) {
13
- return /* @__PURE__ */ jsx(ErrorActionsContext.Provider, { value: render, children });
14
- }
15
- var MENUS_KEY = /* @__PURE__ */ Symbol.for("@ai-matrx/design-system/error-card-menus");
16
- var menusRegistry = globalThis;
17
- var ErrorCardMenusContext = menusRegistry[MENUS_KEY] ?? (menusRegistry[MENUS_KEY] = React.createContext(null));
18
- function ErrorCardMenusProvider({
19
- menus,
20
- children
21
- }) {
22
- return /* @__PURE__ */ jsx(ErrorCardMenusContext.Provider, { value: menus, children });
23
- }
24
- function useErrorCardMenus() {
25
- return React.useContext(ErrorCardMenusContext);
26
- }
27
- function useErrorActions() {
28
- return React.useContext(ErrorActionsContext);
29
- }
30
- function ErrorActions(props) {
31
- const render = useErrorActions();
32
- if (!render) return null;
33
- return /* @__PURE__ */ jsx(Fragment, { children: render(props) });
34
- }
35
- var ErrorBox = React.forwardRef(function ErrorBox2({
36
- as = "p",
37
- message,
38
- title,
39
- error,
40
- operation,
41
- records,
42
- unsavedInput,
43
- origin,
44
- children,
45
- ...rest
46
- }, ref) {
47
- const Tag = as;
48
- const facts = {
49
- ...message !== void 0 ? { message } : {},
50
- ...title !== void 0 ? { title } : {},
51
- ...error !== void 0 ? { error } : {},
52
- ...operation !== void 0 ? { operation } : {},
53
- ...records !== void 0 ? { records } : {},
54
- ...unsavedInput !== void 0 ? { unsavedInput } : {},
55
- ...origin !== void 0 ? { origin } : {}
56
- };
57
- return /* @__PURE__ */ jsxs(Tag, { ref, role: "alert", "data-error-box": "", ...rest, children: [
58
- children ?? message,
59
- /* @__PURE__ */ jsx(ErrorActions, { ...facts })
60
- ] });
61
- });
62
-
63
- export {
64
- ErrorActionsProvider,
65
- ErrorCardMenusProvider,
66
- useErrorCardMenus,
67
- useErrorActions,
68
- ErrorActions,
69
- ErrorBox
70
- };
71
- //# sourceMappingURL=chunk-HKLIRHT2.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/error-box.tsx"],"sourcesContent":["/**\n * ErrorBox — THE one way a package draws an error on screen, and the seam a\n * host uses to put its own actions on every one of them.\n *\n * Every error sentence this package (and every sibling package that depends\n * on it) shows is an `ErrorBox`. The box is a plain `role=\"alert\"` element —\n * its tag and classes are the caller's, so nothing about the look changes — and\n * after its children it renders whatever the host's `ErrorActionsProvider`\n * returns for that error. With no provider it renders nothing extra.\n *\n * Why a slot and not a menu: the package cannot know the host's AI copy, bug\n * report, or support flow (Matrx fills it with its Alchemy copy-for-AI menu at\n * the app root). The package supplies the error's facts — the sentence, the\n * raw error, the operation, the records — and the host decides the actions.\n *\n * Guard: `error-box.census.test.ts` fails when a package file renders\n * `role=\"alert\"` for an error without going through `ErrorBox` (or, for the\n * `Alert` family, `ErrorActions`).\n */\nimport * as React from \"react\";\n\nexport interface ErrorActionsRecord {\n type: string;\n id: string;\n label?: string;\n}\n\n/** The facts a package knows about an error it is showing. All optional. */\nexport interface ErrorActionsInput {\n /** The sentence shown. Omit when the words are only in the rendered box. */\n message?: string | undefined;\n title?: string | undefined;\n /** The raw error (code/status/stack stay available to the host). */\n error?: unknown | undefined;\n /** What was being attempted (\"Load saved views\"). */\n operation?: string | undefined;\n records?: readonly ErrorActionsRecord[] | undefined;\n /** The person's input that did not land. */\n unsavedInput?: unknown | undefined;\n /** The package + component that drew it (\"design-system/SavedViewsControl\"). */\n origin?: string | undefined;\n /** Extra structured facts for the AI payload (never shown). */\n details?: Record<string, unknown> | undefined;\n code?: string | number | undefined;\n status?: number | undefined;\n /** The tables / RPCs the failed call used — pins its captured request as the cause. */\n calls?: readonly string[] | undefined;\n /** Where it was drawn: an `ErrorNotice` card/line (\"inline\") or a package alert box (\"alert\", the default). */\n source?: \"inline\" | \"alert\" | undefined;\n}\n\nexport type ErrorActionsRenderer = (input: ErrorActionsInput) => React.ReactNode;\n\n/**\n * ONE context for every copy of this module. tsup builds each entry point\n * (`.`, `./data-table`, …) without code splitting, so this file is inlined into\n * several bundles; a plain `createContext` would give each bundle its own\n * context and the host's provider (imported from `.`) would never reach an\n * error drawn by the data table. The registry key makes them one.\n */\nconst CONTEXT_KEY = Symbol.for(\"@ai-matrx/design-system/error-actions\");\ntype ContextRegistry = Record<symbol, React.Context<ErrorActionsRenderer | null> | undefined>;\nconst registry = globalThis as unknown as ContextRegistry;\nconst ErrorActionsContext: React.Context<ErrorActionsRenderer | null> =\n registry[CONTEXT_KEY] ??\n (registry[CONTEXT_KEY] = React.createContext<ErrorActionsRenderer | null>(null));\n\n/** Mount once at the host's app root; every ErrorBox below renders `render(...)`. */\nexport function ErrorActionsProvider({\n render,\n children,\n}: {\n render: ErrorActionsRenderer;\n children: React.ReactNode;\n}) {\n return (\n <ErrorActionsContext.Provider value={render}>{children}</ErrorActionsContext.Provider>\n );\n}\n\n/**\n * The host's content menu around an error card (`ErrorNotice`): the corner ⋯\n * button and the right-click boundary that show the host's content actions\n * over the error's sentence. Read-only — nothing here may change a record.\n * Without a provider the card draws neither (the actions slot still renders).\n */\nexport interface ErrorCardMenus {\n /** The corner ⋯ button over `{ title, text }`. */\n Button: React.ComponentType<{ title: string; text: string; className?: string }>;\n /** Wraps the whole card so right-click opens the same menu. */\n Boundary: React.ComponentType<{ title: string; text: string; children: React.ReactNode }>;\n}\n\nconst MENUS_KEY = Symbol.for(\"@ai-matrx/design-system/error-card-menus\");\ntype MenusRegistry = Record<symbol, React.Context<ErrorCardMenus | null> | undefined>;\nconst menusRegistry = globalThis as unknown as MenusRegistry;\nconst ErrorCardMenusContext: React.Context<ErrorCardMenus | null> =\n menusRegistry[MENUS_KEY] ??\n (menusRegistry[MENUS_KEY] = React.createContext<ErrorCardMenus | null>(null));\n\n/** Mount once at the host's app root beside `ErrorActionsProvider`. */\nexport function ErrorCardMenusProvider({\n menus,\n children,\n}: {\n menus: ErrorCardMenus;\n children: React.ReactNode;\n}) {\n return <ErrorCardMenusContext.Provider value={menus}>{children}</ErrorCardMenusContext.Provider>;\n}\n\nexport function useErrorCardMenus(): ErrorCardMenus | null {\n return React.useContext(ErrorCardMenusContext);\n}\n\nexport function useErrorActions(): ErrorActionsRenderer | null {\n return React.useContext(ErrorActionsContext);\n}\n\n/**\n * The host's actions for one error, placed wherever the caller puts this\n * element. Renders nothing without a provider. Use inside a box you do not\n * render yourself (the `Alert` family); everything else uses `ErrorBox`.\n */\nexport function ErrorActions(props: ErrorActionsInput) {\n const render = useErrorActions();\n if (!render) return null;\n return <>{render(props)}</>;\n}\n\ntype ErrorBoxTag = \"p\" | \"div\" | \"span\" | \"section\" | \"li\";\n\nexport interface ErrorBoxProps\n extends Omit<React.HTMLAttributes<HTMLElement>, \"role\" | \"title\">,\n ErrorActionsInput {\n /** The element drawn — the caller's existing tag, so layout never shifts. */\n as?: ErrorBoxTag;\n}\n\nexport const ErrorBox = React.forwardRef<HTMLElement, ErrorBoxProps>(function ErrorBox(\n {\n as = \"p\",\n message,\n title,\n error,\n operation,\n records,\n unsavedInput,\n origin,\n children,\n ...rest\n },\n ref,\n) {\n // A component type, never a bare ElementType: an app compiling this source may carry global JSX\n // elements (react-three-fiber) that make a bare ElementType's props `never` (2026-10-22).\n const Tag = as as unknown as React.ComponentType<React.HTMLAttributes<HTMLElement> & { ref?: React.Ref<HTMLElement> }>;\n const facts: ErrorActionsInput = {\n ...(message !== undefined ? { message } : {}),\n ...(title !== undefined ? { title } : {}),\n ...(error !== undefined ? { error } : {}),\n ...(operation !== undefined ? { operation } : {}),\n ...(records !== undefined ? { records } : {}),\n ...(unsavedInput !== undefined ? { unsavedInput } : {}),\n ...(origin !== undefined ? { origin } : {}),\n };\n return (\n <Tag ref={ref} role=\"alert\" data-error-box=\"\" {...rest}>\n {children ?? message}\n <ErrorActions {...facts} />\n </Tag>\n );\n});\n"],"mappings":";;;AAmBA,YAAY,WAAW;AAyDnB,SAmDK,UAnDL,KA2FA,YA3FA;AAhBJ,IAAM,cAAc,uBAAO,IAAI,uCAAuC;AAEtE,IAAM,WAAW;AACjB,IAAM,sBACJ,SAAS,WAAW,MACnB,SAAS,WAAW,IAAU,oBAA2C,IAAI;AAGzE,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA;AACF,GAGG;AACD,SACE,oBAAC,oBAAoB,UAApB,EAA6B,OAAO,QAAS,UAAS;AAE3D;AAeA,IAAM,YAAY,uBAAO,IAAI,0CAA0C;AAEvE,IAAM,gBAAgB;AACtB,IAAM,wBACJ,cAAc,SAAS,MACtB,cAAc,SAAS,IAAU,oBAAqC,IAAI;AAGtE,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA;AACF,GAGG;AACD,SAAO,oBAAC,sBAAsB,UAAtB,EAA+B,OAAO,OAAQ,UAAS;AACjE;AAEO,SAAS,oBAA2C;AACzD,SAAa,iBAAW,qBAAqB;AAC/C;AAEO,SAAS,kBAA+C;AAC7D,SAAa,iBAAW,mBAAmB;AAC7C;AAOO,SAAS,aAAa,OAA0B;AACrD,QAAM,SAAS,gBAAgB;AAC/B,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,gCAAG,iBAAO,KAAK,GAAE;AAC1B;AAWO,IAAM,WAAiB,iBAAuC,SAASA,UAC5E;AAAA,EACE,KAAK;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GACA,KACA;AAGA,QAAM,MAAM;AACZ,QAAM,QAA2B;AAAA,IAC/B,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC3C,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC;AAAA,IACvC,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC;AAAA,IACvC,GAAI,cAAc,SAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IAC/C,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC3C,GAAI,iBAAiB,SAAY,EAAE,aAAa,IAAI,CAAC;AAAA,IACrD,GAAI,WAAW,SAAY,EAAE,OAAO,IAAI,CAAC;AAAA,EAC3C;AACA,SACE,qBAAC,OAAI,KAAU,MAAK,SAAQ,kBAAe,IAAI,GAAG,MAC/C;AAAA,gBAAY;AAAA,IACb,oBAAC,gBAAc,GAAG,OAAO;AAAA,KAC3B;AAEJ,CAAC;","names":["ErrorBox"]}