@ai-matrx/design-system 0.20.15 → 0.20.18

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 (40) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/data-table/copy-helpers.d.cts +1 -1
  3. package/dist/data-table/copy-helpers.d.ts +1 -1
  4. package/dist/data-table/filter-engine.d.cts +1 -1
  5. package/dist/data-table/filter-engine.d.ts +1 -1
  6. package/dist/data-table/host.d.cts +1 -1
  7. package/dist/data-table/host.d.ts +1 -1
  8. package/dist/data-table/index.cjs +1217 -1068
  9. package/dist/data-table/index.cjs.map +1 -1
  10. package/dist/data-table/index.d.cts +21 -3
  11. package/dist/data-table/index.d.ts +21 -3
  12. package/dist/data-table/index.js +1115 -966
  13. package/dist/data-table/index.js.map +1 -1
  14. package/dist/data-table/infer-filter.d.cts +1 -1
  15. package/dist/data-table/infer-filter.d.ts +1 -1
  16. package/dist/data-table/layered-filters.d.cts +1 -1
  17. package/dist/data-table/layered-filters.d.ts +1 -1
  18. package/dist/data-table/pagination.cjs +18 -14
  19. package/dist/data-table/pagination.cjs.map +1 -1
  20. package/dist/data-table/pagination.js +18 -14
  21. package/dist/data-table/pagination.js.map +1 -1
  22. package/dist/data-table/query-control.d.cts +1 -1
  23. package/dist/data-table/query-control.d.ts +1 -1
  24. package/dist/data-table/types.cjs.map +1 -1
  25. package/dist/data-table/types.d.cts +1 -1
  26. package/dist/data-table/types.d.ts +1 -1
  27. package/dist/data-table/url-state.d.cts +1 -1
  28. package/dist/data-table/url-state.d.ts +1 -1
  29. package/dist/data-table/xlsx.d.cts +1 -1
  30. package/dist/data-table/xlsx.d.ts +1 -1
  31. package/dist/index.cjs +8 -0
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +1 -1
  34. package/dist/index.d.ts +1 -1
  35. package/dist/index.js +8 -0
  36. package/dist/index.js.map +1 -1
  37. package/dist/tap-target.css +11 -2
  38. package/dist/{types-DB30aCHu.d.ts → types-D_UZxZC5.d.ts} +4 -0
  39. package/dist/{types-C2yaTspG.d.cts → types-n8d2I1Gu.d.cts} +4 -0
  40. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/button.tsx","../../src/cn.ts","../../src/tooltip.tsx","../../src/motion.ts","../../src/portal-container.tsx","../../src/data-table/icons.tsx","../../src/select.tsx","../../src/icons.tsx","../../src/data-table/host.tsx","../../src/data-table/pagination.tsx"],"sourcesContent":["\"use client\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nimport { cn } from \"./cn\";\n\nexport const buttonVariants = cva(\n \"inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-0 disabled:pointer-events-none disabled:opacity-50 active:scale-[0.98] [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n /**\n * An explicit spelling of `default`, identical by construction. It is\n * not decoration: matrx-frontend's `ButtonMine` fork carried it, ~17\n * call sites say `variant=\"primary\"`, and the alternative to keeping\n * the word was a host shim translating a prop — the massage C22 bans.\n */\n primary: \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90\",\n /** The affirmative twin of `destructive` — confirm, approve, publish. */\n success:\n \"bg-success text-success-foreground shadow-sm hover:bg-success/90\",\n outline:\n \"border border-border bg-card shadow-sm hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n subtle:\n \"border border-transparent bg-muted/50 text-foreground hover:border-border hover:bg-muted\",\n },\n /**\n * ONE size scale, xs → 3xl, plus the two icon boxes. The top and bottom\n * of the scale came in from matrx-frontend's `ButtonMine` fork (2026-09-07):\n * a dense toolbar needs `xs`, and a marketing/hero call to action needs\n * `xl`+. A host that has to reach outside this scale forks the button,\n * which is exactly how `ButtonMine` was born.\n */\n size: {\n xs: \"h-6 rounded-md px-1 text-xs\",\n sm: \"h-8 rounded-md px-3 text-xs\",\n default: \"h-9 px-4 py-2\",\n /** An explicit spelling of `default` (the fork's middle rung). */\n md: \"h-9 px-4 py-2\",\n lg: \"h-10 rounded-md px-6\",\n xl: \"h-12 px-8 py-3 text-base\",\n \"2xl\": \"h-14 px-10 py-3 text-base\",\n \"3xl\": \"h-16 px-12 py-3 text-base\",\n icon: \"h-9 w-9\",\n \"icon-sm\": \"h-7 w-7\",\n /** A circular icon box — an avatar-shaped control, not a square one. */\n roundIcon: \"h-8 w-8 rounded-full p-0\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Component = asChild ? Slot : \"button\";\n return (\n <Component\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n />\n );\n },\n);\nButton.displayName = \"Button\";\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\n/**\n * Tooltip — the ONE tooltip in the fleet.\n *\n * THE COLLAPSE (0.6.0). Two implementations existed: matrx-frontend's\n * `components/ui/tooltip.tsx` (182 import sites) and `@ai-matrx/tap-target`'s\n * `src/tooltip.tsx` — the latter an explicit inlined PORT of the former,\n * carrying a header that said so. tap-target shipped it only because its ~60\n * tap buttons need a tooltip and no shared package owned one; four repos then\n * adopted `TooltipProvider` from tap-target. That made tap-target — a\n * button-geometry package — the accidental owner of a design-system primitive,\n * with a second copy living in the biggest host.\n *\n * A tooltip is a design-system surface, so it lives here. tap-target now takes\n * `@ai-matrx/design-system` as an ordinary sibling dependency and imports this\n * file; its own copy is deleted, and its re-export removed. The DAG already\n * ordered design-system before tap-target, so no cycle is introduced.\n *\n * BEHAVIOUR is matrx-frontend's, verbatim, including the ruling both copies\n * carried in prose:\n *\n * 1. THE ROOT RENDERS UNCONDITIONALLY — no hydration mount gate. The gate the\n * host wrapper once carried (\"Radix generates dynamic aria-controls ids that\n * differ between SSR and client\") was false: Radix ids come from React's\n * SSR-stable `useId`. It was actively harmful — a Trigger wraps\n * ALWAYS-VISIBLE content, so `return null` deleted that subtree from SSR and\n * the first client paint.\n *\n * 2. THE SURFACE IS NEUTRAL, NOT BRANDED. Popover tokens, not `bg-primary`:\n * rich tooltip content using `text-muted-foreground` was illegible on a\n * brand-coloured background in one theme or the other.\n *\n * SEAM INVERSION. The host resolved nested portal targets through\n * `useNestedPortalContainer` (an app hook wired to its dialog + window-panel\n * systems); tap-target's port dropped that seam entirely and always portalled\n * to `document.body` — which is why a tooltip inside a popped-out panel landed\n * in the wrong window. Here it is the package's `PortalContainerProvider`\n * seam: an explicit `container` prop wins, then the injected container, then\n * `document.body`. Both prior behaviours are reachable; neither is forked.\n */\n\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\nimport * as React from \"react\";\n\nimport { cn } from \"./cn\";\nimport { MOTION_POPPER } from \"./motion\";\nimport { usePortalContainer } from \"./portal-container\";\n\n/**\n * Mount once near the app root. Every tooltip in the tree shares its\n * `delayDuration` / `skipDelayDuration` timing.\n */\nconst TooltipProvider = TooltipPrimitive.Provider;\n\nconst Tooltip = TooltipPrimitive.Root;\n\nconst TooltipTrigger = TooltipPrimitive.Trigger;\n\nexport interface TooltipContentProps\n extends React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content> {\n /**\n * Explicit portal target; wins over the injected `PortalContainerProvider`\n * value. Pass `null` to force `document.body`.\n */\n container?: HTMLElement | null;\n /**\n * Package-owned open/close motion. Default `true`. Pass `false` for a\n * surface that must appear instantly. It is NOT the reduced-motion switch;\n * `styles.css` already honours `prefers-reduced-motion`.\n */\n animated?: boolean;\n}\n\nconst TooltipContent = React.forwardRef<\n React.ComponentRef<typeof TooltipPrimitive.Content>,\n TooltipContentProps\n>(({ className, sideOffset = 4, container, animated = true, ...props }, ref) => {\n const resolved = usePortalContainer(container);\n return (\n <TooltipPrimitive.Portal container={resolved ?? null}>\n <TooltipPrimitive.Content\n ref={ref}\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"z-[10001] overflow-hidden rounded-md border border-border bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-md\",\n animated && MOTION_POPPER,\n className,\n )}\n {...props}\n />\n </TooltipPrimitive.Portal>\n );\n});\nTooltipContent.displayName = TooltipPrimitive.Content.displayName;\n\nexport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };\n","/**\n * THE MOTION CONTRACT (0.10.0) — the class names every animated surface in\n * this package puts on the DOM, in ONE place.\n *\n * Why a module and not ten inline strings: the sweep that produced this file\n * found the same defect ten times over, and it was invisible each time\n * because each primitive spelled its animation out by hand. Ten hand-written\n * copies of `data-[state=open]:animate-in data-[state=closed]:animate-out\n * data-[state=closed]:fade-out-0 …` meant ten chances to reach for a utility\n * nothing in the package defines — which is exactly what happened. A single\n * exported constant per motion SHAPE means the next primitive cannot invent\n * an eleventh spelling, and `styles.test.ts` can prove every one of them\n * resolves to a rule in the shipped stylesheet.\n *\n * Every rule these name lives in `styles.css` under the package's own\n * keyframes. NONE of them is a Tailwind utility, and none requires a host\n * plugin — see that file's header for the measurement that made this\n * necessary.\n */\n\n/** Modal scrims: Dialog, AlertDialog, Sheet, CommandDialog. Fade only. */\nexport const MOTION_OVERLAY = \"matrx-motion-overlay\";\n\n/** The centred dialog card. Fades and scales; centring is not its business. */\nexport const MOTION_DIALOG = \"matrx-motion-dialog\";\n\n/**\n * THE CENTRING OF A CENTRED DIALOG CARD — package-owned, in the `translate`\n * property, and NEVER a Tailwind `translate-x-[-50%] translate-y-[-50%]` pair.\n *\n * Those utilities do not compile to the same thing in every host: Tailwind v3\n * writes them into `transform`, Tailwind v4 writes them into the independent\n * `translate` property, which COMPOSES with `transform` instead of being\n * replaced by it. 0.10.0's keyframes restated the centring inside `transform`,\n * which was harmless on v3 and doubled the centring on v4 — the card flew in\n * from off the top-left of the viewport for the animation's whole duration and\n * snapped into place at the end (fixed in 0.10.1).\n *\n * Owning it here means one spelling that reads the same on both, and it frees\n * `transform` so the keyframes carry ONLY the delta. Put this on every centred\n * surface UNCONDITIONALLY — it is geometry, so unlike {@link MOTION_DIALOG} it\n * must survive `animated={false}`. Its rule ships in `styles.css`.\n */\nexport const CENTERED_DIALOG = \"matrx-dialog-centered\";\n\n/**\n * The resting gap between a `popper`-positioned surface and its trigger, for\n * the primitives that want one (today: `Select`). Same law and same reason as\n * {@link CENTERED_DIALOG} — a position an animated surface holds AT REST is\n * the `translate` property's job, never a Tailwind translate utility, because\n * those land in `transform` on a v3 host and in `translate` on a v4 one while\n * the keyframes animate `transform` either way. Sizes from\n * `--matrx-popper-offset`; keys off Radix's `data-side`.\n */\nexport const POPPER_OFFSET = \"matrx-popper-offset\";\n\n/** The mobile Dialog / CommandDialog bottom sheet. Slides up and fades. */\nexport const MOTION_BOTTOM_SHEET = \"matrx-motion-bottom-sheet\";\n\n/**\n * Radix-popper surfaces: Popover, DropdownMenu, ContextMenu, HoverCard,\n * Select, Tooltip. Reads `--radix-popper-transform-origin` so the surface\n * grows out of its trigger, and `data-side` so it travels from it.\n */\nexport const MOTION_POPPER = \"matrx-motion-popper\";\n\n/** Edge sheets, one class per `sheetVariants` side. */\nexport const MOTION_SHEET = {\n top: \"matrx-motion-sheet-top\",\n bottom: \"matrx-motion-sheet-bottom\",\n left: \"matrx-motion-sheet-left\",\n right: \"matrx-motion-sheet-right\",\n center: \"matrx-motion-sheet-center\",\n} as const;\n\n/** Skeleton's breathing loop. */\nexport const MOTION_PULSE = \"matrx-pulse\";\n\n/** The spinner loop, for every inline busy indicator in the package. */\nexport const MOTION_SPIN = \"matrx-spin\";\n\n/**\n * Every motion class the package ships, for the guards. If a rule for one of\n * these is missing from `styles.css`, a component animates in no consumer and\n * says nothing about it — the C26 failure this list exists to make loud.\n */\nexport const ALL_MOTION_CLASSES = [\n MOTION_OVERLAY,\n MOTION_DIALOG,\n MOTION_BOTTOM_SHEET,\n MOTION_POPPER,\n ...Object.values(MOTION_SHEET),\n MOTION_PULSE,\n MOTION_SPIN,\n] as const;\n\n/**\n * The host-plugin utilities this package is forbidden to emit. They are\n * supplied by `tailwindcss-animate` / `tw-animate-css`, which is a HOST CSS\n * entry concern a package cannot declare a dependency on: three of the four\n * AI Matrx consumers never loaded it, so every surface wearing these appeared\n * with no animation and no error. `styles.test.ts` fails the build if one\n * comes back.\n */\nexport const FORBIDDEN_HOST_MOTION_UTILITIES = [\n \"animate-in\",\n \"animate-out\",\n \"fade-in\",\n \"fade-out\",\n \"zoom-in\",\n \"zoom-out\",\n \"slide-in-from\",\n \"slide-out-to\",\n \"animate-accordion\",\n \"animate-slide-down\",\n \"animate-slide-up\",\n \"animate-pulse\",\n \"animate-spin\",\n] as const;\n","\"use client\";\n\n/**\n * Injected portal-container seam.\n *\n * The matrx-frontend original resolved nested portal targets through\n * `useNestedPortalContainer` (explicit prop > dialog content > popout body >\n * document.body) — a host-shaped hook wired to that app's dialog and\n * window-panel systems. The package inverts the seam: hosts provide the\n * resolved container through `PortalContainerProvider`; an explicit\n * `container` prop on a component still wins, and with neither the portal\n * falls through to `document.body` (Radix default). Priority semantics are\n * unchanged from the original.\n */\n\nimport * as React from \"react\";\n\n// Shared identity across independently bundled public entrypoints/loaders.\nconst CONTEXT_SLOT = Symbol.for(\"ai-matrx.design-system.portal-container-context\");\nconst contextRegistry = globalThis as typeof globalThis & { [CONTEXT_SLOT]?: React.Context<HTMLElement | null | undefined> };\nconst PortalContainerContext = contextRegistry[CONTEXT_SLOT] ??= React.createContext<HTMLElement | null | undefined>(undefined);\n\nexport interface PortalContainerProviderProps {\n /** Where nested Radix portals (Popover, etc.) should mount. `null`/`undefined` → document.body. */\n container: HTMLElement | null | undefined;\n children: React.ReactNode;\n}\n\nexport function PortalContainerProvider({\n container,\n children,\n}: PortalContainerProviderProps) {\n return (\n <PortalContainerContext.Provider value={container ?? undefined}>\n {children}\n </PortalContainerContext.Provider>\n );\n}\n\n/**\n * Resolve a portal target: explicit prop (including an explicit `null`,\n * meaning \"the default body\") beats the injected container.\n */\nexport function usePortalContainer(\n explicit?: HTMLElement | null,\n): HTMLElement | undefined {\n const injected = React.useContext(PortalContainerContext);\n\n if (explicit !== undefined) {\n return explicit ?? undefined;\n }\n\n return injected ?? undefined;\n}\n","import type { SVGProps } from \"react\";\n\ntype IconProps = SVGProps<SVGSVGElement>;\nfunction Icon({ children, ...props }: IconProps) {\n return <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\" {...props}>{children}</svg>;\n}\nconst path = <path d=\"M4 12h16M12 4v16\" />;\nexport const ChevronLeft = (p: IconProps) => <Icon {...p}><path d=\"m15 18-6-6 6-6\" /></Icon>;\nexport const ChevronRight = (p: IconProps) => <Icon {...p}><path d=\"m9 18 6-6-6-6\" /></Icon>;\nexport const ChevronDown = (p: IconProps) => <Icon {...p}><path d=\"m6 9 6 6 6-6\" /></Icon>;\nexport const ArrowDown = (p: IconProps) => <Icon {...p}><path d=\"M12 4v16m-6-6 6 6 6-6\" /></Icon>;\nexport const ArrowUp = (p: IconProps) => <Icon {...p}><path d=\"M12 20V4m-6 6 6-6 6 6\" /></Icon>;\nexport const ArrowUpDown = (p: IconProps) => <Icon {...p}><path d=\"M12 4v16m-4-12 4-4 4 4m-8 8 4 4 4-4\" /></Icon>;\nexport const Check = (p: IconProps) => <Icon {...p}><path d=\"m5 12 4 4L19 6\" /></Icon>;\nexport const X = (p: IconProps) => <Icon {...p}><path d=\"M6 6l12 12M18 6 6 18\" /></Icon>;\nexport const Search = (p: IconProps) => <Icon {...p}><circle cx=\"11\" cy=\"11\" r=\"6\" /><path d=\"m16 16 4 4\" /></Icon>;\nexport const Plus = (p: IconProps) => <Icon {...p}>{path}</Icon>;\nexport const Minus = (p: IconProps) => <Icon {...p}><path d=\"M4 12h16\" /></Icon>;\nexport const Eraser = (p: IconProps) => <Icon {...p}><path d=\"m16 3 5 5-11 11H5l-3-3L13 5l3-2Z M8 10l6 6 M10 19h12\" /></Icon>;\nexport const GripVertical = (p: IconProps) => <Icon {...p}><circle cx=\"9\" cy=\"6\" r=\"1\" /><circle cx=\"15\" cy=\"6\" r=\"1\" /><circle cx=\"9\" cy=\"12\" r=\"1\" /><circle cx=\"15\" cy=\"12\" r=\"1\" /><circle cx=\"9\" cy=\"18\" r=\"1\" /><circle cx=\"15\" cy=\"18\" r=\"1\" /></Icon>;\n/** lucide `sliders-horizontal` — used for the table column manager. */\nexport const SlidersHorizontal = (p: IconProps) => <Icon {...p}>\n <path d=\"M21 4h-7M10 4H3M21 12h-9M8 12H3M21 20h-5M12 20H3M14 2v4M8 10v4M16 18v4\" />\n</Icon>;\nexport const Trash2 = (p: IconProps) => <Icon {...p}><path d=\"M4 7h16M10 11v6M14 11v6M9 7l1-2h4l1 2M6 7l1 13h10l1-13\" /></Icon>;\n/**\n * Spinner-only incomplete arc. Never a resting glyph — at rest this reads as a\n * broken half-circle. Pair it with `animate-spin` / `matrx-spin` only while\n * work is actually running. Refresh controls use `RefreshControlIcon`.\n */\nexport const Loader2 = (p: IconProps) => <Icon {...p}><path d=\"M20 12a8 8 0 1 1-2.3-5.7\" /></Icon>;\n/** lucide `refresh-cw` — the resting refresh arrows. */\nexport const RefreshCw = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\" />\n <path d=\"M21 3v5h-5\" />\n <path d=\"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\" />\n <path d=\"M8 16H3v5\" />\n </Icon>\n);\n/** Refresh affordance: arrows at rest, spinner only while busy. */\nexport function RefreshControlIcon({\n spinning = false,\n className,\n ...props\n}: IconProps & { spinning?: boolean }) {\n if (spinning) {\n return (\n <Loader2\n className={[className, \"animate-spin\"].filter(Boolean).join(\" \")}\n {...props}\n />\n );\n }\n return <RefreshCw className={className} {...props} />;\n}\nexport const Save = (p: IconProps) => <Icon {...p}><path d=\"M5 3h12l2 2v16H5zM8 3v6h8V3M8 21v-7h8v7\" /></Icon>;\nexport const Pencil = (p: IconProps) => <Icon {...p}><path d=\"m4 20 4-1 11-11-3-3L5 16l-1 4z\" /></Icon>;\nexport const Eye = (p: IconProps) => <Icon {...p}><path d=\"M2 12s3-6 10-6 10 6 10 6-3 6-10 6S2 12 2 12z\" /><circle cx=\"12\" cy=\"12\" r=\"2\" /></Icon>;\nexport const PanelRight = (p: IconProps) => <Icon {...p}><rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" /><path d=\"M15 4v16\" /></Icon>;\nexport const PanelRightOpen = PanelRight;\nexport const WholeWord = (p: IconProps) => <Icon {...p}><path d=\"M4 6l3 12 3-8 3 8 3-12M17 15h4\" /></Icon>;\nexport const ExternalLink = (p: IconProps) => <Icon {...p}><path d=\"M14 4h6v6M20 4l-9 9M19 13v6H5V5h6\" /></Icon>;\nexport const Copy = (p: IconProps) => <Icon {...p}><rect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2\" /><path d=\"M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3\" /></Icon>;\nexport const Lightbulb = (p: IconProps) => <Icon {...p}><path d=\"M9 18h6M10 22h4M8 14a6 6 0 1 1 8 0c-1 1-1 2-1 3H9c0-1 0-2-1-3z\" /></Icon>;\nexport const ShieldOff = (p: IconProps) => <Icon {...p}><path d=\"m3 3 18 18M12 3l7 3v5c0 4-3 7-7 9-4-2-7-5-7-9V6l4-2\" /></Icon>;\nexport const ListFilter = SlidersHorizontal;\nexport const ListX = X;\n\nexport const ChevronsLeft = (p: IconProps) => <Icon {...p}><path d=\"m11 18-6-6 6-6m8 12-6-6 6-6\" /></Icon>;\nexport const ChevronsRight = (p: IconProps) => <Icon {...p}><path d=\"m5 18 6-6-6-6m8 12 6-6-6-6\" /></Icon>;\n","\"use client\";\n\n/**\n * Select — ported verbatim from matrx-frontend `components/ui/select.tsx`.\n *\n * Seam inversions:\n * - The host's `useNestedPortalContainer` (dialog/popout aware) becomes the\n * injected `PortalContainerProvider` seam (`portal-container.tsx`); the\n * explicit `container` prop keeps top priority, exactly as before.\n * - `ChevronDownIcon` / `ChevronUpIcon` / `CheckIcon` come from the package's\n * inlined SVGs (C19), not @radix-ui/react-icons — same glyphs, same\n * viewBoxes. (The origin also imported `CaretSortIcon` without ever using\n * it; the dead import is not carried along.)\n *\n * THE ROOT RENDERS UNCONDITIONALLY — no mount gate. This wrapper used to defer\n * rendering until after hydration (\"Radix generates dynamic aria-controls ids\n * that differ between SSR and client\"), and that justification was false:\n * Radix ids come from React's SSR-stable `useId` (verified against\n * @radix-ui/react-select 2.3.1 / react-id 1.1.2). The gate was actively\n * harmful — it deleted the ALWAYS-VISIBLE select trigger (a form control)\n * from SSR and the first client paint.\n */\n\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nimport { cn } from \"./cn\";\nimport { MOTION_POPPER, POPPER_OFFSET } from \"./motion\";\nimport {\n CheckIcon,\n RadixChevronDownIcon,\n RadixChevronUpIcon,\n} from \"./icons\";\nimport { usePortalContainer } from \"./portal-container\";\n\nexport const Select = SelectPrimitive.Root;\n\nexport const SelectGroup = SelectPrimitive.Group;\n\nexport const SelectValue = SelectPrimitive.Value;\n\nexport const selectTriggerVariants = cva(\n \"flex w-full items-center justify-between gap-2 whitespace-nowrap rounded-md border border-border bg-card text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground transition-colors hover:bg-accent hover:border-accent-foreground/20 focus:outline-none focus:ring-1 focus:ring-primary/30 focus:border-primary/40 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:min-w-0 [&>span]:line-clamp-1\",\n {\n variants: {\n size: {\n sm: \"h-7 px-2 py-1 text-xs\",\n default: \"h-9 px-3 py-1\",\n lg: \"h-10 px-3 py-2\",\n },\n },\n defaultVariants: {\n size: \"default\",\n },\n },\n);\n\nexport interface SelectTriggerProps\n extends\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>,\n VariantProps<typeof selectTriggerVariants> {\n hideArrow?: boolean;\n}\n\nexport const SelectTrigger = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Trigger>,\n SelectTriggerProps\n>(({ className, children, hideArrow = false, size, ...props }, ref) => (\n <SelectPrimitive.Trigger\n ref={ref}\n className={cn(selectTriggerVariants({ size, className }))}\n {...props}\n >\n {children}\n {!hideArrow && (\n <SelectPrimitive.Icon asChild>\n <RadixChevronDownIcon className=\"h-4 w-4 shrink-0 opacity-50\" />\n </SelectPrimitive.Icon>\n )}\n </SelectPrimitive.Trigger>\n));\nSelectTrigger.displayName = SelectPrimitive.Trigger.displayName;\n\nexport const SelectScrollUpButton = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.ScrollUpButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollUpButton\n ref={ref}\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className,\n )}\n {...props}\n >\n <RadixChevronUpIcon />\n </SelectPrimitive.ScrollUpButton>\n));\nSelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;\n\nexport const SelectScrollDownButton = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.ScrollDownButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollDownButton\n ref={ref}\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className,\n )}\n {...props}\n >\n <RadixChevronDownIcon />\n </SelectPrimitive.ScrollDownButton>\n));\nSelectScrollDownButton.displayName =\n SelectPrimitive.ScrollDownButton.displayName;\n\nexport interface SelectContentProps\n extends React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content> {\n /** Explicit portal target; wins over the injected container. */\n container?: HTMLElement | null;\n /**\n * Package-owned open/close motion. Default `true`. Pass `false` for a\n * surface that must appear instantly. It is NOT the reduced-motion switch;\n * `styles.css` already honours `prefers-reduced-motion`.\n */\n animated?: boolean;\n}\n\nexport const SelectContent = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Content>,\n SelectContentProps\n>(\n (\n {\n className,\n children,\n position = \"popper\",\n container,\n animated = true,\n ...props\n },\n ref,\n ) => {\n const portalContainer = usePortalContainer(container);\n return (\n <SelectPrimitive.Portal container={portalContainer}>\n <SelectPrimitive.Content\n ref={ref}\n className={cn(\n \"relative z-[10001] max-h-96 min-w-[8rem] max-w-[calc(100vw-2rem)] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md\",\n animated && MOTION_POPPER,\n // The resting gap from the trigger. It is the `translate` property\n // (POPPER_OFFSET), never Tailwind translate utilities: those compose\n // with `transform` on a v4 host and are REPLACED by it on a v3 one,\n // so on v3 the animation ate the gap and the surface snapped 4px at\n // the end. Same law as the centred dialog card — see motion.ts.\n position === \"popper\" && POPPER_OFFSET,\n className,\n )}\n position={position}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n \"max-w-full overflow-y-auto p-0.5\",\n position === \"popper\" &&\n \"w-full min-w-[var(--radix-select-trigger-width)] max-h-[var(--radix-select-content-available-height)]\",\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n );\n});\nSelectContent.displayName = SelectPrimitive.Content.displayName;\n\nexport const SelectLabel = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Label\n ref={ref}\n className={cn(\"px-2 py-1.5 text-sm font-semibold\", className)}\n {...props}\n />\n));\nSelectLabel.displayName = SelectPrimitive.Label.displayName;\n\nexport const SelectItem = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item> & {\n /**\n * Secondary line shown under the label IN THE LIST ONLY. Rendered outside\n * Radix `ItemText` on purpose: everything inside `ItemText` is what the\n * closed trigger displays, so a description passed as `children` gets\n * squeezed into the fixed-height trigger and clipped. This prop keeps the\n * trigger to the one-line label while the open list shows both lines.\n */\n description?: React.ReactNode;\n }\n>(({ className, children, description, ...props }, ref) => (\n <SelectPrimitive.Item\n ref={ref}\n className={cn(\n \"relative flex w-full min-w-0 cursor-default select-none rounded-sm py-1 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n description ? \"flex-col items-start gap-0.5 py-1.5\" : \"items-center\",\n className,\n )}\n {...props}\n >\n <span className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"h-4 w-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <span className=\"min-w-0 whitespace-normal break-words [overflow-wrap:anywhere]\">\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </span>\n {description ? (\n <span className=\"block min-w-0 break-words text-xs leading-snug text-muted-foreground [overflow-wrap:anywhere]\">\n {description}\n </span>\n ) : null}\n </SelectPrimitive.Item>\n));\nSelectItem.displayName = SelectPrimitive.Item.displayName;\n\nexport const SelectSeparator = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Separator\n ref={ref}\n className={cn(\"-mx-1 my-1 h-px bg-muted\", className)}\n {...props}\n />\n));\nSelectSeparator.displayName = SelectPrimitive.Separator.displayName;\n","/**\n * Internal inlined SVG icons (policy C19: no icon-library dependency, ever).\n *\n * Each icon is copied from the exact glyph the ported originals rendered:\n * lucide-react's Loader2 / ChevronLeft / ChevronRight / MoreHorizontal and\n * @radix-ui/react-icons' Cross2Icon. Same viewBoxes, same paths, same default\n * stroke geometry — a host swapping the import sees pixel-identical output.\n *\n * Not exported from the package entry; components consume them directly.\n */\n\nimport * as React from \"react\";\n\ntype IconProps = React.SVGAttributes<SVGSVGElement>;\n\nfunction lucideProps(props: IconProps): React.SVGAttributes<SVGSVGElement> {\n return {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n \"aria-hidden\": true,\n ...props,\n };\n}\n\n/**\n * lucide `loader-2` — the spinner glyph. Callers add `matrx-spin`.\n * Never a resting icon: at rest this incomplete arc reads as a broken\n * half-circle. Refresh controls use arrows, then swap to this only while busy.\n */\nexport function Loader2Icon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n );\n}\n\n/** lucide `chevron-left`. */\nexport function ChevronLeftIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n );\n}\n\n/** lucide `chevron-right`. */\nexport function ChevronRightIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n );\n}\n\n/** lucide `chevron-down` — the disclosure's open glyph. */\nexport function ChevronDownIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n );\n}\n\n/** lucide `archive` — the archived-rows glyph (ArchivedDisclosure). */\nexport function ArchiveIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <rect width=\"20\" height=\"5\" x=\"2\" y=\"3\" rx=\"1\" />\n <path d=\"M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8\" />\n <path d=\"M10 12h4\" />\n </svg>\n );\n}\n\n/** lucide `more-horizontal` — the kebab/ellipsis glyph. */\nexport function MoreHorizontalIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"19\" cy=\"12\" r=\"1\" />\n <circle cx=\"5\" cy=\"12\" r=\"1\" />\n </svg>\n );\n}\n\n/** lucide `check` — the selected-row tick (CreatablePicker). */\nexport function LucideCheckIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n );\n}\n\n/** lucide `chevrons-up-down` — the combobox trigger glyph. */\nexport function ChevronsUpDownIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"m7 15 5 5 5-5\" />\n <path d=\"m7 9 5-5 5 5\" />\n </svg>\n );\n}\n\n/** lucide `external-link` — the manage-in-new-tab glyph. */\nexport function ExternalLinkIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"M15 3h6v6\" />\n <path d=\"M10 14 21 3\" />\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n </svg>\n );\n}\n\n/** lucide `lock` — the platform-governed vocabulary glyph. */\nexport function LockIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <rect width=\"18\" height=\"11\" x=\"3\" y=\"11\" rx=\"2\" ry=\"2\" />\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\" />\n </svg>\n );\n}\n\n/** lucide `plus` — the create/add glyph. */\nexport function PlusIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"M5 12h14\" />\n <path d=\"M12 5v14\" />\n </svg>\n );\n}\n\n/** lucide `x` — the dialog close glyph (host dialog module used lucide X). */\nexport function XIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n\n/**\n * @radix-ui/react-icons components default to width/height 15 — the bare\n * `<ChevronUpIcon />` renders in Select's scroll buttons rely on it.\n */\nfunction radixProps(props: IconProps): React.SVGAttributes<SVGSVGElement> {\n return {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 15 15\",\n width: 15,\n height: 15,\n fill: \"none\",\n \"aria-hidden\": true,\n ...props,\n };\n}\n\n/** @radix-ui/react-icons `MagnifyingGlassIcon` — the command search glyph. */\nexport function MagnifyingGlassIcon(props: IconProps) {\n return (\n <svg {...radixProps(props)}>\n <path\n d=\"M10 6.5C10 8.433 8.433 10 6.5 10C4.567 10 3 8.433 3 6.5C3 4.567 4.567 3 6.5 3C8.433 3 10 4.567 10 6.5ZM9.30884 10.0159C8.53901 10.6318 7.56251 11 6.5 11C4.01472 11 2 8.98528 2 6.5C2 4.01472 4.01472 2 6.5 2C8.98528 2 11 4.01472 11 6.5C11 7.56251 10.6318 8.53901 10.0159 9.30884L12.8536 12.1464C13.0488 12.3417 13.0488 12.6583 12.8536 12.8536C12.6583 13.0488 12.3417 13.0488 12.1464 12.8536L9.30884 10.0159Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n/** @radix-ui/react-icons `CheckIcon` — the select item indicator glyph. */\nexport function CheckIcon(props: IconProps) {\n return (\n <svg {...radixProps(props)}>\n <path\n d=\"M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n/**\n * @radix-ui/react-icons `DividerHorizontalIcon` — the INDETERMINATE checkbox\n * glyph. Radix renders the indicator for both `true` and `\"indeterminate\"`, so\n * a half-selected \"select all\" that shows a full check states something false;\n * the two states get different glyphs on purpose.\n */\nexport function DividerHorizontalIcon(props: IconProps) {\n return (\n <svg {...radixProps(props)}>\n <path\n d=\"M2 7.5C2 7.22386 2.22386 7 2.5 7H12.5C12.7761 7 13 7.22386 13 7.5C13 7.77614 12.7761 8 12.5 8H2.5C2.22386 8 2 7.77614 2 7.5Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n/** @radix-ui/react-icons `DotFilledIcon` — the menu radio-item indicator. */\nexport function DotFilledIcon(props: IconProps) {\n return (\n <svg {...radixProps(props)}>\n <path\n d=\"M9.875 7.5C9.875 8.81168 8.81168 9.875 7.5 9.875C6.18832 9.875 5.125 8.81168 5.125 7.5C5.125 6.18832 6.18832 5.125 7.5 5.125C8.81168 5.125 9.875 6.18832 9.875 7.5Z\"\n fill=\"currentColor\"\n />\n </svg>\n );\n}\n\n/** @radix-ui/react-icons `ChevronRightIcon` — the submenu-trigger glyph. */\nexport function RadixChevronRightIcon(props: IconProps) {\n return (\n <svg {...radixProps(props)}>\n <path\n d=\"M6.1584 3.13508C6.35985 2.94621 6.67627 2.95642 6.86514 3.15788L10.6151 7.15788C10.7954 7.3502 10.7954 7.64949 10.6151 7.84182L6.86514 11.8418C6.67627 12.0433 6.35985 12.0535 6.1584 11.8646C5.95694 11.6757 5.94673 11.3593 6.1356 11.1579L9.565 7.49985L6.1356 3.84182C5.94673 3.64036 5.95694 3.32394 6.1584 3.13508Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n/** @radix-ui/react-icons `ChevronDownIcon` — the select trigger/scroll glyph. */\nexport function RadixChevronDownIcon(props: IconProps) {\n return (\n <svg {...radixProps(props)}>\n <path\n d=\"M3.13523 6.15803C3.3241 5.95657 3.64052 5.94637 3.84197 6.13523L7.5 9.56464L11.158 6.13523C11.3595 5.94637 11.6759 5.95657 11.8648 6.15803C12.0536 6.35949 12.0434 6.67591 11.842 6.86477L7.84197 10.6148C7.64964 10.7951 7.35036 10.7951 7.15803 10.6148L3.15803 6.86477C2.95657 6.67591 2.94637 6.35949 3.13523 6.15803Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n/** @radix-ui/react-icons `ChevronUpIcon` — the select scroll-up glyph. */\nexport function RadixChevronUpIcon(props: IconProps) {\n return (\n <svg {...radixProps(props)}>\n <path\n d=\"M3.13523 8.84197C3.3241 9.04343 3.64052 9.05363 3.84197 8.86477L7.5 5.43536L11.158 8.86477C11.3595 9.05363 11.6759 9.04343 11.8648 8.84197C12.0536 8.64051 12.0434 8.32409 11.842 8.13523L7.84197 4.38523C7.64964 4.20492 7.35036 4.20492 7.15803 4.38523L3.15803 8.13523C2.95657 8.32409 2.94637 8.64051 3.13523 8.84197Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n/** @radix-ui/react-icons `Cross2Icon` — the dialog/sheet close glyph. */\nexport function Cross2Icon(props: IconProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 15 15\"\n fill=\"none\"\n aria-hidden\n {...props}\n >\n <path\n d=\"M11.7816 4.03157C12.0062 3.80702 12.0062 3.44295 11.7816 3.2184C11.5571 2.99385 11.193 2.99385 10.9685 3.2184L7.50005 6.68682L4.03164 3.2184C3.80708 2.99385 3.44301 2.99385 3.21846 3.2184C2.99391 3.44295 2.99391 3.80702 3.21846 4.03157L6.68688 7.49999L3.21846 10.9684C2.99391 11.193 2.99391 11.557 3.21846 11.7816C3.44301 12.0061 3.80708 12.0061 4.03164 11.7816L7.50005 8.31316L10.9685 11.7816C11.193 12.0061 11.5571 12.0061 11.7816 11.7816C12.0062 11.557 12.0062 11.193 11.7816 10.9684L8.31322 7.49999L11.7816 4.03157Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n/**\n * @radix-ui/react-icons `DragHandleDots2Icon` — the grip on `ResizableHandle`.\n * Inlined per C19: this package depends on no icon library.\n */\nexport function DragHandleDots2Icon(props: IconProps) {\n return (\n <svg {...radixProps(props)}>\n <path\n d=\"M4.5 2.5C5.05228 2.5 5.5 2.05228 5.5 1.5C5.5 0.947715 5.05228 0.5 4.5 0.5C3.94772 0.5 3.5 0.947715 3.5 1.5C3.5 2.05228 3.94772 2.5 4.5 2.5ZM4.5 6.5C5.05228 6.5 5.5 6.05229 5.5 5.5C5.5 4.94771 5.05228 4.5 4.5 4.5C3.94772 4.5 3.5 4.94771 3.5 5.5C3.5 6.05229 3.94772 6.5 4.5 6.5ZM5.5 9.5C5.5 10.0523 5.05228 10.5 4.5 10.5C3.94772 10.5 3.5 10.0523 3.5 9.5C3.5 8.94771 3.94772 8.5 4.5 8.5C5.05228 8.5 5.5 8.94771 5.5 9.5ZM4.5 14.5C5.05228 14.5 5.5 14.0523 5.5 13.5C5.5 12.9477 5.05228 12.5 4.5 12.5C3.94772 12.5 3.5 12.9477 3.5 13.5C3.5 14.0523 3.94772 14.5 4.5 14.5ZM11.5 1.5C11.5 2.05228 11.0523 2.5 10.5 2.5C9.94771 2.5 9.5 2.05228 9.5 1.5C9.5 0.947715 9.94771 0.5 10.5 0.5C11.0523 0.5 11.5 0.947715 11.5 1.5ZM10.5 6.5C11.0523 6.5 11.5 6.05229 11.5 5.5C11.5 4.94771 11.0523 4.5 10.5 4.5C9.94771 4.5 9.5 4.94771 9.5 5.5C9.5 6.05229 9.94771 6.5 10.5 6.5ZM11.5 9.5C11.5 10.0523 11.0523 10.5 10.5 10.5C9.94771 10.5 9.5 10.0523 9.5 9.5C9.5 8.94771 9.94771 8.5 10.5 8.5C11.0523 8.5 11.5 8.94771 11.5 9.5ZM10.5 14.5C11.0523 14.5 11.5 14.0523 11.5 13.5C11.5 12.9477 11.0523 12.5 10.5 12.5C9.94771 12.5 9.5 12.9477 9.5 13.5C9.5 14.0523 9.94771 14.5 10.5 14.5Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n/** lucide `star` — the default-organization badge (OrganizationPicker). */\nexport function StarIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z\" />\n </svg>\n );\n}\n\n/** lucide `building-2` — the organization glyph (OrganizationPicker trigger). */\nexport function Building2Icon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18Z\" />\n <path d=\"M6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2\" />\n <path d=\"M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2\" />\n <path d=\"M10 6h4\" />\n <path d=\"M10 10h4\" />\n <path d=\"M10 14h4\" />\n <path d=\"M10 18h4\" />\n </svg>\n );\n}\n","\"use client\";\nimport { createContext, useContext, type Context, type ComponentType, type ReactNode, type MouseEventHandler } from \"react\";\nimport type { CopyControlProps } from \"./copy-types\";\nimport type { MatrxDataTableDensity, TableSavedViewsProps } from \"./types\";\n\nexport type {\n AgentPayloadInput,\n AiCustomSource,\n AiVariant,\n CopyControlProps,\n CopyExportConfig,\n} from \"./copy-types\";\n\nexport interface TableLinkProps { href: string; children: ReactNode; className?: string; onClick?: MouseEventHandler<HTMLAnchorElement>; }\n/**\n * Host-owned toolbar affordance. The table package keeps operation state and\n * labels; an application can supply its canonical icon-button primitive\n * without making the shared package depend on an application UI package.\n */\nexport interface TableToolbarActionProps { ariaLabel: string; tooltip?: string | undefined; disabled?: boolean | undefined; busy?: boolean | undefined; /** Indicates a selected mutually-exclusive action such as the current page. */ active?: boolean | undefined; onClick: () => void; children: ReactNode; }\nexport interface TableSidePanelProps { title: string; titleNode?: ReactNode; description?: ReactNode; onClose: () => void; defaultWidth?: number; headerActions?: ReactNode; children: ReactNode; }\nexport interface TableWindowPanelProps { id: string; title: string; onClose: () => void; width?: number; height?: number; minWidth?: number; minHeight?: number; actionsRight?: ReactNode; bodyClassName?: string; sidebarDefaultSize?: number; sidebarMinSize?: number; sidebar?: ReactNode; children: ReactNode; }\nexport interface TableEntityRefProps { token: string; id: string; href?: string; children: ReactNode; className?: string; }\nexport interface TablePeekProps { kind: string; id: string; href?: string; onClose: () => void; }\nexport interface TableDoors { href?: string; peekKind?: string; canPeek?: boolean; }\nexport interface MatrxDataTableHost { JsonViewer?: ComponentType<{ data: object | string }>; Link?: ComponentType<TableLinkProps>; CopyControls?: ComponentType<CopyControlProps>; ToolbarAction?: ComponentType<TableToolbarActionProps>; SidePanelSurface?: ComponentType<TableSidePanelProps>; WindowPanel?: ComponentType<TableWindowPanelProps>; EntityRef?: ComponentType<TableEntityRefProps>; resolveEntityDoors?: (token: string, id: string, href?: string | null) => TableDoors | null; ResourcePeek?: ComponentType<TablePeekProps>; SavedViews?: ComponentType<TableSavedViewsProps>; /** Host default; a table's explicit density takes precedence. */ defaultDensity?: MatrxDataTableDensity; notify?: { success(message: string): void; error(message: string): void }; }\n// Public entrypoints are independently bundled in ESM and CJS. The context\n// identity must survive those bundle boundaries; values stay provider-scoped.\nconst HOST_SLOT = Symbol.for(\"ai-matrx.design-system.table-host-context\");\nconst hostRegistry = globalThis as typeof globalThis & { [HOST_SLOT]?: Context<MatrxDataTableHost> };\nconst HostContext = hostRegistry[HOST_SLOT] ??= createContext<MatrxDataTableHost>({});\nexport function MatrxDataTableProvider({ value, children }: { value: MatrxDataTableHost; children: ReactNode }) { return <HostContext.Provider value={value}>{children}</HostContext.Provider>; }\nexport function useMatrxDataTableHost(): MatrxDataTableHost { return useContext(HostContext); }\n","\"use client\";\nimport { Button, type ButtonProps } from \"../button\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../tooltip\";\nimport {\n ChevronsLeft,\n ChevronLeft,\n ChevronsRight,\n ChevronRight,\n} from \"./icons\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../select\";\nimport { cn } from \"../cn\";\nimport { useMatrxDataTableHost, type TableToolbarActionProps } from \"./host\";\nimport type { ComponentType } from \"react\";\n\nexport interface GenericTablePaginationProps {\n totalItems: number;\n itemsPerPage: number;\n currentPage: number;\n onPageChange: (page: number) => void;\n onItemsPerPageChange: (items: number) => void;\n pageSizeOptions?: number[];\n className?: string;\n showItemsPerPageSelect?: boolean;\n showPageInfo?: boolean;\n showPageControls?: boolean;\n maxPagesToShow?: number;\n containerClassName?: string;\n selectContainerClassName?: string;\n infoContainerClassName?: string;\n controlsContainerClassName?: string;\n pageButtonClassName?: string;\n pageActiveButtonClassName?: string;\n navButtonClassName?: string;\n /** Value emitted for the optional All choice. Defaults to the current total. */\n allValue?: number;\n /** Honest label for the optional all-rows choice. */\n allOptionLabel?: string;\n showAllOption?: boolean;\n layoutType?: \"grid\" | \"flex\";\n labelFormat?: (start: number, end: number, total: number) => string;\n compact?: boolean;\n hideEntriesInfo?: boolean;\n /** Keeps progressive local pagination in one stable footer, including at\n * exhaustion. Counts describe rendered rows, not a numbered page. */\n progressive?: { loadedCount?: number; shownCount: number; hasMore: boolean; onShowMore: () => void };\n}\n\nfunction PageNavigationControl({\n label,\n disabledHint,\n visibilityClassName = \"inline-flex\",\n disabled,\n className,\n ...props\n}: ButtonProps & {\n label: string;\n disabledHint: string;\n visibilityClassName?: string;\n}) {\n const button = (\n <Button\n {...props}\n disabled={disabled}\n aria-label={label}\n className={cn(visibilityClassName, className, \"[&_svg]:size-5\")}\n />\n );\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n {disabled ? (\n <span\n className={cn(visibilityClassName, \"rounded-md outline-none focus-visible:ring-2 focus-visible:ring-ring\")}\n tabIndex={0}\n aria-label={`${label} — ${disabledHint.toLowerCase()}`}\n >\n {button}\n </span>\n ) : button}\n </TooltipTrigger>\n <TooltipContent>{disabled ? disabledHint : label}</TooltipContent>\n </Tooltip>\n );\n}\n\nfunction PaginationAction({\n HostAction,\n active = false,\n disabledHint,\n visibilityClassName = \"inline-flex\",\n fallbackClassName,\n ...props\n}: TableToolbarActionProps & {\n HostAction: ComponentType<TableToolbarActionProps> | undefined;\n active?: boolean;\n disabledHint: string;\n visibilityClassName?: string;\n fallbackClassName?: string;\n}) {\n if (HostAction) {\n return (\n <span data-matrx-table-icon-action className={visibilityClassName}>\n <HostAction\n {...props}\n active={active}\n tooltip={props.disabled ? disabledHint : (props.tooltip ?? props.ariaLabel)}\n />\n </span>\n );\n }\n return (\n <PageNavigationControl\n variant=\"outline\"\n size=\"icon\"\n visibilityClassName={visibilityClassName}\n label={props.ariaLabel}\n disabledHint={disabledHint}\n disabled={props.disabled}\n onClick={props.onClick}\n className={cn(\n PAGINATION_ACTION_CLASS,\n active && PAGINATION_ACTIVE_CLASS,\n fallbackClassName,\n )}\n aria-current={active ? \"page\" : undefined}\n data-matrx-table-icon-action\n >\n {props.children}\n </PageNavigationControl>\n );\n}\n\n// Table footers use an actual 44px control shape. A pseudo-element inset into a\n// smaller visual box let the select text and chevron escape its border.\nconst PAGINATION_ACTION_CLASS = \"h-11 w-11 min-h-11 min-w-11 rounded-md border border-border bg-card p-0 text-sm shadow-none hover:bg-accent disabled:opacity-40 [&_svg]:size-5\";\nconst PAGINATION_ACTIVE_CLASS = \"border-primary bg-primary text-primary-foreground hover:bg-primary/90\";\n\nexport default function GenericTablePagination({\n totalItems,\n itemsPerPage,\n currentPage,\n onPageChange,\n onItemsPerPageChange,\n pageSizeOptions = [5, 10, 25, 50, 100],\n className = \"\",\n showItemsPerPageSelect = true,\n showPageInfo = true,\n showPageControls = true,\n maxPagesToShow = 5,\n containerClassName = \"\",\n selectContainerClassName = \"\",\n infoContainerClassName = \"\",\n controlsContainerClassName = \"\",\n pageButtonClassName = \"\",\n pageActiveButtonClassName = \"\",\n navButtonClassName = \"\",\n allValue = totalItems,\n allOptionLabel = \"All\",\n showAllOption = true,\n layoutType = \"grid\",\n labelFormat,\n compact = false,\n hideEntriesInfo = false,\n progressive,\n}: GenericTablePaginationProps) {\n const host = useMatrxDataTableHost();\n const positivePageSizes = pageSizeOptions.filter((size) => size > 0);\n const availablePageSizes =\n itemsPerPage > 0 && !positivePageSizes.includes(itemsPerPage)\n ? [...positivePageSizes, itemsPerPage].sort((a, b) => a - b)\n : positivePageSizes;\n const effectiveItemsPerPage =\n itemsPerPage === 0 ? Math.max(totalItems, 1) : Math.max(itemsPerPage, 1);\n\n const totalPages = Math.max(1, Math.ceil(totalItems / effectiveItemsPerPage));\n\n const getPageNumbers = (limit = maxPagesToShow) => {\n let startPage = Math.max(1, currentPage - Math.floor(limit / 2));\n const endPage = Math.min(totalPages, startPage + limit - 1);\n startPage = Math.max(1, endPage - limit + 1);\n return Array.from(\n { length: endPage - startPage + 1 },\n (_, i) => startPage + i,\n );\n };\n\n const isFirstPageDisabled = currentPage <= 1;\n const isLastPageDisabled = currentPage >= totalPages;\n const startItem = totalItems === 0 ? 0 : progressive ? 1 : (currentPage - 1) * effectiveItemsPerPage + 1;\n const endItem = Math.min(progressive?.shownCount ?? currentPage * effectiveItemsPerPage, totalItems);\n\n const defaultLabelFormat = (start: number, end: number, total: number) => {\n if (progressive) return progressive.loadedCount !== undefined && progressive.loadedCount !== total\n ? `${end} shown / ${total} matching · ${progressive.loadedCount} loaded`\n : `${end} shown / ${total} loaded`;\n return compact\n ? `${start}-${end} of ${total}`\n : `Showing ${start} to ${end} of ${total} entries`;\n };\n\n const formatLabel = labelFormat || defaultLabelFormat;\n\n const containerClass = cn(\n \"w-full items-center\",\n !compact && \"border-t border-border\",\n layoutType === \"grid\"\n ? progressive\n ? \"grid grid-cols-[auto_minmax(0,1fr)_auto]\"\n : \"grid grid-cols-[auto_minmax(0,1fr)] sm:grid-cols-[auto_minmax(0,1fr)_auto]\"\n : \"flex flex-nowrap justify-between\",\n compact\n ? \"box-border min-h-11 gap-0 px-0 py-0\"\n : \"gap-1 px-2 py-1 sm:gap-4 sm:px-3\",\n className,\n containerClassName,\n );\n\n return (\n <TooltipProvider>\n <div data-matrx-table-footer className={containerClass}>\n {/* Items Per Page Select */}\n {showItemsPerPageSelect && (\n <div\n className={cn(\n \"flex min-w-0 justify-start\",\n !compact && \"sm:p-1\",\n selectContainerClassName,\n )}\n >\n <Select\n value={itemsPerPage.toString()}\n onValueChange={(value) => onItemsPerPageChange(parseInt(value))}\n >\n <SelectTrigger\n aria-label={progressive ? \"Rows per batch\" : \"Rows per page\"}\n className={cn(\n \"focus:ring-0\",\n compact\n ? \"h-11 min-w-20 rounded-md border border-border bg-card px-3 text-sm hover:bg-accent [&_svg]:size-5\"\n : \"h-8 w-[3.75rem] text-xs sm:w-36 sm:text-sm\",\n )}\n >\n <SelectValue placeholder={itemsPerPage.toString()} />\n </SelectTrigger>\n <SelectContent>\n {availablePageSizes.map((size) => (\n <SelectItem key={size} value={size.toString()}>\n {size}\n </SelectItem>\n ))}\n {showAllOption ? (\n <SelectItem value={allValue.toString()}>{allOptionLabel}</SelectItem>\n ) : null}\n </SelectContent>\n </Select>\n </div>\n )}\n\n <div\n className={cn(\"flex min-w-0 justify-center\", infoContainerClassName)}\n >\n {/* Page Info - only show if not hidden But always show the div. */}\n {showPageInfo && !hideEntriesInfo && (\n <>\n <span className=\"truncate text-xs tabular-nums text-muted-foreground sm:hidden\">\n {progressive ? `${endItem}/${totalItems} ${progressive.loadedCount !== undefined && progressive.loadedCount !== totalItems ? \"matching\" : \"loaded\"}` : `${startItem}-${endItem} / ${totalItems}`}\n </span>\n <span\n className={`hidden whitespace-nowrap ${\n compact ? \"text-sm\" : \"text-sm\"\n } min-w-0 truncate text-muted-foreground sm:inline`}\n >\n {formatLabel(startItem, endItem, totalItems)}\n </span>\n </>\n )}\n </div>\n\n {/* Page Controls */}\n {progressive ? (progressive.hasMore ? (\n <PaginationAction\n HostAction={host.ToolbarAction}\n ariaLabel={progressive.hasMore ? \"Show more rows\" : \"All rows shown\"}\n disabledHint=\"All rows shown\"\n disabled={!progressive.hasMore}\n onClick={progressive.onShowMore}\n >\n <ChevronRight className=\"h-5 w-5 rotate-90\" />\n </PaginationAction>\n ) : null) : showPageControls && (\n <div\n className={cn(\n \"col-span-2 flex min-w-0 items-center justify-end sm:col-span-1\",\n compact ? \"gap-0\" : \"gap-0.5 sm:gap-1\",\n controlsContainerClassName,\n )}\n >\n <PaginationAction\n HostAction={host.ToolbarAction}\n ariaLabel=\"First page\"\n disabledHint=\"Already on the first page\"\n visibilityClassName=\"hidden sm:inline-flex\"\n fallbackClassName={navButtonClassName}\n onClick={() => onPageChange(1)}\n disabled={isFirstPageDisabled}\n >\n <ChevronsLeft className=\"h-5 w-5\" />\n </PaginationAction>\n\n <PaginationAction\n HostAction={host.ToolbarAction}\n ariaLabel=\"Previous page\"\n disabledHint=\"Already on the first page\"\n fallbackClassName={navButtonClassName}\n onClick={() => onPageChange(currentPage - 1)}\n disabled={isFirstPageDisabled}\n >\n <ChevronLeft className=\"h-5 w-5\" />\n </PaginationAction>\n\n {getPageNumbers(3).map((page) => (\n <PaginationAction\n key={`mobile-${page}`}\n HostAction={host.ToolbarAction}\n ariaLabel={`Page ${page}`}\n active={currentPage === page}\n disabledHint={`Already on page ${page}`}\n visibilityClassName={cn(\n \"sm:hidden\",\n page === currentPage ? \"inline-flex\" : \"hidden min-[360px]:inline-flex\",\n )}\n fallbackClassName={page === currentPage ? pageActiveButtonClassName : pageButtonClassName}\n onClick={() => onPageChange(page)}\n >\n <span>{page}</span>\n </PaginationAction>\n ))}\n\n {getPageNumbers().map((page) => (\n <PaginationAction\n key={`desktop-${page}`}\n HostAction={host.ToolbarAction}\n ariaLabel={`Page ${page}`}\n active={currentPage === page}\n disabledHint={`Already on page ${page}`}\n visibilityClassName=\"hidden sm:inline-flex\"\n fallbackClassName={currentPage === page ? pageActiveButtonClassName : pageButtonClassName}\n onClick={() => onPageChange(page)}\n >\n <span>{page}</span>\n </PaginationAction>\n ))}\n\n <PaginationAction\n HostAction={host.ToolbarAction}\n ariaLabel=\"Next page\"\n disabledHint=\"Already on the last page\"\n fallbackClassName={navButtonClassName}\n onClick={() => onPageChange(currentPage + 1)}\n disabled={isLastPageDisabled}\n >\n <ChevronRight className=\"h-5 w-5\" />\n </PaginationAction>\n\n <PaginationAction\n HostAction={host.ToolbarAction}\n ariaLabel=\"Last page\"\n disabledHint=\"Already on the last page\"\n visibilityClassName=\"hidden sm:inline-flex\"\n fallbackClassName={navButtonClassName}\n onClick={() => onPageChange(totalPages)}\n disabled={isLastPageDisabled}\n >\n <ChevronsRight className=\"h-5 w-5\" />\n </PaginationAction>\n </div>\n )}\n </div>\n </TooltipProvider>\n );\n}\n"],"mappings":"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","names":["React","React","jsx","jsx","jsx","jsx","jsx","cva","React","jsx","jsxs","jsx","jsx","jsx","jsxs","cva","jsxs","jsx","createContext","useContext","jsx","useContext","jsx","jsxs"]}
1
+ {"version":3,"sources":["../../src/button.tsx","../../src/cn.ts","../../src/tooltip.tsx","../../src/motion.ts","../../src/portal-container.tsx","../../src/data-table/icons.tsx","../../src/select.tsx","../../src/icons.tsx","../../src/data-table/host.tsx","../../src/data-table/pagination.tsx"],"sourcesContent":["\"use client\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nimport { cn } from \"./cn\";\n\nexport const buttonVariants = cva(\n \"inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-0 disabled:pointer-events-none disabled:opacity-50 active:scale-[0.98] [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n /**\n * An explicit spelling of `default`, identical by construction. It is\n * not decoration: matrx-frontend's `ButtonMine` fork carried it, ~17\n * call sites say `variant=\"primary\"`, and the alternative to keeping\n * the word was a host shim translating a prop — the massage C22 bans.\n */\n primary: \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90\",\n /** The affirmative twin of `destructive` — confirm, approve, publish. */\n success:\n \"bg-success text-success-foreground shadow-sm hover:bg-success/90\",\n outline:\n \"border border-border bg-card shadow-sm hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n subtle:\n \"border border-transparent bg-muted/50 text-foreground hover:border-border hover:bg-muted\",\n },\n /**\n * ONE size scale, xs → 3xl, plus the two icon boxes. The top and bottom\n * of the scale came in from matrx-frontend's `ButtonMine` fork (2026-09-07):\n * a dense toolbar needs `xs`, and a marketing/hero call to action needs\n * `xl`+. A host that has to reach outside this scale forks the button,\n * which is exactly how `ButtonMine` was born.\n */\n size: {\n xs: \"h-6 rounded-md px-1 text-xs\",\n sm: \"h-8 rounded-md px-3 text-xs\",\n default: \"h-9 px-4 py-2\",\n /** An explicit spelling of `default` (the fork's middle rung). */\n md: \"h-9 px-4 py-2\",\n lg: \"h-10 rounded-md px-6\",\n xl: \"h-12 px-8 py-3 text-base\",\n \"2xl\": \"h-14 px-10 py-3 text-base\",\n \"3xl\": \"h-16 px-12 py-3 text-base\",\n icon: \"h-9 w-9\",\n \"icon-sm\": \"h-7 w-7\",\n /** A circular icon box — an avatar-shaped control, not a square one. */\n roundIcon: \"h-8 w-8 rounded-full p-0\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Component = asChild ? Slot : \"button\";\n return (\n <Component\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n />\n );\n },\n);\nButton.displayName = \"Button\";\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\n/**\n * Tooltip — the ONE tooltip in the fleet.\n *\n * THE COLLAPSE (0.6.0). Two implementations existed: matrx-frontend's\n * `components/ui/tooltip.tsx` (182 import sites) and `@ai-matrx/tap-target`'s\n * `src/tooltip.tsx` — the latter an explicit inlined PORT of the former,\n * carrying a header that said so. tap-target shipped it only because its ~60\n * tap buttons need a tooltip and no shared package owned one; four repos then\n * adopted `TooltipProvider` from tap-target. That made tap-target — a\n * button-geometry package — the accidental owner of a design-system primitive,\n * with a second copy living in the biggest host.\n *\n * A tooltip is a design-system surface, so it lives here. tap-target now takes\n * `@ai-matrx/design-system` as an ordinary sibling dependency and imports this\n * file; its own copy is deleted, and its re-export removed. The DAG already\n * ordered design-system before tap-target, so no cycle is introduced.\n *\n * BEHAVIOUR is matrx-frontend's, verbatim, including the ruling both copies\n * carried in prose:\n *\n * 1. THE ROOT RENDERS UNCONDITIONALLY — no hydration mount gate. The gate the\n * host wrapper once carried (\"Radix generates dynamic aria-controls ids that\n * differ between SSR and client\") was false: Radix ids come from React's\n * SSR-stable `useId`. It was actively harmful — a Trigger wraps\n * ALWAYS-VISIBLE content, so `return null` deleted that subtree from SSR and\n * the first client paint.\n *\n * 2. THE SURFACE IS NEUTRAL, NOT BRANDED. Popover tokens, not `bg-primary`:\n * rich tooltip content using `text-muted-foreground` was illegible on a\n * brand-coloured background in one theme or the other.\n *\n * SEAM INVERSION. The host resolved nested portal targets through\n * `useNestedPortalContainer` (an app hook wired to its dialog + window-panel\n * systems); tap-target's port dropped that seam entirely and always portalled\n * to `document.body` — which is why a tooltip inside a popped-out panel landed\n * in the wrong window. Here it is the package's `PortalContainerProvider`\n * seam: an explicit `container` prop wins, then the injected container, then\n * `document.body`. Both prior behaviours are reachable; neither is forked.\n */\n\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\nimport * as React from \"react\";\n\nimport { cn } from \"./cn\";\nimport { MOTION_POPPER } from \"./motion\";\nimport { usePortalContainer } from \"./portal-container\";\n\n/**\n * Mount once near the app root. Every tooltip in the tree shares its\n * `delayDuration` / `skipDelayDuration` timing.\n */\nconst TooltipProvider = TooltipPrimitive.Provider;\n\nconst Tooltip = TooltipPrimitive.Root;\n\nconst TooltipTrigger = TooltipPrimitive.Trigger;\n\nexport interface TooltipContentProps\n extends React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content> {\n /**\n * Explicit portal target; wins over the injected `PortalContainerProvider`\n * value. Pass `null` to force `document.body`.\n */\n container?: HTMLElement | null;\n /**\n * Package-owned open/close motion. Default `true`. Pass `false` for a\n * surface that must appear instantly. It is NOT the reduced-motion switch;\n * `styles.css` already honours `prefers-reduced-motion`.\n */\n animated?: boolean;\n}\n\nconst TooltipContent = React.forwardRef<\n React.ComponentRef<typeof TooltipPrimitive.Content>,\n TooltipContentProps\n>(({ className, sideOffset = 4, container, animated = true, ...props }, ref) => {\n const resolved = usePortalContainer(container);\n return (\n <TooltipPrimitive.Portal container={resolved ?? null}>\n <TooltipPrimitive.Content\n ref={ref}\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"z-[10001] overflow-hidden rounded-md border border-border bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-md\",\n animated && MOTION_POPPER,\n className,\n )}\n {...props}\n />\n </TooltipPrimitive.Portal>\n );\n});\nTooltipContent.displayName = TooltipPrimitive.Content.displayName;\n\nexport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };\n","/**\n * THE MOTION CONTRACT (0.10.0) — the class names every animated surface in\n * this package puts on the DOM, in ONE place.\n *\n * Why a module and not ten inline strings: the sweep that produced this file\n * found the same defect ten times over, and it was invisible each time\n * because each primitive spelled its animation out by hand. Ten hand-written\n * copies of `data-[state=open]:animate-in data-[state=closed]:animate-out\n * data-[state=closed]:fade-out-0 …` meant ten chances to reach for a utility\n * nothing in the package defines — which is exactly what happened. A single\n * exported constant per motion SHAPE means the next primitive cannot invent\n * an eleventh spelling, and `styles.test.ts` can prove every one of them\n * resolves to a rule in the shipped stylesheet.\n *\n * Every rule these name lives in `styles.css` under the package's own\n * keyframes. NONE of them is a Tailwind utility, and none requires a host\n * plugin — see that file's header for the measurement that made this\n * necessary.\n */\n\n/** Modal scrims: Dialog, AlertDialog, Sheet, CommandDialog. Fade only. */\nexport const MOTION_OVERLAY = \"matrx-motion-overlay\";\n\n/** The centred dialog card. Fades and scales; centring is not its business. */\nexport const MOTION_DIALOG = \"matrx-motion-dialog\";\n\n/**\n * THE CENTRING OF A CENTRED DIALOG CARD — package-owned, in the `translate`\n * property, and NEVER a Tailwind `translate-x-[-50%] translate-y-[-50%]` pair.\n *\n * Those utilities do not compile to the same thing in every host: Tailwind v3\n * writes them into `transform`, Tailwind v4 writes them into the independent\n * `translate` property, which COMPOSES with `transform` instead of being\n * replaced by it. 0.10.0's keyframes restated the centring inside `transform`,\n * which was harmless on v3 and doubled the centring on v4 — the card flew in\n * from off the top-left of the viewport for the animation's whole duration and\n * snapped into place at the end (fixed in 0.10.1).\n *\n * Owning it here means one spelling that reads the same on both, and it frees\n * `transform` so the keyframes carry ONLY the delta. Put this on every centred\n * surface UNCONDITIONALLY — it is geometry, so unlike {@link MOTION_DIALOG} it\n * must survive `animated={false}`. Its rule ships in `styles.css`.\n */\nexport const CENTERED_DIALOG = \"matrx-dialog-centered\";\n\n/**\n * The resting gap between a `popper`-positioned surface and its trigger, for\n * the primitives that want one (today: `Select`). Same law and same reason as\n * {@link CENTERED_DIALOG} — a position an animated surface holds AT REST is\n * the `translate` property's job, never a Tailwind translate utility, because\n * those land in `transform` on a v3 host and in `translate` on a v4 one while\n * the keyframes animate `transform` either way. Sizes from\n * `--matrx-popper-offset`; keys off Radix's `data-side`.\n */\nexport const POPPER_OFFSET = \"matrx-popper-offset\";\n\n/** The mobile Dialog / CommandDialog bottom sheet. Slides up and fades. */\nexport const MOTION_BOTTOM_SHEET = \"matrx-motion-bottom-sheet\";\n\n/**\n * Radix-popper surfaces: Popover, DropdownMenu, ContextMenu, HoverCard,\n * Select, Tooltip. Reads `--radix-popper-transform-origin` so the surface\n * grows out of its trigger, and `data-side` so it travels from it.\n */\nexport const MOTION_POPPER = \"matrx-motion-popper\";\n\n/** Edge sheets, one class per `sheetVariants` side. */\nexport const MOTION_SHEET = {\n top: \"matrx-motion-sheet-top\",\n bottom: \"matrx-motion-sheet-bottom\",\n left: \"matrx-motion-sheet-left\",\n right: \"matrx-motion-sheet-right\",\n center: \"matrx-motion-sheet-center\",\n} as const;\n\n/** Skeleton's breathing loop. */\nexport const MOTION_PULSE = \"matrx-pulse\";\n\n/** The spinner loop, for every inline busy indicator in the package. */\nexport const MOTION_SPIN = \"matrx-spin\";\n\n/**\n * Every motion class the package ships, for the guards. If a rule for one of\n * these is missing from `styles.css`, a component animates in no consumer and\n * says nothing about it — the C26 failure this list exists to make loud.\n */\nexport const ALL_MOTION_CLASSES = [\n MOTION_OVERLAY,\n MOTION_DIALOG,\n MOTION_BOTTOM_SHEET,\n MOTION_POPPER,\n ...Object.values(MOTION_SHEET),\n MOTION_PULSE,\n MOTION_SPIN,\n] as const;\n\n/**\n * The host-plugin utilities this package is forbidden to emit. They are\n * supplied by `tailwindcss-animate` / `tw-animate-css`, which is a HOST CSS\n * entry concern a package cannot declare a dependency on: three of the four\n * AI Matrx consumers never loaded it, so every surface wearing these appeared\n * with no animation and no error. `styles.test.ts` fails the build if one\n * comes back.\n */\nexport const FORBIDDEN_HOST_MOTION_UTILITIES = [\n \"animate-in\",\n \"animate-out\",\n \"fade-in\",\n \"fade-out\",\n \"zoom-in\",\n \"zoom-out\",\n \"slide-in-from\",\n \"slide-out-to\",\n \"animate-accordion\",\n \"animate-slide-down\",\n \"animate-slide-up\",\n \"animate-pulse\",\n \"animate-spin\",\n] as const;\n","\"use client\";\n\n/**\n * Injected portal-container seam.\n *\n * The matrx-frontend original resolved nested portal targets through\n * `useNestedPortalContainer` (explicit prop > dialog content > popout body >\n * document.body) — a host-shaped hook wired to that app's dialog and\n * window-panel systems. The package inverts the seam: hosts provide the\n * resolved container through `PortalContainerProvider`; an explicit\n * `container` prop on a component still wins, and with neither the portal\n * falls through to `document.body` (Radix default). Priority semantics are\n * unchanged from the original.\n */\n\nimport * as React from \"react\";\n\n// Shared identity across independently bundled public entrypoints/loaders.\nconst CONTEXT_SLOT = Symbol.for(\"ai-matrx.design-system.portal-container-context\");\nconst contextRegistry = globalThis as typeof globalThis & { [CONTEXT_SLOT]?: React.Context<HTMLElement | null | undefined> };\nconst PortalContainerContext = contextRegistry[CONTEXT_SLOT] ??= React.createContext<HTMLElement | null | undefined>(undefined);\n\nexport interface PortalContainerProviderProps {\n /** Where nested Radix portals (Popover, etc.) should mount. `null`/`undefined` → document.body. */\n container: HTMLElement | null | undefined;\n children: React.ReactNode;\n}\n\nexport function PortalContainerProvider({\n container,\n children,\n}: PortalContainerProviderProps) {\n return (\n <PortalContainerContext.Provider value={container ?? undefined}>\n {children}\n </PortalContainerContext.Provider>\n );\n}\n\n/**\n * Resolve a portal target: explicit prop (including an explicit `null`,\n * meaning \"the default body\") beats the injected container.\n */\nexport function usePortalContainer(\n explicit?: HTMLElement | null,\n): HTMLElement | undefined {\n const injected = React.useContext(PortalContainerContext);\n\n if (explicit !== undefined) {\n return explicit ?? undefined;\n }\n\n return injected ?? undefined;\n}\n","import type { SVGProps } from \"react\";\n\ntype IconProps = SVGProps<SVGSVGElement>;\nfunction Icon({ children, ...props }: IconProps) {\n return <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\" {...props}>{children}</svg>;\n}\nconst path = <path d=\"M4 12h16M12 4v16\" />;\nexport const ChevronLeft = (p: IconProps) => <Icon {...p}><path d=\"m15 18-6-6 6-6\" /></Icon>;\nexport const ChevronRight = (p: IconProps) => <Icon {...p}><path d=\"m9 18 6-6-6-6\" /></Icon>;\nexport const ChevronDown = (p: IconProps) => <Icon {...p}><path d=\"m6 9 6 6 6-6\" /></Icon>;\nexport const ArrowDown = (p: IconProps) => <Icon {...p}><path d=\"M12 4v16m-6-6 6 6 6-6\" /></Icon>;\nexport const ArrowUp = (p: IconProps) => <Icon {...p}><path d=\"M12 20V4m-6 6 6-6 6 6\" /></Icon>;\nexport const ArrowUpDown = (p: IconProps) => <Icon {...p}><path d=\"M12 4v16m-4-12 4-4 4 4m-8 8 4 4 4-4\" /></Icon>;\nexport const Check = (p: IconProps) => <Icon {...p}><path d=\"m5 12 4 4L19 6\" /></Icon>;\nexport const X = (p: IconProps) => <Icon {...p}><path d=\"M6 6l12 12M18 6 6 18\" /></Icon>;\nexport const Search = (p: IconProps) => <Icon {...p}><circle cx=\"11\" cy=\"11\" r=\"6\" /><path d=\"m16 16 4 4\" /></Icon>;\nexport const Plus = (p: IconProps) => <Icon {...p}>{path}</Icon>;\nexport const Minus = (p: IconProps) => <Icon {...p}><path d=\"M4 12h16\" /></Icon>;\nexport const Eraser = (p: IconProps) => <Icon {...p}><path d=\"m16 3 5 5-11 11H5l-3-3L13 5l3-2Z M8 10l6 6 M10 19h12\" /></Icon>;\nexport const GripVertical = (p: IconProps) => <Icon {...p}><circle cx=\"9\" cy=\"6\" r=\"1\" /><circle cx=\"15\" cy=\"6\" r=\"1\" /><circle cx=\"9\" cy=\"12\" r=\"1\" /><circle cx=\"15\" cy=\"12\" r=\"1\" /><circle cx=\"9\" cy=\"18\" r=\"1\" /><circle cx=\"15\" cy=\"18\" r=\"1\" /></Icon>;\n/** lucide `sliders-horizontal` — used for the table column manager. */\nexport const SlidersHorizontal = (p: IconProps) => <Icon {...p}>\n <path d=\"M21 4h-7M10 4H3M21 12h-9M8 12H3M21 20h-5M12 20H3M14 2v4M8 10v4M16 18v4\" />\n</Icon>;\nexport const Trash2 = (p: IconProps) => <Icon {...p}><path d=\"M4 7h16M10 11v6M14 11v6M9 7l1-2h4l1 2M6 7l1 13h10l1-13\" /></Icon>;\n/**\n * Spinner-only incomplete arc. Never a resting glyph — at rest this reads as a\n * broken half-circle. Pair it with `animate-spin` / `matrx-spin` only while\n * work is actually running. Refresh controls use `RefreshControlIcon`.\n */\nexport const Loader2 = (p: IconProps) => <Icon {...p}><path d=\"M20 12a8 8 0 1 1-2.3-5.7\" /></Icon>;\n/** lucide `refresh-cw` — the resting refresh arrows. */\nexport const RefreshCw = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\" />\n <path d=\"M21 3v5h-5\" />\n <path d=\"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\" />\n <path d=\"M8 16H3v5\" />\n </Icon>\n);\n/** Refresh affordance: arrows at rest, spinner only while busy. */\nexport function RefreshControlIcon({\n spinning = false,\n className,\n ...props\n}: IconProps & { spinning?: boolean }) {\n if (spinning) {\n return (\n <Loader2\n className={[className, \"animate-spin\"].filter(Boolean).join(\" \")}\n {...props}\n />\n );\n }\n return <RefreshCw className={className} {...props} />;\n}\nexport const Save = (p: IconProps) => <Icon {...p}><path d=\"M5 3h12l2 2v16H5zM8 3v6h8V3M8 21v-7h8v7\" /></Icon>;\nexport const Pencil = (p: IconProps) => <Icon {...p}><path d=\"m4 20 4-1 11-11-3-3L5 16l-1 4z\" /></Icon>;\nexport const Eye = (p: IconProps) => <Icon {...p}><path d=\"M2 12s3-6 10-6 10 6 10 6-3 6-10 6S2 12 2 12z\" /><circle cx=\"12\" cy=\"12\" r=\"2\" /></Icon>;\nexport const PanelRight = (p: IconProps) => <Icon {...p}><rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" /><path d=\"M15 4v16\" /></Icon>;\nexport const PanelRightOpen = PanelRight;\nexport const WholeWord = (p: IconProps) => <Icon {...p}><path d=\"M4 6l3 12 3-8 3 8 3-12M17 15h4\" /></Icon>;\nexport const ExternalLink = (p: IconProps) => <Icon {...p}><path d=\"M14 4h6v6M20 4l-9 9M19 13v6H5V5h6\" /></Icon>;\nexport const Copy = (p: IconProps) => <Icon {...p}><rect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2\" /><path d=\"M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3\" /></Icon>;\nexport const Lightbulb = (p: IconProps) => <Icon {...p}><path d=\"M9 18h6M10 22h4M8 14a6 6 0 1 1 8 0c-1 1-1 2-1 3H9c0-1 0-2-1-3z\" /></Icon>;\nexport const ShieldOff = (p: IconProps) => <Icon {...p}><path d=\"m3 3 18 18M12 3l7 3v5c0 4-3 7-7 9-4-2-7-5-7-9V6l4-2\" /></Icon>;\nexport const ListFilter = SlidersHorizontal;\nexport const ListX = X;\n\nexport const ChevronsLeft = (p: IconProps) => <Icon {...p}><path d=\"m11 18-6-6 6-6m8 12-6-6 6-6\" /></Icon>;\nexport const ChevronsRight = (p: IconProps) => <Icon {...p}><path d=\"m5 18 6-6-6-6m8 12 6-6-6-6\" /></Icon>;\n","\"use client\";\n\n/**\n * Select — ported verbatim from matrx-frontend `components/ui/select.tsx`.\n *\n * Seam inversions:\n * - The host's `useNestedPortalContainer` (dialog/popout aware) becomes the\n * injected `PortalContainerProvider` seam (`portal-container.tsx`); the\n * explicit `container` prop keeps top priority, exactly as before.\n * - `ChevronDownIcon` / `ChevronUpIcon` / `CheckIcon` come from the package's\n * inlined SVGs (C19), not @radix-ui/react-icons — same glyphs, same\n * viewBoxes. (The origin also imported `CaretSortIcon` without ever using\n * it; the dead import is not carried along.)\n *\n * THE ROOT RENDERS UNCONDITIONALLY — no mount gate. This wrapper used to defer\n * rendering until after hydration (\"Radix generates dynamic aria-controls ids\n * that differ between SSR and client\"), and that justification was false:\n * Radix ids come from React's SSR-stable `useId` (verified against\n * @radix-ui/react-select 2.3.1 / react-id 1.1.2). The gate was actively\n * harmful — it deleted the ALWAYS-VISIBLE select trigger (a form control)\n * from SSR and the first client paint.\n */\n\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nimport { cn } from \"./cn\";\nimport { MOTION_POPPER, POPPER_OFFSET } from \"./motion\";\nimport {\n CheckIcon,\n RadixChevronDownIcon,\n RadixChevronUpIcon,\n} from \"./icons\";\nimport { usePortalContainer } from \"./portal-container\";\n\nexport const Select = SelectPrimitive.Root;\n\nexport const SelectGroup = SelectPrimitive.Group;\n\nexport const SelectValue = SelectPrimitive.Value;\n\nexport const selectTriggerVariants = cva(\n \"flex w-full items-center justify-between gap-2 whitespace-nowrap rounded-md border border-border bg-card text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground transition-colors hover:bg-accent hover:border-accent-foreground/20 focus:outline-none focus:ring-1 focus:ring-primary/30 focus:border-primary/40 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:min-w-0 [&>span]:line-clamp-1\",\n {\n variants: {\n size: {\n sm: \"h-7 px-2 py-1 text-xs\",\n default: \"h-9 px-3 py-1\",\n lg: \"h-10 px-3 py-2\",\n },\n },\n defaultVariants: {\n size: \"default\",\n },\n },\n);\n\nexport interface SelectTriggerProps\n extends\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>,\n VariantProps<typeof selectTriggerVariants> {\n hideArrow?: boolean;\n}\n\nexport const SelectTrigger = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Trigger>,\n SelectTriggerProps\n>(({ className, children, hideArrow = false, size, ...props }, ref) => (\n <SelectPrimitive.Trigger\n ref={ref}\n className={cn(selectTriggerVariants({ size, className }))}\n {...props}\n >\n {children}\n {!hideArrow && (\n <SelectPrimitive.Icon asChild>\n <RadixChevronDownIcon className=\"h-4 w-4 shrink-0 opacity-50\" />\n </SelectPrimitive.Icon>\n )}\n </SelectPrimitive.Trigger>\n));\nSelectTrigger.displayName = SelectPrimitive.Trigger.displayName;\n\nexport const SelectScrollUpButton = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.ScrollUpButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollUpButton\n ref={ref}\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className,\n )}\n {...props}\n >\n <RadixChevronUpIcon />\n </SelectPrimitive.ScrollUpButton>\n));\nSelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;\n\nexport const SelectScrollDownButton = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.ScrollDownButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollDownButton\n ref={ref}\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className,\n )}\n {...props}\n >\n <RadixChevronDownIcon />\n </SelectPrimitive.ScrollDownButton>\n));\nSelectScrollDownButton.displayName =\n SelectPrimitive.ScrollDownButton.displayName;\n\nexport interface SelectContentProps\n extends React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content> {\n /** Explicit portal target; wins over the injected container. */\n container?: HTMLElement | null;\n /**\n * Package-owned open/close motion. Default `true`. Pass `false` for a\n * surface that must appear instantly. It is NOT the reduced-motion switch;\n * `styles.css` already honours `prefers-reduced-motion`.\n */\n animated?: boolean;\n}\n\nexport const SelectContent = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Content>,\n SelectContentProps\n>(\n (\n {\n className,\n children,\n position = \"popper\",\n container,\n animated = true,\n ...props\n },\n ref,\n ) => {\n const portalContainer = usePortalContainer(container);\n return (\n <SelectPrimitive.Portal container={portalContainer}>\n <SelectPrimitive.Content\n ref={ref}\n className={cn(\n \"relative z-[10001] max-h-96 min-w-[8rem] max-w-[calc(100vw-2rem)] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md\",\n animated && MOTION_POPPER,\n // The resting gap from the trigger. It is the `translate` property\n // (POPPER_OFFSET), never Tailwind translate utilities: those compose\n // with `transform` on a v4 host and are REPLACED by it on a v3 one,\n // so on v3 the animation ate the gap and the surface snapped 4px at\n // the end. Same law as the centred dialog card — see motion.ts.\n position === \"popper\" && POPPER_OFFSET,\n className,\n )}\n position={position}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n \"max-w-full overflow-y-auto p-0.5\",\n position === \"popper\" &&\n \"w-full min-w-[var(--radix-select-trigger-width)] max-h-[var(--radix-select-content-available-height)]\",\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n );\n});\nSelectContent.displayName = SelectPrimitive.Content.displayName;\n\nexport const SelectLabel = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Label\n ref={ref}\n className={cn(\"px-2 py-1.5 text-sm font-semibold\", className)}\n {...props}\n />\n));\nSelectLabel.displayName = SelectPrimitive.Label.displayName;\n\nexport const SelectItem = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item> & {\n /**\n * Secondary line shown under the label IN THE LIST ONLY. Rendered outside\n * Radix `ItemText` on purpose: everything inside `ItemText` is what the\n * closed trigger displays, so a description passed as `children` gets\n * squeezed into the fixed-height trigger and clipped. This prop keeps the\n * trigger to the one-line label while the open list shows both lines.\n */\n description?: React.ReactNode;\n }\n>(({ className, children, description, ...props }, ref) => (\n <SelectPrimitive.Item\n ref={ref}\n className={cn(\n \"relative flex w-full min-w-0 cursor-default select-none rounded-sm py-1 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n description ? \"flex-col items-start gap-0.5 py-1.5\" : \"items-center\",\n className,\n )}\n {...props}\n >\n <span className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"h-4 w-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <span className=\"min-w-0 whitespace-normal break-words [overflow-wrap:anywhere]\">\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </span>\n {description ? (\n <span className=\"block min-w-0 break-words text-xs leading-snug text-muted-foreground [overflow-wrap:anywhere]\">\n {description}\n </span>\n ) : null}\n </SelectPrimitive.Item>\n));\nSelectItem.displayName = SelectPrimitive.Item.displayName;\n\nexport const SelectSeparator = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Separator\n ref={ref}\n className={cn(\"-mx-1 my-1 h-px bg-muted\", className)}\n {...props}\n />\n));\nSelectSeparator.displayName = SelectPrimitive.Separator.displayName;\n","/**\n * Internal inlined SVG icons (policy C19: no icon-library dependency, ever).\n *\n * Each icon is copied from the exact glyph the ported originals rendered:\n * lucide-react's Loader2 / ChevronLeft / ChevronRight / MoreHorizontal and\n * @radix-ui/react-icons' Cross2Icon. Same viewBoxes, same paths, same default\n * stroke geometry — a host swapping the import sees pixel-identical output.\n *\n * Not exported from the package entry; components consume them directly.\n */\n\nimport * as React from \"react\";\n\ntype IconProps = React.SVGAttributes<SVGSVGElement>;\n\nfunction lucideProps(props: IconProps): React.SVGAttributes<SVGSVGElement> {\n return {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n \"aria-hidden\": true,\n ...props,\n };\n}\n\n/**\n * lucide `loader-2` — the spinner glyph. Callers add `matrx-spin`.\n * Never a resting icon: at rest this incomplete arc reads as a broken\n * half-circle. Refresh controls use arrows, then swap to this only while busy.\n */\nexport function Loader2Icon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n );\n}\n\n/** lucide `chevron-left`. */\nexport function ChevronLeftIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n );\n}\n\n/** lucide `chevron-right`. */\nexport function ChevronRightIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n );\n}\n\n/** lucide `chevron-down` — the disclosure's open glyph. */\nexport function ChevronDownIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n );\n}\n\n/** lucide `archive` — the archived-rows glyph (ArchivedDisclosure). */\nexport function ArchiveIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <rect width=\"20\" height=\"5\" x=\"2\" y=\"3\" rx=\"1\" />\n <path d=\"M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8\" />\n <path d=\"M10 12h4\" />\n </svg>\n );\n}\n\n/** lucide `more-horizontal` — the kebab/ellipsis glyph. */\nexport function MoreHorizontalIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"19\" cy=\"12\" r=\"1\" />\n <circle cx=\"5\" cy=\"12\" r=\"1\" />\n </svg>\n );\n}\n\n/** lucide `check` — the selected-row tick (CreatablePicker). */\nexport function LucideCheckIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n );\n}\n\n/** lucide `chevrons-up-down` — the combobox trigger glyph. */\nexport function ChevronsUpDownIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"m7 15 5 5 5-5\" />\n <path d=\"m7 9 5-5 5 5\" />\n </svg>\n );\n}\n\n/** lucide `external-link` — the manage-in-new-tab glyph. */\nexport function ExternalLinkIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"M15 3h6v6\" />\n <path d=\"M10 14 21 3\" />\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n </svg>\n );\n}\n\n/** lucide `lock` — the platform-governed vocabulary glyph. */\nexport function LockIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <rect width=\"18\" height=\"11\" x=\"3\" y=\"11\" rx=\"2\" ry=\"2\" />\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\" />\n </svg>\n );\n}\n\n/** lucide `plus` — the create/add glyph. */\nexport function PlusIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"M5 12h14\" />\n <path d=\"M12 5v14\" />\n </svg>\n );\n}\n\n/** lucide `x` — the dialog close glyph (host dialog module used lucide X). */\nexport function XIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n\n/**\n * @radix-ui/react-icons components default to width/height 15 — the bare\n * `<ChevronUpIcon />` renders in Select's scroll buttons rely on it.\n */\nfunction radixProps(props: IconProps): React.SVGAttributes<SVGSVGElement> {\n return {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 15 15\",\n width: 15,\n height: 15,\n fill: \"none\",\n \"aria-hidden\": true,\n ...props,\n };\n}\n\n/** @radix-ui/react-icons `MagnifyingGlassIcon` — the command search glyph. */\nexport function MagnifyingGlassIcon(props: IconProps) {\n return (\n <svg {...radixProps(props)}>\n <path\n d=\"M10 6.5C10 8.433 8.433 10 6.5 10C4.567 10 3 8.433 3 6.5C3 4.567 4.567 3 6.5 3C8.433 3 10 4.567 10 6.5ZM9.30884 10.0159C8.53901 10.6318 7.56251 11 6.5 11C4.01472 11 2 8.98528 2 6.5C2 4.01472 4.01472 2 6.5 2C8.98528 2 11 4.01472 11 6.5C11 7.56251 10.6318 8.53901 10.0159 9.30884L12.8536 12.1464C13.0488 12.3417 13.0488 12.6583 12.8536 12.8536C12.6583 13.0488 12.3417 13.0488 12.1464 12.8536L9.30884 10.0159Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n/** @radix-ui/react-icons `CheckIcon` — the select item indicator glyph. */\nexport function CheckIcon(props: IconProps) {\n return (\n <svg {...radixProps(props)}>\n <path\n d=\"M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n/**\n * @radix-ui/react-icons `DividerHorizontalIcon` — the INDETERMINATE checkbox\n * glyph. Radix renders the indicator for both `true` and `\"indeterminate\"`, so\n * a half-selected \"select all\" that shows a full check states something false;\n * the two states get different glyphs on purpose.\n */\nexport function DividerHorizontalIcon(props: IconProps) {\n return (\n <svg {...radixProps(props)}>\n <path\n d=\"M2 7.5C2 7.22386 2.22386 7 2.5 7H12.5C12.7761 7 13 7.22386 13 7.5C13 7.77614 12.7761 8 12.5 8H2.5C2.22386 8 2 7.77614 2 7.5Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n/** @radix-ui/react-icons `DotFilledIcon` — the menu radio-item indicator. */\nexport function DotFilledIcon(props: IconProps) {\n return (\n <svg {...radixProps(props)}>\n <path\n d=\"M9.875 7.5C9.875 8.81168 8.81168 9.875 7.5 9.875C6.18832 9.875 5.125 8.81168 5.125 7.5C5.125 6.18832 6.18832 5.125 7.5 5.125C8.81168 5.125 9.875 6.18832 9.875 7.5Z\"\n fill=\"currentColor\"\n />\n </svg>\n );\n}\n\n/** @radix-ui/react-icons `ChevronRightIcon` — the submenu-trigger glyph. */\nexport function RadixChevronRightIcon(props: IconProps) {\n return (\n <svg {...radixProps(props)}>\n <path\n d=\"M6.1584 3.13508C6.35985 2.94621 6.67627 2.95642 6.86514 3.15788L10.6151 7.15788C10.7954 7.3502 10.7954 7.64949 10.6151 7.84182L6.86514 11.8418C6.67627 12.0433 6.35985 12.0535 6.1584 11.8646C5.95694 11.6757 5.94673 11.3593 6.1356 11.1579L9.565 7.49985L6.1356 3.84182C5.94673 3.64036 5.95694 3.32394 6.1584 3.13508Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n/** @radix-ui/react-icons `ChevronDownIcon` — the select trigger/scroll glyph. */\nexport function RadixChevronDownIcon(props: IconProps) {\n return (\n <svg {...radixProps(props)}>\n <path\n d=\"M3.13523 6.15803C3.3241 5.95657 3.64052 5.94637 3.84197 6.13523L7.5 9.56464L11.158 6.13523C11.3595 5.94637 11.6759 5.95657 11.8648 6.15803C12.0536 6.35949 12.0434 6.67591 11.842 6.86477L7.84197 10.6148C7.64964 10.7951 7.35036 10.7951 7.15803 10.6148L3.15803 6.86477C2.95657 6.67591 2.94637 6.35949 3.13523 6.15803Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n/** @radix-ui/react-icons `ChevronUpIcon` — the select scroll-up glyph. */\nexport function RadixChevronUpIcon(props: IconProps) {\n return (\n <svg {...radixProps(props)}>\n <path\n d=\"M3.13523 8.84197C3.3241 9.04343 3.64052 9.05363 3.84197 8.86477L7.5 5.43536L11.158 8.86477C11.3595 9.05363 11.6759 9.04343 11.8648 8.84197C12.0536 8.64051 12.0434 8.32409 11.842 8.13523L7.84197 4.38523C7.64964 4.20492 7.35036 4.20492 7.15803 4.38523L3.15803 8.13523C2.95657 8.32409 2.94637 8.64051 3.13523 8.84197Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n/** @radix-ui/react-icons `Cross2Icon` — the dialog/sheet close glyph. */\nexport function Cross2Icon(props: IconProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 15 15\"\n fill=\"none\"\n aria-hidden\n {...props}\n >\n <path\n d=\"M11.7816 4.03157C12.0062 3.80702 12.0062 3.44295 11.7816 3.2184C11.5571 2.99385 11.193 2.99385 10.9685 3.2184L7.50005 6.68682L4.03164 3.2184C3.80708 2.99385 3.44301 2.99385 3.21846 3.2184C2.99391 3.44295 2.99391 3.80702 3.21846 4.03157L6.68688 7.49999L3.21846 10.9684C2.99391 11.193 2.99391 11.557 3.21846 11.7816C3.44301 12.0061 3.80708 12.0061 4.03164 11.7816L7.50005 8.31316L10.9685 11.7816C11.193 12.0061 11.5571 12.0061 11.7816 11.7816C12.0062 11.557 12.0062 11.193 11.7816 10.9684L8.31322 7.49999L11.7816 4.03157Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n/**\n * @radix-ui/react-icons `DragHandleDots2Icon` — the grip on `ResizableHandle`.\n * Inlined per C19: this package depends on no icon library.\n */\nexport function DragHandleDots2Icon(props: IconProps) {\n return (\n <svg {...radixProps(props)}>\n <path\n d=\"M4.5 2.5C5.05228 2.5 5.5 2.05228 5.5 1.5C5.5 0.947715 5.05228 0.5 4.5 0.5C3.94772 0.5 3.5 0.947715 3.5 1.5C3.5 2.05228 3.94772 2.5 4.5 2.5ZM4.5 6.5C5.05228 6.5 5.5 6.05229 5.5 5.5C5.5 4.94771 5.05228 4.5 4.5 4.5C3.94772 4.5 3.5 4.94771 3.5 5.5C3.5 6.05229 3.94772 6.5 4.5 6.5ZM5.5 9.5C5.5 10.0523 5.05228 10.5 4.5 10.5C3.94772 10.5 3.5 10.0523 3.5 9.5C3.5 8.94771 3.94772 8.5 4.5 8.5C5.05228 8.5 5.5 8.94771 5.5 9.5ZM4.5 14.5C5.05228 14.5 5.5 14.0523 5.5 13.5C5.5 12.9477 5.05228 12.5 4.5 12.5C3.94772 12.5 3.5 12.9477 3.5 13.5C3.5 14.0523 3.94772 14.5 4.5 14.5ZM11.5 1.5C11.5 2.05228 11.0523 2.5 10.5 2.5C9.94771 2.5 9.5 2.05228 9.5 1.5C9.5 0.947715 9.94771 0.5 10.5 0.5C11.0523 0.5 11.5 0.947715 11.5 1.5ZM10.5 6.5C11.0523 6.5 11.5 6.05229 11.5 5.5C11.5 4.94771 11.0523 4.5 10.5 4.5C9.94771 4.5 9.5 4.94771 9.5 5.5C9.5 6.05229 9.94771 6.5 10.5 6.5ZM11.5 9.5C11.5 10.0523 11.0523 10.5 10.5 10.5C9.94771 10.5 9.5 10.0523 9.5 9.5C9.5 8.94771 9.94771 8.5 10.5 8.5C11.0523 8.5 11.5 8.94771 11.5 9.5ZM10.5 14.5C11.0523 14.5 11.5 14.0523 11.5 13.5C11.5 12.9477 11.0523 12.5 10.5 12.5C9.94771 12.5 9.5 12.9477 9.5 13.5C9.5 14.0523 9.94771 14.5 10.5 14.5Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\n/** lucide `star` — the default-organization badge (OrganizationPicker). */\nexport function StarIcon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z\" />\n </svg>\n );\n}\n\n/** lucide `building-2` — the organization glyph (OrganizationPicker trigger). */\nexport function Building2Icon(props: IconProps) {\n return (\n <svg {...lucideProps(props)}>\n <path d=\"M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18Z\" />\n <path d=\"M6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2\" />\n <path d=\"M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2\" />\n <path d=\"M10 6h4\" />\n <path d=\"M10 10h4\" />\n <path d=\"M10 14h4\" />\n <path d=\"M10 18h4\" />\n </svg>\n );\n}\n","\"use client\";\nimport { createContext, useContext, type Context, type ComponentType, type ReactNode, type MouseEventHandler } from \"react\";\nimport type { CopyControlProps } from \"./copy-types\";\nimport type { MatrxDataTableDensity, TableSavedViewsProps } from \"./types\";\n\nexport type {\n AgentPayloadInput,\n AiCustomSource,\n AiVariant,\n CopyControlProps,\n CopyExportConfig,\n} from \"./copy-types\";\n\nexport interface TableLinkProps { href: string; children: ReactNode; className?: string; onClick?: MouseEventHandler<HTMLAnchorElement>; }\n/**\n * Host-owned toolbar affordance. The table package keeps operation state and\n * labels; an application can supply its canonical icon-button primitive\n * without making the shared package depend on an application UI package.\n */\nexport interface TableToolbarActionProps { ariaLabel: string; tooltip?: string | undefined; disabled?: boolean | undefined; busy?: boolean | undefined; /** Indicates a selected mutually-exclusive action such as the current page. */ active?: boolean | undefined; onClick: () => void; children: ReactNode; }\nexport interface TableSidePanelProps { title: string; titleNode?: ReactNode; description?: ReactNode; onClose: () => void; defaultWidth?: number; headerActions?: ReactNode; children: ReactNode; }\nexport interface TableWindowPanelProps { id: string; title: string; onClose: () => void; width?: number; height?: number; minWidth?: number; minHeight?: number; actionsRight?: ReactNode; bodyClassName?: string; sidebarDefaultSize?: number; sidebarMinSize?: number; sidebar?: ReactNode; children: ReactNode; }\nexport interface TableEntityRefProps { token: string; id: string; href?: string; children: ReactNode; className?: string; }\nexport interface TablePeekProps { kind: string; id: string; href?: string; onClose: () => void; }\nexport interface TableDoors { href?: string; peekKind?: string; canPeek?: boolean; }\nexport interface MatrxDataTableHost { JsonViewer?: ComponentType<{ data: object | string }>; Link?: ComponentType<TableLinkProps>; CopyControls?: ComponentType<CopyControlProps>; ToolbarAction?: ComponentType<TableToolbarActionProps>; SidePanelSurface?: ComponentType<TableSidePanelProps>; WindowPanel?: ComponentType<TableWindowPanelProps>; EntityRef?: ComponentType<TableEntityRefProps>; resolveEntityDoors?: (token: string, id: string, href?: string | null) => TableDoors | null; ResourcePeek?: ComponentType<TablePeekProps>; SavedViews?: ComponentType<TableSavedViewsProps>; /** Host default; a table's explicit density takes precedence. */ defaultDensity?: MatrxDataTableDensity; notify?: { success(message: string): void; error(message: string): void }; }\n// Public entrypoints are independently bundled in ESM and CJS. The context\n// identity must survive those bundle boundaries; values stay provider-scoped.\nconst HOST_SLOT = Symbol.for(\"ai-matrx.design-system.table-host-context\");\nconst hostRegistry = globalThis as typeof globalThis & { [HOST_SLOT]?: Context<MatrxDataTableHost> };\nconst HostContext = hostRegistry[HOST_SLOT] ??= createContext<MatrxDataTableHost>({});\nexport function MatrxDataTableProvider({ value, children }: { value: MatrxDataTableHost; children: ReactNode }) { return <HostContext.Provider value={value}>{children}</HostContext.Provider>; }\nexport function useMatrxDataTableHost(): MatrxDataTableHost { return useContext(HostContext); }\n","\"use client\";\nimport { Button, type ButtonProps } from \"../button\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../tooltip\";\nimport {\n ChevronsLeft,\n ChevronLeft,\n ChevronsRight,\n ChevronRight,\n} from \"./icons\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../select\";\nimport { cn } from \"../cn\";\nimport { useMatrxDataTableHost, type TableToolbarActionProps } from \"./host\";\nimport type { ComponentType } from \"react\";\n\nexport interface GenericTablePaginationProps {\n totalItems: number;\n itemsPerPage: number;\n currentPage: number;\n onPageChange: (page: number) => void;\n onItemsPerPageChange: (items: number) => void;\n pageSizeOptions?: number[];\n className?: string;\n showItemsPerPageSelect?: boolean;\n showPageInfo?: boolean;\n showPageControls?: boolean;\n maxPagesToShow?: number;\n containerClassName?: string;\n selectContainerClassName?: string;\n infoContainerClassName?: string;\n controlsContainerClassName?: string;\n pageButtonClassName?: string;\n pageActiveButtonClassName?: string;\n navButtonClassName?: string;\n /** Value emitted for the optional All choice. Defaults to the current total. */\n allValue?: number;\n /** Honest label for the optional all-rows choice. */\n allOptionLabel?: string;\n showAllOption?: boolean;\n layoutType?: \"grid\" | \"flex\";\n labelFormat?: (start: number, end: number, total: number) => string;\n compact?: boolean;\n hideEntriesInfo?: boolean;\n /** Keeps progressive local pagination in one stable footer, including at\n * exhaustion. Counts describe rendered rows, not a numbered page. */\n progressive?: { loadedCount?: number; shownCount: number; hasMore: boolean; onShowMore: () => void };\n}\n\nfunction PageNavigationControl({\n label,\n disabledHint,\n visibilityClassName = \"inline-flex\",\n disabled,\n className,\n ...props\n}: ButtonProps & {\n label: string;\n disabledHint: string;\n visibilityClassName?: string;\n}) {\n const button = (\n <Button\n {...props}\n disabled={disabled}\n aria-label={label}\n className={cn(visibilityClassName, className, \"[&_svg]:size-5\")}\n />\n );\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n {disabled ? (\n <span\n className={cn(visibilityClassName, \"rounded-md outline-none focus-visible:ring-2 focus-visible:ring-ring\")}\n tabIndex={0}\n aria-label={`${label} — ${disabledHint.toLowerCase()}`}\n >\n {button}\n </span>\n ) : button}\n </TooltipTrigger>\n <TooltipContent>{disabled ? disabledHint : label}</TooltipContent>\n </Tooltip>\n );\n}\n\nfunction PaginationAction({\n HostAction,\n active = false,\n disabledHint,\n visibilityClassName = \"inline-flex\",\n fallbackClassName,\n ...props\n}: TableToolbarActionProps & {\n HostAction: ComponentType<TableToolbarActionProps> | undefined;\n active?: boolean;\n disabledHint: string;\n visibilityClassName?: string;\n fallbackClassName?: string;\n}) {\n if (HostAction) {\n return (\n <span data-matrx-table-icon-action className={visibilityClassName}>\n <HostAction\n {...props}\n active={active}\n tooltip={props.disabled ? disabledHint : (props.tooltip ?? props.ariaLabel)}\n />\n </span>\n );\n }\n return (\n <PageNavigationControl\n variant=\"outline\"\n size=\"icon\"\n visibilityClassName={visibilityClassName}\n label={props.ariaLabel}\n disabledHint={disabledHint}\n disabled={props.disabled}\n onClick={props.onClick}\n className={cn(\n PAGINATION_ACTION_CLASS,\n active && PAGINATION_ACTIVE_CLASS,\n fallbackClassName,\n )}\n aria-current={active ? \"page\" : undefined}\n data-matrx-table-icon-action\n >\n {props.children}\n </PageNavigationControl>\n );\n}\n\n// Table footers use an actual 44px control shape. A pseudo-element inset into a\n// smaller visual box let the select text and chevron escape its border.\nconst PAGINATION_ACTION_CLASS = \"h-11 w-11 min-h-11 min-w-11 rounded-md border border-border bg-card p-0 text-sm shadow-none hover:bg-accent disabled:opacity-40 [&_svg]:size-5\";\nconst PAGINATION_ACTIVE_CLASS = \"border-primary bg-primary text-primary-foreground hover:bg-primary/90\";\n\nexport default function GenericTablePagination({\n totalItems,\n itemsPerPage,\n currentPage,\n onPageChange,\n onItemsPerPageChange,\n pageSizeOptions = [5, 10, 25, 50, 100],\n className = \"\",\n showItemsPerPageSelect = true,\n showPageInfo = true,\n showPageControls = true,\n maxPagesToShow = 5,\n containerClassName = \"\",\n selectContainerClassName = \"\",\n infoContainerClassName = \"\",\n controlsContainerClassName = \"\",\n pageButtonClassName = \"\",\n pageActiveButtonClassName = \"\",\n navButtonClassName = \"\",\n allValue = totalItems,\n allOptionLabel = \"All\",\n showAllOption = true,\n layoutType = \"grid\",\n labelFormat,\n compact = false,\n hideEntriesInfo = false,\n progressive,\n}: GenericTablePaginationProps) {\n const host = useMatrxDataTableHost();\n const positivePageSizes = pageSizeOptions.filter((size) => size > 0);\n const availablePageSizes =\n itemsPerPage > 0 && !positivePageSizes.includes(itemsPerPage)\n ? [...positivePageSizes, itemsPerPage].sort((a, b) => a - b)\n : positivePageSizes;\n const effectiveItemsPerPage =\n itemsPerPage === 0 ? Math.max(totalItems, 1) : Math.max(itemsPerPage, 1);\n\n const totalPages = Math.max(1, Math.ceil(totalItems / effectiveItemsPerPage));\n\n const getPageNumbers = (limit = maxPagesToShow) => {\n let startPage = Math.max(1, currentPage - Math.floor(limit / 2));\n const endPage = Math.min(totalPages, startPage + limit - 1);\n startPage = Math.max(1, endPage - limit + 1);\n return Array.from(\n { length: endPage - startPage + 1 },\n (_, i) => startPage + i,\n );\n };\n\n const isFirstPageDisabled = currentPage <= 1;\n const isLastPageDisabled = currentPage >= totalPages;\n const startItem = totalItems === 0 ? 0 : progressive ? 1 : (currentPage - 1) * effectiveItemsPerPage + 1;\n const endItem = Math.min(progressive?.shownCount ?? currentPage * effectiveItemsPerPage, totalItems);\n\n const defaultLabelFormat = (start: number, end: number, total: number) => {\n if (progressive) return progressive.loadedCount !== undefined && progressive.loadedCount !== total\n ? `${end} shown / ${total} matching · ${progressive.loadedCount} loaded`\n : `${end} shown / ${total} loaded`;\n return compact\n ? `${start}-${end} of ${total}`\n : `Showing ${start} to ${end} of ${total} entries`;\n };\n\n const formatLabel = labelFormat || defaultLabelFormat;\n\n const containerClass = cn(\n \"w-full items-center\",\n !compact && \"border-t border-border\",\n layoutType === \"grid\"\n ? progressive\n ? \"grid grid-cols-[auto_minmax(0,1fr)_auto]\"\n : \"grid grid-cols-[auto_minmax(0,1fr)] sm:grid-cols-[auto_minmax(0,1fr)_auto]\"\n : \"flex flex-nowrap justify-between\",\n compact\n ? \"box-border min-h-8 gap-0 px-0 py-0\"\n : \"gap-1 px-2 py-1 sm:gap-4 sm:px-3\",\n className,\n containerClassName,\n );\n\n return (\n <TooltipProvider>\n <div data-matrx-table-footer className={containerClass}>\n {/* Items Per Page Select */}\n {showItemsPerPageSelect && (\n <div\n className={cn(\n \"flex min-w-0 justify-start\",\n !compact && \"sm:p-1\",\n selectContainerClassName,\n )}\n >\n <Select\n value={itemsPerPage.toString()}\n onValueChange={(value) => onItemsPerPageChange(parseInt(value))}\n >\n <SelectTrigger\n aria-label={progressive ? \"Visible row limit\" : \"Rows per page\"}\n className={cn(\n \"focus:ring-0\",\n compact\n ? \"h-8 min-h-8 min-w-20 rounded-md border border-border bg-card px-2 text-sm hover:bg-accent [&_svg]:size-4\"\n : \"h-8 w-[3.75rem] text-xs sm:w-36 sm:text-sm\",\n )}\n >\n <SelectValue placeholder={itemsPerPage.toString()} />\n </SelectTrigger>\n <SelectContent>\n {availablePageSizes.map((size) => (\n <SelectItem key={size} value={size.toString()}>\n {size}\n </SelectItem>\n ))}\n {showAllOption ? (\n <SelectItem value={allValue.toString()}>{allOptionLabel}</SelectItem>\n ) : null}\n </SelectContent>\n </Select>\n </div>\n )}\n\n <div\n className={cn(\"flex min-w-0 justify-center\", infoContainerClassName)}\n >\n {/* Page Info - only show if not hidden But always show the div. */}\n {showPageInfo && !hideEntriesInfo && (\n <>\n <span className=\"truncate text-xs tabular-nums text-muted-foreground sm:hidden\">\n {progressive ? `${endItem}/${totalItems} ${progressive.loadedCount !== undefined && progressive.loadedCount !== totalItems ? \"matching\" : \"loaded\"}` : `${startItem}-${endItem} / ${totalItems}`}\n </span>\n <span\n className={`hidden whitespace-nowrap ${\n compact ? \"text-sm\" : \"text-sm\"\n } min-w-0 truncate text-muted-foreground sm:inline`}\n >\n {formatLabel(startItem, endItem, totalItems)}\n </span>\n </>\n )}\n </div>\n\n {/* Page Controls */}\n {progressive ? (progressive.hasMore ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" aria-label=\"Show more rows\"\n className=\"h-8 min-h-8 shrink-0 justify-self-end px-2 text-xs\"\n onClick={progressive.onShowMore}>Show more</Button>\n </TooltipTrigger>\n <TooltipContent>Show more already-loaded rows</TooltipContent>\n </Tooltip>\n ) : null) : showPageControls && (\n <div\n className={cn(\n \"col-span-2 flex min-w-0 items-center justify-end sm:col-span-1\",\n compact ? \"gap-0\" : \"gap-0.5 sm:gap-1\",\n controlsContainerClassName,\n )}\n >\n <PaginationAction\n HostAction={host.ToolbarAction}\n ariaLabel=\"First page\"\n disabledHint=\"Already on the first page\"\n visibilityClassName=\"hidden sm:inline-flex\"\n fallbackClassName={navButtonClassName}\n onClick={() => onPageChange(1)}\n disabled={isFirstPageDisabled}\n >\n <ChevronsLeft className=\"h-5 w-5\" />\n </PaginationAction>\n\n <PaginationAction\n HostAction={host.ToolbarAction}\n ariaLabel=\"Previous page\"\n disabledHint=\"Already on the first page\"\n fallbackClassName={navButtonClassName}\n onClick={() => onPageChange(currentPage - 1)}\n disabled={isFirstPageDisabled}\n >\n <ChevronLeft className=\"h-5 w-5\" />\n </PaginationAction>\n\n {getPageNumbers(3).map((page) => (\n <PaginationAction\n key={`mobile-${page}`}\n HostAction={host.ToolbarAction}\n ariaLabel={`Page ${page}`}\n active={currentPage === page}\n disabledHint={`Already on page ${page}`}\n visibilityClassName={cn(\n \"sm:hidden\",\n page === currentPage ? \"inline-flex\" : \"hidden min-[360px]:inline-flex\",\n )}\n fallbackClassName={page === currentPage ? pageActiveButtonClassName : pageButtonClassName}\n onClick={() => onPageChange(page)}\n >\n <span>{page}</span>\n </PaginationAction>\n ))}\n\n {getPageNumbers().map((page) => (\n <PaginationAction\n key={`desktop-${page}`}\n HostAction={host.ToolbarAction}\n ariaLabel={`Page ${page}`}\n active={currentPage === page}\n disabledHint={`Already on page ${page}`}\n visibilityClassName=\"hidden sm:inline-flex\"\n fallbackClassName={currentPage === page ? pageActiveButtonClassName : pageButtonClassName}\n onClick={() => onPageChange(page)}\n >\n <span>{page}</span>\n </PaginationAction>\n ))}\n\n <PaginationAction\n HostAction={host.ToolbarAction}\n ariaLabel=\"Next page\"\n disabledHint=\"Already on the last page\"\n fallbackClassName={navButtonClassName}\n onClick={() => onPageChange(currentPage + 1)}\n disabled={isLastPageDisabled}\n >\n <ChevronRight className=\"h-5 w-5\" />\n </PaginationAction>\n\n <PaginationAction\n HostAction={host.ToolbarAction}\n ariaLabel=\"Last page\"\n disabledHint=\"Already on the last page\"\n visibilityClassName=\"hidden sm:inline-flex\"\n fallbackClassName={navButtonClassName}\n onClick={() => onPageChange(totalPages)}\n disabled={isLastPageDisabled}\n >\n <ChevronsRight className=\"h-5 w-5\" />\n </PaginationAction>\n </div>\n )}\n </div>\n </TooltipProvider>\n );\n}\n"],"mappings":"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","names":["React","React","jsx","jsx","jsx","jsx","jsx","cva","React","jsx","jsxs","jsx","jsx","jsx","jsxs","cva","jsxs","jsx","createContext","useContext","jsx","useContext","jsx","jsxs"]}
@@ -1,5 +1,5 @@
1
1
  import { ResolvedFilterKind } from './infer-filter.cjs';
2
- import { d as MatrxDataTableQueryState, M as MatrxColumnDef } from '../types-C2yaTspG.cjs';
2
+ import { d as MatrxDataTableQueryState, M as MatrxColumnDef } from '../types-n8d2I1Gu.cjs';
3
3
  import '../extensions-DCHtNwG3.cjs';
4
4
  import '@ai-matrx/kit/content-transfer';
5
5
  import 'react';
@@ -1,5 +1,5 @@
1
1
  import { ResolvedFilterKind } from './infer-filter.js';
2
- import { d as MatrxDataTableQueryState, M as MatrxColumnDef } from '../types-DB30aCHu.js';
2
+ import { d as MatrxDataTableQueryState, M as MatrxColumnDef } from '../types-D_UZxZC5.js';
3
3
  import '../extensions-DCHtNwG3.js';
4
4
  import '@ai-matrx/kit/content-transfer';
5
5
  import 'react';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/data-table/types.ts"],"sourcesContent":["import type { ContentTransferReference } from \"../content-transfer/extensions\";\nimport type { ReactNode } from \"react\";\nimport type { TableSearchRole, TableSearchScope } from \"./ranked-search\";\nimport type { AgentPayloadInput } from \"./copy\";\nimport type {\n AiCustomSource,\n AiVariant,\n} from \"./copy\";\nimport type { LayeredFilterField, LayeredFilterRule } from \"./layered-filters\";\n\n/** How a column's filter UI behaves. `auto` infers from sample values. */\nexport type ColumnFilterKind =\n \"auto\" | \"text\" | \"select\" | \"boolean\" | \"number\" | false;\n\nexport type SortDirection = \"asc\" | \"desc\";\n\n/** How the table's primary search text is matched. */\nexport type TableSearchMatchMode = \"contains\" | \"whole_words\";\n\n/** Cell value type for typed inline editors (Supabase-style popovers for non-strings). */\nexport type CellEditType =\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"select\"\n /** Free-text multi-value chips (string[] cells: tags, labels, aliases). */\n | \"tags\"\n | \"date\"\n | false;\n\nexport interface MatrxColumnDef<T> {\n /** Stable id used for sort/filter state. Defaults to `accessorKey` when set. */\n id?: string;\n /** Dot-free key on the row for default value access + auto filter. */\n accessorKey?: keyof T & string;\n /** Custom value for sort/filter when `accessorKey` is insufficient. */\n accessorFn?: (row: T) => unknown;\n /** Value used only for local sort. Falls back to `accessorFn` / `accessorKey`. */\n sortValue?: (row: T) => unknown;\n /** Value used only for local filters. Falls back to `accessorFn` / `accessorKey`. */\n filterValue?: (row: T) => unknown;\n header: ReactNode;\n /** Plain-text name used for header controls when `header` is visual-only. */\n label?: string;\n /** Cell renderer. Defaults to stringified accessor value. */\n cell?: (row: T, index: number) => ReactNode;\n /** Sortable unless explicitly false. Default true. */\n sortable?: boolean;\n /** Direction used by the first header-click sort. Default `\"asc\"`. */\n defaultSortDirection?: SortDirection;\n /**\n * Filter kind. Default `\"auto\"` — every column gets a filter.\n * Pass `false` only when a column truly must not filter (e.g. actions).\n */\n filter?: ColumnFilterKind;\n /** Explicit select options (when filter is `\"select\"` or auto-detected). */\n filterOptions?: Array<{ value: string; label: string }>;\n /**\n * Single-choice select filter. The default select filter is a multi-select\n * that APPENDS (OR semantics) — correct for a status column, wrong for a\n * column whose options are mutually exclusive VIEWS of the list (a\n * record-class scope, a relative-date bucket). There, appending makes the\n * filter inert: the consumer reads one value, the popover accumulates a set,\n * and the first-selected value wins forever (D218). With `filterSingle`,\n * choosing an option REPLACES the selection, and choosing the active option\n * again clears it.\n */\n filterSingle?: boolean;\n /**\n * Inline edit. Default false. `\"string\"` edits in-cell; other types open a\n * small popover (Supabase-style). Edits stay local until Save on the dirty pill.\n */\n editable?: CellEditType;\n /**\n * Per-row edit gate for an `editable` column. Return false to render the\n * plain cell (no pencil, no click-to-edit) for that row — for heterogeneous\n * lists where some kinds cannot take the write (e.g. a transcripts row of\n * kind \"unsorted\" has no user-facing title). Default: every row editable.\n */\n editableIf?: (row: T) => boolean;\n /**\n * How inline edit starts. Default `\"click\"` (click the cell body). `\"pencil\"`\n * shows a hover/focus pencil; the cell body no longer starts edit — so a\n * whole-row click can own that gesture. Forced to `\"pencil\"` when `href` is\n * set (D112 — the body is a real link).\n */\n editTrigger?: \"click\" | \"pencil\";\n /**\n * Options when `editable === \"select\"`. Also used by `\"tags\"` as the\n * suggestion list (existing values), while still allowing new entries.\n */\n editOptions?: Array<{ value: string; label: string }>;\n /**\n * Row link for the primary/title cell (D112): renders the cell content as a\n * real `next/link` anchor, so the row is reachable by keyboard, announced as\n * a link by screen readers, and cmd/middle-clickable into a new tab. The\n * whole-row `onRowOpen` click stays as a mouse convenience; clicks on the\n * anchor never double-fire it. Combine with `editable` and the link renders\n * with a hover/focus pencil that opens the inline editor instead of\n * click-text-to-edit.\n */\n href?: (row: T) => string | undefined;\n /**\n * Canonical entity token for the record this column NAMES. When set, the cell\n * renders through `EntityRef`, so the name carries the full door set — Open,\n * new tab, and Peek — instead of the Open-only `<Link>` that `href` alone\n * produces.\n *\n * THE INVENTORY LAW, applied to this component: the table grew its own door\n * (`href`) beside the platform's (`EntityRef`), and every column that named a\n * record picked one and silently lost the other half. This field collapses\n * them — `href` still works and still forces the pencil trigger, and it\n * OVERRIDES the registry route when both are set (for an admin-side route on\n * a satellite deployment).\n *\n * Needs the record's id: `entityToken` is paired with `entityId`, defaulting\n * to the table's own `getRowId`.\n *\n * **PER ROW, not per column** — a hub can be heterogeneous. `/transcripts`\n * lists transcripts, studio sessions, cleanup runs and an \"unsorted\" bucket\n * in one table, each with its own destination; a constant token would have\n * sent a session id to the transcript processor route and opened the\n * transcript peek on a record that is not one. Return `undefined` for a row\n * that names no entity — it falls back to the plain `href` link, or to inert\n * text. Pair with a per-row `href` when the kinds diverge.\n */\n entityToken?: string | ((row: T) => string | undefined);\n /**\n * NOTE: give the column a `cell` when you set this. Without one, a\n * UUID-shaped value renders the default `MatrxUuidCell`, which has its own\n * controls — wrapping those in the door's anchor would nest interactive\n * elements inside a link, and is redundant besides. The shell detects that\n * combination, skips the door, and screams once per column.\n */\n /** The id `entityToken` refers to. Defaults to the table's `getRowId(row)`. */\n entityId?: (row: T) => string | undefined;\n /**\n * Drop this column below `sm` (the phone breakpoint).\n *\n * A wide table on a phone becomes a horizontal scroller: the frozen\n * identity column stays, and everything after the second column sits off\n * the right edge where a reviewer will never find it. Marking the columns\n * that do NOT earn their width on a phone is how a surface declares an\n * INTENTIONAL mobile column set instead of an accidental one.\n *\n * The column is still fully sortable/filterable from the toolbar and still\n * rides every copy/export payload — this hides the CELL, not the data.\n * Default `false` = today's behavior everywhere.\n */\n mobileHidden?: boolean;\n /**\n * Built-in cell kinds. `\"uuid\"` / `\"fk\"` use MatrxUuidCell (short + copy +\n * optional open). `\"auto\"` (default) detects UUID-shaped strings.\n */\n cellKind?: \"auto\" | \"uuid\" | \"fk\" | \"text\";\n /**\n * FK / UUID navigation. Prefer `onOpen` → WindowPanel of the target.\n * Return `\"forbidden\"` when the caller lacks access.\n */\n fk?: {\n label?: string;\n /**\n * Canonical entity token this column's ids point at (`agent`, `note`, …).\n * THE DOOR LAW made declarative: the cell resolves route + new tab + peek\n * from the registries, so a column of ids stops being a dead end without\n * hand-wiring a link. `href` / `onOpen` still win when both are set.\n * A function form resolves the token per row (an audit log whose target\n * type varies by row).\n *\n * `\"auto\"` derives the token from the COLUMN NAME (`task_id` → `task`).\n * It is opt-in on purpose: the guess is only correct when you have checked\n * the actual FK. `scheduler.sch_run.task_id` references `scheduler.sch_task`,\n * not the workspace `task` the name implies, and `app_id` /\n * `conversation_id` / `file_id` / `workflow_id` each have several candidate\n * tables. A wrong door opens a DIFFERENT record — worse than no door.\n */\n token?: string | null | \"auto\" | ((row: T) => string | null | undefined);\n href?: (id: string, row: T) => string | null | undefined;\n onOpen?: (\n id: string,\n row: T,\n ) => void | \"forbidden\" | Promise<void | \"forbidden\">;\n /** Force non-navigable for this column. */\n forbidden?: boolean | ((id: string, row: T) => boolean);\n };\n className?: string;\n headerClassName?: string;\n width?: string | number;\n /** Enable desktop resizing for this column. Defaults to true when the table enables it. */\n resizable?: boolean;\n /** Desktop resize boundary. Defaults to 80px. */\n minWidth?: number;\n /** Desktop resize boundary. Defaults to 1200px. */\n maxWidth?: number;\n align?: \"left\" | \"center\" | \"right\";\n /**\n * ICON COLUMN. A column whose whole content is one glyph — a star, a lock, a\n * status dot — and whose `width` is therefore a lie without this flag.\n *\n * `width` is only a hint on a table cell: min-content wins. A 40px star column\n * still rendered ~70px wide because the HEADER carried three separate\n * controls beside the glyph (the sort button, its arrow, the filter funnel),\n * and the cell carried the default `px-2` on both sides. Every surface that\n * wanted a tight icon column was paying for chrome it never used.\n *\n * `compact` fixes it AT THE PRIMITIVE, and does NOT cost the column anything:\n * horizontal padding drops to `px-1`, and the header collapses its three\n * controls into ONE popover trigger that still offers Sort ascending / Sort\n * descending / Clear sort / the full filter body. The column stays fully\n * sortable and filterable — the affordances moved into the menu, they did not\n * disappear. Active sort/filter still show, as a 2px dot on the trigger.\n *\n * Pair it with `width` and `align: \"center\"`.\n */\n compact?: boolean;\n /** Hide from the table (still available in column picker when we add it). */\n hidden?: boolean;\n /** Whether the package-owned Columns dialog may hide this column. Default true. */\n hideable?: boolean;\n}\n\n/** How a text filter matches. Default `\"contains\"`. */\nexport type TextFilterMode = \"contains\" | \"empty\" | \"not_empty\" | \"null\" | \"not_null\";\n\n/** Active per-column filter value. Shape depends on filter kind. */\nexport type ColumnFilterValue =\n | { kind: \"text\"; value: string; mode?: TextFilterMode; negated?: boolean }\n | {\n kind: \"select\";\n /** Single-choice value (legacy writers). Ignored when `values` is set. */\n value: string;\n /** Multi-choice OR set — a row passes if it matches ANY entry. */\n values?: string[];\n /** Exclude matching values instead of including them. */\n negated?: boolean;\n }\n | { kind: \"boolean\"; value: boolean; negated?: boolean }\n | { kind: \"number\"; min?: number | undefined; max?: number | undefined; negated?: boolean };\n\nexport type ColumnFiltersState = Record<string, ColumnFilterValue | undefined>;\n\nexport interface SortState {\n id: string;\n direction: SortDirection;\n}\n\n/**\n * Opt-in durable URL state for a local table.\n *\n * Every table gets an explicit stable id, producing namespaced parameters such\n * as `table.accounts.q` and `table.accounts.sort`. This prevents collisions\n * with page-owned parameters and with sibling tables on the same route.\n */\nexport interface MatrxDataTableUrlStateConfig {\n /** Stable lowercase identifier: letters, numbers, and hyphens; max 64 chars. */\n id: string;\n /** Initial sort when the URL carries none. Default: none. */\n defaultSort?: SortState | null | undefined;\n /** Browser history behavior for table transitions. Default: `push`. */\n history?: \"push\" | \"replace\" | undefined;\n /**\n * History behavior while typing search/any-of text. `session` pushes the\n * first edit, then replaces rapid keystrokes. Default: `session`.\n */\n textHistory?: \"session\" | \"push\" | \"replace\" | undefined;\n /** Persist the open side-panel row. Default true. */\n selectedRow?: boolean;\n /** Persist the open table-owned window row. Default true. */\n windowRow?: boolean;\n /** Persist checkbox selection. Opt-in because large selections lengthen URLs. */\n selection?: boolean;\n}\n\n/**\n * Complete view state for a remotely queried table page. The table owns none\n * of this state in controlled mode: callers may mirror it to URL search params\n * and use it as part of a direct database-query cache key.\n */\nexport interface MatrxDataTableQueryState {\n /** One-based page number, matching the table's pagination UI. */\n page: number;\n pageSize: number;\n search: string;\n /** Defaults to `contains` when omitted, preserving every existing table. */\n searchMatchMode?: TableSearchMatchMode;\n /** Selected intelligent-search scope. Omitted means the backward-compatible All scope. */\n searchScope?: string;\n anyOf: string;\n /** Ordered AND rules from the compact advanced-filter builder. */\n layeredFilters?: LayeredFilterRule[];\n columnFilters: ColumnFiltersState;\n sort: SortState | null;\n}\n\n/**\n * Optional data-processing contract. Omit it (or use `local`) to preserve the\n * original in-memory filter/sort/pagination behavior. In controlled mode,\n * `data` is already the current page and the caller performs all querying.\n */\n/** Structural match for @ai-matrx/data/react usePaginatedData. */\nexport interface MatrxTablePagination<T> {\n queryKey: string;\n rows: T[];\n loading: boolean;\n isFetchingNextPage: boolean;\n error: Error | null;\n hasNextPage: boolean;\n loadNextPage: () => Promise<void>;\n refresh: () => void;\n totalItems: number | undefined;\n loadAll?: { isLoading: boolean; request: () => void; stop: () => void };\n retrySource?: () => void;\n sourceUntil?: string;\n sourcePageSize?: { value: number; options: readonly number[]; onChange: (value: number) => void };\n}\n\n/**\n * A controlled-local table can retain local search/pagination while its source\n * owns column filters and/or sorting. `sourceTotal` is display metadata only:\n * it never changes local page slicing, because the loaded rows remain local.\n */\nexport interface MatrxDataTableSourceProcessing {\n search?: \"local\" | \"source\";\n /** Source accepts and ranks `searchScope`; omit to keep scope UI local-only. */\n intelligentSearch?: \"local\" | \"source\";\n columnFilters?: \"local\" | \"source\";\n sort?: \"local\" | \"source\";\n sourceTotal?: number;\n}\n\nexport type MatrxDataTableQueryControl<T = unknown> =\n | { mode: \"local\" }\n | {\n /** Accumulated server rows; page stays 1 and sort/filter remain server-owned. */\n mode: \"controlled-append\";\n state: MatrxDataTableQueryState;\n onStateChange: (next: MatrxDataTableQueryState) => void;\n pagination: MatrxTablePagination<T>;\n sourceProcessing?: MatrxDataTableSourceProcessing;\n /** Source-connected tables append on user scroll by default. */\n scroll?: { thresholdPx?: number; intentTimeoutMs?: number } & (\n | { mode?: \"scroll\" }\n | { mode: \"manual\"; reason: string; approvedBy: string }\n /** Temporary configuration state: automatic append is off, but Load more stays available. */\n | { mode: \"suspended\"; reason: string }\n );\n }\n | {\n /** Local rows, but every query control is owned by the caller (for URL state). */\n mode: \"controlled-local\";\n state: MatrxDataTableQueryState;\n onStateChange: (next: MatrxDataTableQueryState) => void;\n sourceProcessing?: MatrxDataTableSourceProcessing;\n }\n | {\n mode: \"controlled\";\n state: MatrxDataTableQueryState;\n /** Total rows matching the controlled query, not just `data.length`. */\n totalItems: number;\n onStateChange: (next: MatrxDataTableQueryState) => void;\n /** Declare source-owned query behavior before enabling source-aware controls. */\n sourceProcessing?: MatrxDataTableSourceProcessing;\n };\n\n/**\n * Toolbar facets — first-class, Mars-extensible filter controls above the grid.\n * Start with button-group; add radio / switch / complex later without forking.\n */\nexport type ToolbarFacet =\n | {\n type: \"button-group\";\n id: string;\n label?: string;\n value: string;\n /** Reset target for per-facet + global clear. Default: first option value. */\n defaultValue?: string;\n options: Array<{\n value: string;\n label: string;\n icon?: ReactNode;\n }>;\n onChange: (value: string) => void;\n }\n | {\n type: \"custom\";\n id: string;\n render: () => ReactNode;\n };\n\n/**\n * Cross-column OR search — matches if ANY listed column contains the query.\n * Relationships use case: filter by entity type without picking source vs target.\n */\nexport interface AnyOfColumnSearch {\n columnIds: string[];\n placeholder?: string;\n /** Controlled value. Uncontrolled if omitted. */\n value?: string;\n onChange?: (value: string) => void;\n}\n\nexport interface MatrxDataTableToolbar {\n /** Optional human-readable table title, rendered by the shared title row. */\n title?: string;\n /** Global search across all accessor values. Default true. */\n search?: boolean;\n searchPlaceholder?: string;\n searchValue?: string;\n onSearchChange?: (value: string) => void;\n /**\n * Show a compact, visible choice between substring and whole-word search.\n * Omit it when a data source cannot honor both modes server-side.\n */\n searchMatch?: {\n defaultMode?: TableSearchMatchMode;\n };\n /** Prototype ranked search. Local tables rank complete loaded rows before pagination. */\n intelligentSearch?: {\n roles?: Readonly<Record<string, TableSearchRole>>;\n scopes?: readonly TableSearchScope[];\n };\n /**\n * OR-search across specific columns (e.g. source_type OR target_type).\n * Shown as its own input beside global search when set.\n */\n anyOf?: AnyOfColumnSearch;\n /**\n * Optional compact advanced-filter builder beside the regular search. In\n * controlled mode rules live in `query.state.layeredFilters`; local tables\n * evaluate them against matching column ids.\n */\n layeredFilters?: {\n fields: readonly LayeredFilterField[];\n maxRules?: number;\n label?: string;\n };\n /** Extensible facet strip (button groups, later radios/switches/…). */\n facets?: ToolbarFacet[];\n /** Source controls in a separate wrapping row below the standard toolbar. */\n leading?: ReactNode;\n /**\n * Standard host refresh affordance. The package owns its placement, busy\n * state, accessible tooltip, and glyphs (refresh arrows at rest, spinner\n * only while busy); the host remains the sole data owner.\n */\n refresh?: {\n onRefresh: () => void | Promise<void>;\n label?: string;\n };\n /**\n * Standard create affordance. The host owns authorization and the actual\n * create flow; disabledReason is exposed through the shared tooltip.\n */\n add?: {\n onAdd: () => void | Promise<void>;\n disabled?: boolean;\n disabledReason?: string;\n };\n /** Right-side domain actions, rendered after standard table controls. */\n actions?: ReactNode;\n}\n\n/** Query fields safe to persist in a named table view. */\nexport type TableViewQuery = Omit<MatrxDataTableQueryState, \"page\">;\n\n/** Portable, persistence-neutral table state saved by a host adapter. */\nexport interface TableViewSnapshot {\n __kind: \"matrx-table-view\";\n version: 1;\n /** Page/cursor/selection/loaded rows are deliberately never saved. */\n query: TableViewQuery;\n /** `widths` is sparse so views saved before resize remain valid. */\n columns: { order: string[]; hidden: string[]; widths?: Record<string, number> };\n}\n\n/** Host port for durable named views. The host owns actor, tenancy and CRUD. */\nexport interface TableSavedViewsProps {\n tableId: string;\n snapshot: TableViewSnapshot;\n defaultSnapshot: TableViewSnapshot;\n onApply: (snapshot: TableViewSnapshot) => void;\n}\n\n/** Optional deferred-apply copy for column filter popovers. */\nexport interface MatrxDataTableFilterUi {\n /** Enables the Include/Exclude control. Default false for remote-safe filters. */\n allowNegation?: boolean;\n /** Enables null/not-null text modes. Default false for remote-safe filters. */\n allowNullModes?: boolean;\n applyLabel?: string;\n showCancel?: boolean;\n footerHint?: ReactNode;\n}\n\nexport interface MatrxDataTableCopyConfig<T> {\n /** Explicit registered identities; never inferred from table labels or row shapes. */\n rowReferences?: (row: T) => readonly ContentTransferReference[];\n references?: (visible: T[], all: T[]) => readonly ContentTransferReference[];\n triggerVariant?: \"transparent\" | \"glass\" | \"outline\";\n /** Toast / tooltip label base, e.g. \"Relationship rule\". */\n label: string;\n listLabel?: string;\n location: string;\n rowKind: string;\n listKind: string;\n rowDescription?: string;\n listDescription?: string;\n humanRow: (row: T) => string;\n /** Project row for agent JSON. Default: full row. */\n agentRow?: (row: T) => unknown;\n rowAttributes?: (\n row: T,\n ) => Record<string, string | number | boolean | null | undefined>;\n listAttributes?: (\n visible: T[],\n all: T[],\n ) => Record<string, string | number | boolean | null | undefined>;\n /**\n * Live view state rendered inside the list payload's <context>. Unlike\n * per-row data, this remains present when the current view has zero rows.\n */\n listContext?: (\n visible: T[],\n all: T[],\n ) => Record<string, string | number | boolean | null | undefined>;\n /**\n * Additional row-scoped AI actions. Use this to fold a domain action such\n * as a paste-ready repair brief into the table-owned row copy menu instead\n * of rendering a separate third control. Builders run at click time.\n */\n rowAiVariants?: (row: T) => AiVariant[];\n /**\n * Graded AI variants for the toolbar's view copy (e.g. \"Top 25\", \"Summary\n * only\"). When set, the toolbar's Copy-for-AI upgrades to a dropdown with\n * these variants + the full-view payload as the automatic \"Everything\"\n * escape hatch. Receives (visible, all) rows at render; builders run at\n * click time.\n */\n aiVariants?: (visible: T[], all: T[]) => AiVariant[];\n /** Custom-preview source (options dialog + live size counts) for the view. */\n aiCustom?: (visible: T[], all: T[]) => AiCustomSource;\n /** Show toolbar copy (this view). Default true when copy is set. */\n showToolbar?: boolean;\n /** Show per-row copy. Default true when copy is set. */\n showRow?: boolean;\n}\n\nexport interface MatrxDataTableDetailConfig<T> {\n /** Side-panel title. Default: first string column or \"Details\". */\n title?: (row: T) => ReactNode;\n description?: (row: T) => ReactNode | undefined;\n /** Override the default key/value inspector. */\n render?: (row: T, controls: MatrxDataTableRecordControls) => ReactNode;\n /** Header actions inside the side panel. */\n headerActions?: (row: T) => ReactNode;\n defaultWidth?: number;\n enabled?: boolean;\n /**\n * Maps a field name to the entity token its id points at, turning that field\n * into a door (route + peek) in the default inspector — side panel AND row\n * window.\n *\n * There is no default guess: this inspector renders whatever columns the row\n * has, and a wrong door opens a DIFFERENT record (`sch_run.task_id` is a\n * SCHEDULED task, not a workspace `task`). A table whose FKs you HAVE checked\n * can pass `tokenFromColumnName` (`components/official/entity-ref/doors`) to\n * open every `<token>_id` field at once.\n *\n * The ROW is passed too, because a table whose target type varies per row (an\n * audit log, an exposure report) cannot answer from the column name alone.\n */\n tokenForField?: (key: string, row: T) => string | null;\n}\n\n/** Actions a record-owned control can use without reaching into table state. */\nexport interface MatrxDataTableRecordControls {\n /** Close the row's side-panel detail, if open. */\n closeDetail: () => void;\n /** Open the row in the canonical adjustable side panel. */\n openDetail: () => void;\n /** Open the row in its canonical table-owned WindowPanel. */\n openWindow: () => void;\n /** Close the row's table-owned WindowPanel, if open. */\n closeWindow: () => void;\n /** Whether this row currently has visible, unpersisted inline edits. */\n hasPendingEdits: boolean;\n /**\n * Discard this row's pending inline edits.\n *\n * Row actions that persist the already-merged visible row (for example an\n * explicit Confirm action) call this only after that write succeeds. This\n * prevents the floating Save pill from later replaying the same draft as a\n * different, weaker write.\n */\n discardPendingEdits: () => void;\n}\n\nexport interface MatrxDataTableWindowConfig<T> {\n /** Window title. */\n title?: (row: T) => string;\n /**\n * @deprecated Prefer `renderView` + `renderEdit` so the window stays editable.\n * Full-body override with no View/Edit tabs.\n */\n render?: (row: T, controls: MatrxDataTableRecordControls) => ReactNode;\n /** View tab body. Defaults to DataRowInspector. */\n renderView?: (row: T, controls: MatrxDataTableRecordControls) => ReactNode;\n /**\n * Edit tab body. When set, the WindowPanel shows View / Edit sidebar tabs\n * (WindowPanel built-in sidebar). Defaults to `detail.render` when present.\n * Pass `false` to keep a view-only window even when `detail.render` exists.\n */\n renderEdit?:\n ((row: T, controls: MatrxDataTableRecordControls) => ReactNode) | false;\n /**\n * Called when the panel icon opens the window — hydrate edit state here\n * without opening the side panel (prefer this over `onRowOpen` for windows).\n */\n onOpen?: (row: T) => void;\n /**\n * Make full-row click open the WindowPanel instead of the side panel.\n * The trailing row action and the window header then expose the side panel\n * as the explicit secondary presentation. Default false.\n */\n openOnRowClick?: boolean;\n /** Which tab to open. Default: `\"edit\"` when an edit body exists. */\n defaultTab?: \"view\" | \"edit\";\n /** Show the panel-icon that opens the window. Default true when detail enabled. */\n enabled?: boolean;\n width?: number;\n height?: number;\n}\n\nexport interface MatrxDataTableEmptyState {\n icon?: ReactNode;\n title: string;\n description?: string;\n action?: ReactNode;\n}\n\n/** Pending cell edits keyed by row id → partial field map. */\nexport type CellEditsMap = Record<string, Record<string, unknown>>;\n\nexport interface MatrxDataTableEditConfig<T> {\n /** Enable inline editing for columns with `editable` set. */\n enabled?: boolean;\n /**\n * Persist all pending edits. Called when the user clicks Save on the dirty pill.\n * Return resolved when done; throw/reject to keep the draft (with toast).\n */\n onSave: (edits: CellEditsMap, rows: T[]) => void | Promise<void>;\n /** Persist each committed cell immediately. Failed writes remain in the\n * dirty pill so the user can retry or cancel them. */\n autoSave?: boolean;\n /** Optional cancel hook (draft already discarded). */\n onCancel?: () => void;\n}\n\nexport interface MatrxDataTableHierarchyConfig<T> {\n /** Complete hierarchy when `data` is only the current controlled page. */\n rows?: T[];\n getParentId: (row: T) => string | null;\n /** Persist the exact structural intent represented by the drop shadow. */\n onMove: (row: T, move: MatrxDataTableHierarchyMove) => void | Promise<void>;\n /** Enables sibling insertion shadows in addition to parent/root drops. */\n manualOrder?: boolean;\n canReparent?: (row: T) => boolean;\n itemLabel?: (row: T) => string;\n rootDropLabel?: string;\n}\n\nexport interface MatrxDataTableHierarchyMove {\n parentId: string | null;\n /**\n * Insert immediately before this sibling. Null means first child for\n * \"inside\"/\"root\", and LAST sibling for \"after\" (target had no successor).\n */\n beforeId: string | null;\n position: \"before\" | \"after\" | \"inside\" | \"root\";\n targetId: string | null;\n}\n\n/**\n * Multi-row selection — a leading checkbox column plus a bulk bar that appears\n * only while rows are checked.\n *\n * OPT-IN and fully CONTROLLED: the consumer owns the id set, so selection\n * survives (or is deliberately cleared by) a re-fetch, a filter change, or an\n * optimistic list update — the table never holds hidden selection state that\n * can disagree with the surface around it.\n *\n * Why this is a primitive and not a per-surface checkbox column: a register\n * the user cannot clear in bulk is a register they stop reading, and the fifth\n * hand-rolled selection column — each with its own shift-click, its own\n * select-all semantics, its own bar — is exactly the fork `components/official/`\n * exists to prevent.\n *\n * Selection does not alter mobile horizontal scrolling. The complete row moves\n * as one surface below `sm`; no leading column is allowed to pin over the data.\n */\nexport interface MatrxDataTableSelectionConfig<T> {\n /** Selected row ids (`getRowId`). Ids not on the current page are kept. */\n selectedIds: string[];\n onSelectedIdsChange: (ids: string[]) => void;\n /**\n * The bulk bar's actions, given the currently-selected rows THAT ARE LOADED.\n * Selection can outlive a page change, so also take `selectedIds` when an\n * action only needs ids.\n */\n actions?: (selected: T[], selectedIds: string[]) => ReactNode;\n /**\n * Rows that cannot be acted on in bulk render NO checkbox at all — the cell\n * stays for alignment, the control is absent from the DOM. A greyed control\n * still advertises a choice the surface underneath would refuse.\n */\n isRowSelectable?: (row: T) => boolean;\n /** Singular noun for the bar's count (\"finding\" → \"3 findings selected\"). */\n noun?: string;\n}\n\n/** Table-owned state and actions exposed to an opt-in phone card renderer. */\nexport interface MatrxDataTableMobileCardControls {\n /** Render a declared column with the same editable/draft/link behavior as the grid. */\n renderCell: (columnId: string) => ReactNode;\n /** Whether this row is in the canonical selection set. */\n selected: boolean;\n /** Whether the consumer allows this row to be selected. */\n selectable: boolean;\n /** Update selection through the table's controlled/URL-backed contract. */\n onSelectedChange: (selected: boolean) => void;\n /**\n * The table's canonical per-row copy controls plus consumer row actions.\n * Render this instead of rebuilding either action path inside the card.\n */\n actions: ReactNode;\n}\n\nexport type MatrxDataTableDensity = \"condensed\" | \"normal\" | \"spacious\";\n\nexport interface MatrxDataTableProps<T> {\n data: T[];\n columns: MatrxColumnDef<T>[];\n /** Table-local visual density. An explicit value wins over the host default. */\n density?: MatrxDataTableDensity;\n /** Stable persistence identity for host-installed named views. */\n tableId?: string;\n /** Declared reset state for the host Saved Views control. */\n defaultViewSnapshot?: TableViewSnapshot;\n /** Optional URL/source-owned column order and visibility. */\n columnState?: {\n order: string[];\n hidden: string[];\n onChange: (next: { order: string[]; hidden: string[] }) => void;\n /** Optional source-owned desktop widths keyed by canonical column id. */\n widths?: Record<string, number>;\n /** Required to persist controlled width changes across remounts. */\n onWidthsChange?: (widths: Record<string, number>) => void;\n };\n /** Enables package-owned drag reordering in table headers. Default true. */\n reorderableColumns?: boolean;\n /** Enables desktop column resizing. Default true; handles are absent below `sm`. */\n resizableColumns?: boolean;\n columnManager?: { open: boolean; onOpenChange: (open: boolean) => void };\n getRowId: (row: T) => string;\n /**\n * Additional row identity included in local global search without becoming\n * a visible/sortable/filterable column. Use for canonical composite keys or\n * aliases whose displayed parts live in separate columns.\n *\n * Ignored in remote controlled mode, where the query owner applies search.\n */\n searchText?: (row: T) => string;\n /**\n * Hierarchy-aware local processing seam. The canonical table still owns the\n * toolbar, URL state, headers, pagination, editing, copy, and rendering; the\n * consumer only preserves domain ordering that a flat sort would destroy.\n *\n * The processor must honor every active query control in `state` and return\n * the complete filtered/sorted local result before pagination. It is ignored\n * in remote controlled mode, where `data` is already the queried page.\n */\n processLocalRows?: (rows: T[], state: MatrxDataTableQueryState) => T[];\n /** Initial local sort when neither URL state nor a controlled query owns it. */\n defaultSort?: SortState | null;\n isLoading?: boolean;\n /**\n * Background refresh state. Unlike `isLoading`, this preserves rendered rows\n * and shows only the table's non-blocking refresh indicator.\n */\n isFetching?: boolean;\n /**\n * Controlled query state for direct remote data sources. The component never\n * fetches data itself; it only emits state changes to the caller.\n */\n query?: MatrxDataTableQueryControl<T>;\n /**\n * Persist local query and record-view state in namespaced URL parameters.\n * This is intentionally opt-in and cannot be combined with controlled query\n * mode; remote tables use `useTableUrlState({ tableId })` in their query owner.\n */\n urlState?: MatrxDataTableUrlStateConfig;\n\n toolbar?: MatrxDataTableToolbar;\n /** Hide the package toolbar while retaining table-owned query behavior. */\n hideToolbar?: boolean;\n /** Hide numbered pagination; local rows remain available to the caller. */\n hidePagination?: boolean;\n /** Optional deferred Apply/Cancel copy for column filter popovers. */\n filterUi?: MatrxDataTableFilterUi;\n /** Row click opens the side panel unless `window.openOnRowClick` is true. */\n detail?: MatrxDataTableDetailConfig<T>;\n /** Panel icon opens a WindowPanel (page-local; supports ReactNode override). */\n window?: MatrxDataTableWindowConfig<T>;\n /** Copy + Copy for AI (rows + this view). Omit for the declared-column default; false suppresses it. */\n copy?: false | MatrxDataTableCopyConfig<T>;\n /** Inline edit session with floating Save/Cancel pill. */\n edit?: MatrxDataTableEditConfig<T>;\n /** Opt-in tree reparenting owned by the canonical row renderer. */\n hierarchy?: MatrxDataTableHierarchyConfig<T>;\n\n /** Controlled selection (selected row id for highlight). */\n selectedId?: string | null | undefined;\n onSelectedIdChange?: ((id: string | null) => void) | undefined;\n\n /** Controlled table-owned window row (normally supplied by URL state). */\n windowRowId?: string | null | undefined;\n onWindowRowIdChange?: ((id: string | null) => void) | undefined;\n\n /** Opt-in multi-row checkbox selection + a bulk action bar. */\n selection?: MatrxDataTableSelectionConfig<T>;\n\n /** Extra row actions rendered in a trailing Actions column. */\n rowActions?: (row: T, controls: MatrxDataTableRecordControls) => ReactNode;\n /** Extra rows rendered in the table footer with the same columns as data rows. */\n footerRows?: T[];\n /** Per-row presentation class, after canonical selection/highlight state. */\n rowClassName?: (row: T, index: number) => string | undefined;\n /** Highlight an index in the currently rendered page without selecting it. */\n highlightedIndex?: number | undefined;\n /** Receives the complete visible local view after local processing, before paging. Attaching after absence receives one snapshot; callback identity changes alone do not notify. */\n onViewChange?: (rows: T[]) => void;\n /**\n * Wrap the whole `<tr>`. Return `children` unchanged for no-op.\n *\n * `rowActions` only reaches the actions CELL, so anything that must own the\n * entire row — a right-click menu, a drag handle, a drop target — had no\n * seam and would have forced a surface to fork the table. THE INVENTORY LAW:\n * the fork is the defect, so the seam exists instead.\n *\n * Whatever you return must render `children` as a direct `<tbody>` child, so\n * the wrapper has to be a component that emits the `<tr>` unchanged\n * (`ItemContextMenu` does — it renders a Radix trigger with `asChild`).\n */\n rowWrapper?: (row: T, children: ReactNode) => ReactNode;\n\n emptyState?: MatrxDataTableEmptyState;\n /** Default 25. Pass 0 to show all. */\n pageSize?: number;\n /** Complete local results reveal on physical scroll by default. Numbered\n * paging is an explicit exception requiring its reason and approving owner. */\n localPagination?:\n | { mode?: \"progressive\" }\n | { mode: \"numbered\"; reason: string; approvedBy: string };\n pageSizeOptions?: number[];\n zebra?: boolean;\n className?: string;\n tableClassName?: string;\n /**\n * Optional compact row presentation rendered below `mobileCardsBreakpoint`\n * in place of the horizontal table. The caller supplies the record summary\n * because only the product surface knows which values and actions are\n * essential at narrow widths; MatrxDataTable still owns query state,\n * loading/empty states, and pagination.\n *\n * `controls.actions` carries the table-owned copy controls and consumer row\n * actions, so a card does not fork them. Prefer the default horizontal table\n * unless the product explicitly requires every essential value/action to be\n * discoverable without horizontal scrolling.\n */\n mobileCards?: (\n row: T,\n index: number,\n controls: MatrxDataTableMobileCardControls,\n ) => ReactNode;\n /** Card/table handoff. `sm` is phone-only; `lg` includes portrait tablets. */\n mobileCardsBreakpoint?: \"sm\" | \"lg\";\n /** Called after a row is selected for detail (in addition to opening the panel). */\n onRowOpen?: (row: T) => void;\n}\n\n/** Re-export for callers building custom agent payloads. */\nexport type { AgentPayloadInput };\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../src/data-table/types.ts"],"sourcesContent":["import type { ContentTransferReference } from \"../content-transfer/extensions\";\nimport type { ReactNode } from \"react\";\nimport type { TableSearchRole, TableSearchScope } from \"./ranked-search\";\nimport type { AgentPayloadInput } from \"./copy\";\nimport type {\n AiCustomSource,\n AiVariant,\n} from \"./copy\";\nimport type { LayeredFilterField, LayeredFilterRule } from \"./layered-filters\";\n\n/** How a column's filter UI behaves. `auto` infers from sample values. */\nexport type ColumnFilterKind =\n \"auto\" | \"text\" | \"select\" | \"boolean\" | \"number\" | false;\n\nexport type SortDirection = \"asc\" | \"desc\";\n\n/** How the table's primary search text is matched. */\nexport type TableSearchMatchMode = \"contains\" | \"whole_words\";\n\n/** Cell value type for typed inline editors (Supabase-style popovers for non-strings). */\nexport type CellEditType =\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"select\"\n /** Free-text multi-value chips (string[] cells: tags, labels, aliases). */\n | \"tags\"\n | \"date\"\n | false;\n\nexport interface MatrxColumnDef<T> {\n /** Stable id used for sort/filter state. Defaults to `accessorKey` when set. */\n id?: string;\n /** Dot-free key on the row for default value access + auto filter. */\n accessorKey?: keyof T & string;\n /** Custom value for sort/filter when `accessorKey` is insufficient. */\n accessorFn?: (row: T) => unknown;\n /** Value used only for local sort. Falls back to `accessorFn` / `accessorKey`. */\n sortValue?: (row: T) => unknown;\n /** Value used only for local filters. Falls back to `accessorFn` / `accessorKey`. */\n filterValue?: (row: T) => unknown;\n header: ReactNode;\n /** Plain-text name used for header controls when `header` is visual-only. */\n label?: string;\n /** Cell renderer. Defaults to stringified accessor value. */\n cell?: (row: T, index: number) => ReactNode;\n /** Sortable unless explicitly false. Default true. */\n sortable?: boolean;\n /** Direction used by the first header-click sort. Default `\"asc\"`. */\n defaultSortDirection?: SortDirection;\n /**\n * Filter kind. Default `\"auto\"` — every column gets a filter.\n * Pass `false` only when a column truly must not filter (e.g. actions).\n */\n filter?: ColumnFilterKind;\n /** Explicit select options (when filter is `\"select\"` or auto-detected). */\n filterOptions?: Array<{ value: string; label: string }>;\n /**\n * Single-choice select filter. The default select filter is a multi-select\n * that APPENDS (OR semantics) — correct for a status column, wrong for a\n * column whose options are mutually exclusive VIEWS of the list (a\n * record-class scope, a relative-date bucket). There, appending makes the\n * filter inert: the consumer reads one value, the popover accumulates a set,\n * and the first-selected value wins forever (D218). With `filterSingle`,\n * choosing an option REPLACES the selection, and choosing the active option\n * again clears it.\n */\n filterSingle?: boolean;\n /**\n * Inline edit. Default false. `\"string\"` edits in-cell; other types open a\n * small popover (Supabase-style). Edits stay local until Save on the dirty pill.\n */\n editable?: CellEditType;\n /**\n * Per-row edit gate for an `editable` column. Return false to render the\n * plain cell (no pencil, no click-to-edit) for that row — for heterogeneous\n * lists where some kinds cannot take the write (e.g. a transcripts row of\n * kind \"unsorted\" has no user-facing title). Default: every row editable.\n */\n editableIf?: (row: T) => boolean;\n /**\n * How inline edit starts. Default `\"click\"` (click the cell body). `\"pencil\"`\n * shows a hover/focus pencil; the cell body no longer starts edit — so a\n * whole-row click can own that gesture. Forced to `\"pencil\"` when `href` is\n * set (D112 — the body is a real link).\n */\n editTrigger?: \"click\" | \"pencil\";\n /**\n * Options when `editable === \"select\"`. Also used by `\"tags\"` as the\n * suggestion list (existing values), while still allowing new entries.\n */\n editOptions?: Array<{ value: string; label: string }>;\n /**\n * Row link for the primary/title cell (D112): renders the cell content as a\n * real `next/link` anchor, so the row is reachable by keyboard, announced as\n * a link by screen readers, and cmd/middle-clickable into a new tab. The\n * whole-row `onRowOpen` click stays as a mouse convenience; clicks on the\n * anchor never double-fire it. Combine with `editable` and the link renders\n * with a hover/focus pencil that opens the inline editor instead of\n * click-text-to-edit.\n */\n href?: (row: T) => string | undefined;\n /**\n * Canonical entity token for the record this column NAMES. When set, the cell\n * renders through `EntityRef`, so the name carries the full door set — Open,\n * new tab, and Peek — instead of the Open-only `<Link>` that `href` alone\n * produces.\n *\n * THE INVENTORY LAW, applied to this component: the table grew its own door\n * (`href`) beside the platform's (`EntityRef`), and every column that named a\n * record picked one and silently lost the other half. This field collapses\n * them — `href` still works and still forces the pencil trigger, and it\n * OVERRIDES the registry route when both are set (for an admin-side route on\n * a satellite deployment).\n *\n * Needs the record's id: `entityToken` is paired with `entityId`, defaulting\n * to the table's own `getRowId`.\n *\n * **PER ROW, not per column** — a hub can be heterogeneous. `/transcripts`\n * lists transcripts, studio sessions, cleanup runs and an \"unsorted\" bucket\n * in one table, each with its own destination; a constant token would have\n * sent a session id to the transcript processor route and opened the\n * transcript peek on a record that is not one. Return `undefined` for a row\n * that names no entity — it falls back to the plain `href` link, or to inert\n * text. Pair with a per-row `href` when the kinds diverge.\n */\n entityToken?: string | ((row: T) => string | undefined);\n /**\n * NOTE: give the column a `cell` when you set this. Without one, a\n * UUID-shaped value renders the default `MatrxUuidCell`, which has its own\n * controls — wrapping those in the door's anchor would nest interactive\n * elements inside a link, and is redundant besides. The shell detects that\n * combination, skips the door, and screams once per column.\n */\n /** The id `entityToken` refers to. Defaults to the table's `getRowId(row)`. */\n entityId?: (row: T) => string | undefined;\n /**\n * Drop this column below `sm` (the phone breakpoint).\n *\n * A wide table on a phone becomes a horizontal scroller: the frozen\n * identity column stays, and everything after the second column sits off\n * the right edge where a reviewer will never find it. Marking the columns\n * that do NOT earn their width on a phone is how a surface declares an\n * INTENTIONAL mobile column set instead of an accidental one.\n *\n * The column is still fully sortable/filterable from the toolbar and still\n * rides every copy/export payload — this hides the CELL, not the data.\n * Default `false` = today's behavior everywhere.\n */\n mobileHidden?: boolean;\n /**\n * Built-in cell kinds. `\"uuid\"` / `\"fk\"` use MatrxUuidCell (short + copy +\n * optional open). `\"auto\"` (default) detects UUID-shaped strings.\n */\n cellKind?: \"auto\" | \"uuid\" | \"fk\" | \"text\";\n /**\n * FK / UUID navigation. Prefer `onOpen` → WindowPanel of the target.\n * Return `\"forbidden\"` when the caller lacks access.\n */\n fk?: {\n label?: string;\n /**\n * Canonical entity token this column's ids point at (`agent`, `note`, …).\n * THE DOOR LAW made declarative: the cell resolves route + new tab + peek\n * from the registries, so a column of ids stops being a dead end without\n * hand-wiring a link. `href` / `onOpen` still win when both are set.\n * A function form resolves the token per row (an audit log whose target\n * type varies by row).\n *\n * `\"auto\"` derives the token from the COLUMN NAME (`task_id` → `task`).\n * It is opt-in on purpose: the guess is only correct when you have checked\n * the actual FK. `scheduler.sch_run.task_id` references `scheduler.sch_task`,\n * not the workspace `task` the name implies, and `app_id` /\n * `conversation_id` / `file_id` / `workflow_id` each have several candidate\n * tables. A wrong door opens a DIFFERENT record — worse than no door.\n */\n token?: string | null | \"auto\" | ((row: T) => string | null | undefined);\n href?: (id: string, row: T) => string | null | undefined;\n onOpen?: (\n id: string,\n row: T,\n ) => void | \"forbidden\" | Promise<void | \"forbidden\">;\n /** Force non-navigable for this column. */\n forbidden?: boolean | ((id: string, row: T) => boolean);\n };\n className?: string;\n headerClassName?: string;\n width?: string | number;\n /** Enable desktop resizing for this column. Defaults to true when the table enables it. */\n resizable?: boolean;\n /** Desktop resize boundary. Defaults to 80px. */\n minWidth?: number;\n /** Desktop resize boundary. Defaults to 1200px. */\n maxWidth?: number;\n align?: \"left\" | \"center\" | \"right\";\n /**\n * ICON COLUMN. A column whose whole content is one glyph — a star, a lock, a\n * status dot — and whose `width` is therefore a lie without this flag.\n *\n * `width` is only a hint on a table cell: min-content wins. A 40px star column\n * still rendered ~70px wide because the HEADER carried three separate\n * controls beside the glyph (the sort button, its arrow, the filter funnel),\n * and the cell carried the default `px-2` on both sides. Every surface that\n * wanted a tight icon column was paying for chrome it never used.\n *\n * `compact` fixes it AT THE PRIMITIVE, and does NOT cost the column anything:\n * horizontal padding drops to `px-1`, and the header collapses its three\n * controls into ONE popover trigger that still offers Sort ascending / Sort\n * descending / Clear sort / the full filter body. The column stays fully\n * sortable and filterable — the affordances moved into the menu, they did not\n * disappear. Active sort/filter still show, as a 2px dot on the trigger.\n *\n * Pair it with `width` and `align: \"center\"`.\n */\n compact?: boolean;\n /** Hide from the table (still available in column picker when we add it). */\n hidden?: boolean;\n /** Whether the package-owned Columns dialog may hide this column. Default true. */\n hideable?: boolean;\n}\n\n/** How a text filter matches. Default `\"contains\"`. */\nexport type TextFilterMode = \"contains\" | \"empty\" | \"not_empty\" | \"null\" | \"not_null\";\n\n/** Active per-column filter value. Shape depends on filter kind. */\nexport type ColumnFilterValue =\n | { kind: \"text\"; value: string; mode?: TextFilterMode; negated?: boolean }\n | {\n kind: \"select\";\n /** Single-choice value (legacy writers). Ignored when `values` is set. */\n value: string;\n /** Multi-choice OR set — a row passes if it matches ANY entry. */\n values?: string[];\n /** Exclude matching values instead of including them. */\n negated?: boolean;\n }\n | { kind: \"boolean\"; value: boolean; negated?: boolean }\n | { kind: \"number\"; min?: number | undefined; max?: number | undefined; negated?: boolean };\n\nexport type ColumnFiltersState = Record<string, ColumnFilterValue | undefined>;\n\nexport interface SortState {\n id: string;\n direction: SortDirection;\n}\n\n/**\n * Opt-in durable URL state for a local table.\n *\n * Every table gets an explicit stable id, producing namespaced parameters such\n * as `table.accounts.q` and `table.accounts.sort`. This prevents collisions\n * with page-owned parameters and with sibling tables on the same route.\n */\nexport interface MatrxDataTableUrlStateConfig {\n /** Stable lowercase identifier: letters, numbers, and hyphens; max 64 chars. */\n id: string;\n /** Initial sort when the URL carries none. Default: none. */\n defaultSort?: SortState | null | undefined;\n /** Browser history behavior for table transitions. Default: `push`. */\n history?: \"push\" | \"replace\" | undefined;\n /**\n * History behavior while typing search/any-of text. `session` pushes the\n * first edit, then replaces rapid keystrokes. Default: `session`.\n */\n textHistory?: \"session\" | \"push\" | \"replace\" | undefined;\n /** Persist the open side-panel row. Default true. */\n selectedRow?: boolean;\n /** Persist the open table-owned window row. Default true. */\n windowRow?: boolean;\n /** Persist checkbox selection. Opt-in because large selections lengthen URLs. */\n selection?: boolean;\n}\n\n/**\n * Complete view state for a remotely queried table page. The table owns none\n * of this state in controlled mode: callers may mirror it to URL search params\n * and use it as part of a direct database-query cache key.\n */\nexport interface MatrxDataTableQueryState {\n /** One-based page number, matching the table's pagination UI. */\n page: number;\n pageSize: number;\n search: string;\n /** Defaults to `contains` when omitted, preserving every existing table. */\n searchMatchMode?: TableSearchMatchMode;\n /** Selected intelligent-search scope. Omitted means the backward-compatible All scope. */\n searchScope?: string;\n anyOf: string;\n /** Ordered AND rules from the compact advanced-filter builder. */\n layeredFilters?: LayeredFilterRule[];\n columnFilters: ColumnFiltersState;\n sort: SortState | null;\n}\n\n/**\n * Optional data-processing contract. Omit it (or use `local`) to preserve the\n * original in-memory filter/sort/pagination behavior. In controlled mode,\n * `data` is already the current page and the caller performs all querying.\n */\n/** Structural match for @ai-matrx/data/react usePaginatedData. */\nexport interface MatrxTablePagination<T> {\n queryKey: string;\n rows: T[];\n loading: boolean;\n isFetchingNextPage: boolean;\n error: Error | null;\n hasNextPage: boolean;\n loadNextPage: () => Promise<void>;\n refresh: () => void;\n totalItems: number | undefined;\n loadAll?: { isLoading: boolean; request: () => void; stop: () => void };\n retrySource?: () => void;\n sourceUntil?: string;\n sourcePageSize?: { value: number; options: readonly number[]; onChange: (value: number) => void };\n}\n\n/**\n * A controlled-local table can retain local search/pagination while its source\n * owns column filters and/or sorting. `sourceTotal` is display metadata only:\n * it never changes local page slicing, because the loaded rows remain local.\n */\nexport interface MatrxDataTableSourceProcessing {\n search?: \"local\" | \"source\";\n /** Source accepts and ranks `searchScope`; omit to keep scope UI local-only. */\n intelligentSearch?: \"local\" | \"source\";\n columnFilters?: \"local\" | \"source\";\n sort?: \"local\" | \"source\";\n sourceTotal?: number;\n}\n\nexport type MatrxDataTableQueryControl<T = unknown> =\n | { mode: \"local\" }\n | {\n /** Accumulated server rows; page stays 1 and sort/filter remain server-owned. */\n mode: \"controlled-append\";\n state: MatrxDataTableQueryState;\n onStateChange: (next: MatrxDataTableQueryState) => void;\n pagination: MatrxTablePagination<T>;\n sourceProcessing?: MatrxDataTableSourceProcessing;\n /** Source-connected tables append on user scroll by default. */\n scroll?: { thresholdPx?: number; intentTimeoutMs?: number } & (\n | { mode?: \"scroll\" }\n | { mode: \"manual\"; reason: string; approvedBy: string }\n /** Temporary configuration state: automatic append is off, but Load more stays available. */\n | { mode: \"suspended\"; reason: string }\n );\n }\n | {\n /** Local rows, but every query control is owned by the caller (for URL state). */\n mode: \"controlled-local\";\n state: MatrxDataTableQueryState;\n onStateChange: (next: MatrxDataTableQueryState) => void;\n sourceProcessing?: MatrxDataTableSourceProcessing;\n }\n | {\n mode: \"controlled\";\n state: MatrxDataTableQueryState;\n /** Total rows matching the controlled query, not just `data.length`. */\n totalItems: number;\n onStateChange: (next: MatrxDataTableQueryState) => void;\n /** Declare source-owned query behavior before enabling source-aware controls. */\n sourceProcessing?: MatrxDataTableSourceProcessing;\n };\n\n/**\n * Toolbar facets — first-class, Mars-extensible filter controls above the grid.\n * Start with button-group; add radio / switch / complex later without forking.\n */\nexport type ToolbarFacet =\n | {\n type: \"button-group\";\n id: string;\n label?: string;\n value: string;\n /** Reset target for per-facet + global clear. Default: first option value. */\n defaultValue?: string;\n options: Array<{\n value: string;\n label: string;\n icon?: ReactNode;\n }>;\n onChange: (value: string) => void;\n }\n | {\n type: \"custom\";\n id: string;\n render: () => ReactNode;\n };\n\n/**\n * Cross-column OR search — matches if ANY listed column contains the query.\n * Relationships use case: filter by entity type without picking source vs target.\n */\nexport interface AnyOfColumnSearch {\n columnIds: string[];\n placeholder?: string;\n /** Controlled value. Uncontrolled if omitted. */\n value?: string;\n onChange?: (value: string) => void;\n}\n\nexport interface MatrxDataTableToolbar {\n /** Optional human-readable table title, rendered by the shared title row. */\n title?: string;\n /** Global search across all accessor values. Default true. */\n search?: boolean;\n searchPlaceholder?: string;\n searchValue?: string;\n onSearchChange?: (value: string) => void;\n /**\n * Show a compact, visible choice between substring and whole-word search.\n * Omit it when a data source cannot honor both modes server-side.\n */\n searchMatch?: {\n defaultMode?: TableSearchMatchMode;\n };\n /** Prototype ranked search. Local tables rank complete loaded rows before pagination. */\n intelligentSearch?: {\n roles?: Readonly<Record<string, TableSearchRole>>;\n scopes?: readonly TableSearchScope[];\n };\n /**\n * OR-search across specific columns (e.g. source_type OR target_type).\n * Shown as its own input beside global search when set.\n */\n anyOf?: AnyOfColumnSearch;\n /**\n * Optional compact advanced-filter builder beside the regular search. In\n * controlled mode rules live in `query.state.layeredFilters`; local tables\n * evaluate them against matching column ids.\n */\n layeredFilters?: {\n fields: readonly LayeredFilterField[];\n maxRules?: number;\n label?: string;\n };\n /** Extensible facet strip (button groups, later radios/switches/…). */\n facets?: ToolbarFacet[];\n /** Source controls in a separate wrapping row below the standard toolbar. */\n leading?: ReactNode;\n /**\n * Standard host refresh affordance. The package owns its placement, busy\n * state, accessible tooltip, and glyphs (refresh arrows at rest, spinner\n * only while busy); the host remains the sole data owner.\n */\n refresh?: {\n onRefresh: () => void | Promise<void>;\n label?: string;\n };\n /**\n * Standard create affordance. The host owns authorization and the actual\n * create flow; disabledReason is exposed through the shared tooltip.\n */\n add?: {\n onAdd: () => void | Promise<void>;\n disabled?: boolean;\n disabledReason?: string;\n };\n /** Right-side domain actions, rendered after standard table controls. */\n actions?: ReactNode;\n}\n\n/** Query fields safe to persist in a named table view. */\nexport type TableViewQuery = Omit<MatrxDataTableQueryState, \"page\">;\n\n/** Portable, persistence-neutral table state saved by a host adapter. */\nexport interface TableViewSnapshot {\n __kind: \"matrx-table-view\";\n version: 1;\n /** Page/cursor/selection/loaded rows are deliberately never saved. */\n query: TableViewQuery;\n /** `widths` is sparse so views saved before resize remain valid. */\n columns: { order: string[]; hidden: string[]; widths?: Record<string, number> };\n}\n\n/** Host port for durable named views. The host owns actor, tenancy and CRUD. */\nexport interface TableSavedViewsProps {\n tableId: string;\n snapshot: TableViewSnapshot;\n defaultSnapshot: TableViewSnapshot;\n onApply: (snapshot: TableViewSnapshot) => void;\n}\n\n/** Optional deferred-apply copy for column filter popovers. */\nexport interface MatrxDataTableFilterUi {\n /** Enables the Include/Exclude control. Default false for remote-safe filters. */\n allowNegation?: boolean;\n /** Enables null/not-null text modes. Default false for remote-safe filters. */\n allowNullModes?: boolean;\n applyLabel?: string;\n showCancel?: boolean;\n footerHint?: ReactNode;\n}\n\nexport interface MatrxDataTableCopyConfig<T> {\n /** Explicit registered identities; never inferred from table labels or row shapes. */\n rowReferences?: (row: T) => readonly ContentTransferReference[];\n references?: (visible: T[], all: T[]) => readonly ContentTransferReference[];\n triggerVariant?: \"transparent\" | \"glass\" | \"outline\";\n /** Toast / tooltip label base, e.g. \"Relationship rule\". */\n label: string;\n listLabel?: string;\n location: string;\n rowKind: string;\n listKind: string;\n rowDescription?: string;\n listDescription?: string;\n humanRow: (row: T) => string;\n /** Project row for agent JSON. Default: full row. */\n agentRow?: (row: T) => unknown;\n rowAttributes?: (\n row: T,\n ) => Record<string, string | number | boolean | null | undefined>;\n listAttributes?: (\n visible: T[],\n all: T[],\n ) => Record<string, string | number | boolean | null | undefined>;\n /**\n * Live view state rendered inside the list payload's <context>. Unlike\n * per-row data, this remains present when the current view has zero rows.\n */\n listContext?: (\n visible: T[],\n all: T[],\n ) => Record<string, string | number | boolean | null | undefined>;\n /**\n * Additional row-scoped AI actions. Use this to fold a domain action such\n * as a paste-ready repair brief into the table-owned row copy menu instead\n * of rendering a separate third control. Builders run at click time.\n */\n rowAiVariants?: (row: T) => AiVariant[];\n /**\n * Graded AI variants for the toolbar's view copy (e.g. \"Top 25\", \"Summary\n * only\"). When set, the toolbar's Copy-for-AI upgrades to a dropdown with\n * these variants + the full-view payload as the automatic \"Everything\"\n * escape hatch. Receives (visible, all) rows at render; builders run at\n * click time.\n */\n aiVariants?: (visible: T[], all: T[]) => AiVariant[];\n /** Custom-preview source (options dialog + live size counts) for the view. */\n aiCustom?: (visible: T[], all: T[]) => AiCustomSource;\n /** Show toolbar copy (this view). Default true when copy is set. */\n showToolbar?: boolean;\n /** Show per-row copy. Default true when copy is set. */\n showRow?: boolean;\n}\n\nexport interface MatrxDataTableDetailConfig<T> {\n /** Side-panel title. Default: first string column or \"Details\". */\n title?: (row: T) => ReactNode;\n description?: (row: T) => ReactNode | undefined;\n /** Override the default key/value inspector. */\n render?: (row: T, controls: MatrxDataTableRecordControls) => ReactNode;\n /** Header actions inside the side panel. */\n headerActions?: (row: T) => ReactNode;\n defaultWidth?: number;\n enabled?: boolean;\n /**\n * Maps a field name to the entity token its id points at, turning that field\n * into a door (route + peek) in the default inspector — side panel AND row\n * window.\n *\n * There is no default guess: this inspector renders whatever columns the row\n * has, and a wrong door opens a DIFFERENT record (`sch_run.task_id` is a\n * SCHEDULED task, not a workspace `task`). A table whose FKs you HAVE checked\n * can pass `tokenFromColumnName` (`components/official/entity-ref/doors`) to\n * open every `<token>_id` field at once.\n *\n * The ROW is passed too, because a table whose target type varies per row (an\n * audit log, an exposure report) cannot answer from the column name alone.\n */\n tokenForField?: (key: string, row: T) => string | null;\n}\n\n/** Actions a record-owned control can use without reaching into table state. */\nexport interface MatrxDataTableRecordControls {\n /** Close the row's side-panel detail, if open. */\n closeDetail: () => void;\n /** Open the row in the canonical adjustable side panel. */\n openDetail: () => void;\n /** Open the row in its canonical table-owned WindowPanel. */\n openWindow: () => void;\n /** Close the row's table-owned WindowPanel, if open. */\n closeWindow: () => void;\n /** Whether this row currently has visible, unpersisted inline edits. */\n hasPendingEdits: boolean;\n /**\n * Discard this row's pending inline edits.\n *\n * Row actions that persist the already-merged visible row (for example an\n * explicit Confirm action) call this only after that write succeeds. This\n * prevents the floating Save pill from later replaying the same draft as a\n * different, weaker write.\n */\n discardPendingEdits: () => void;\n}\n\nexport interface MatrxDataTableWindowConfig<T> {\n /** Window title. */\n title?: (row: T) => string;\n /**\n * @deprecated Prefer `renderView` + `renderEdit` so the window stays editable.\n * Full-body override with no View/Edit tabs.\n */\n render?: (row: T, controls: MatrxDataTableRecordControls) => ReactNode;\n /** View tab body. Defaults to DataRowInspector. */\n renderView?: (row: T, controls: MatrxDataTableRecordControls) => ReactNode;\n /**\n * Edit tab body. When set, the WindowPanel shows View / Edit sidebar tabs\n * (WindowPanel built-in sidebar). Defaults to `detail.render` when present.\n * Pass `false` to keep a view-only window even when `detail.render` exists.\n */\n renderEdit?:\n ((row: T, controls: MatrxDataTableRecordControls) => ReactNode) | false;\n /**\n * Called when the panel icon opens the window — hydrate edit state here\n * without opening the side panel (prefer this over `onRowOpen` for windows).\n */\n onOpen?: (row: T) => void;\n /**\n * Make full-row click open the WindowPanel instead of the side panel.\n * The trailing row action and the window header then expose the side panel\n * as the explicit secondary presentation. Default false.\n */\n openOnRowClick?: boolean;\n /** Which tab to open. Default: `\"edit\"` when an edit body exists. */\n defaultTab?: \"view\" | \"edit\";\n /** Show the panel-icon that opens the window. Default true when detail enabled. */\n enabled?: boolean;\n width?: number;\n height?: number;\n}\n\nexport interface MatrxDataTableEmptyState {\n icon?: ReactNode;\n title: string;\n description?: string;\n action?: ReactNode;\n}\n\n/** Pending cell edits keyed by row id → partial field map. */\nexport type CellEditsMap = Record<string, Record<string, unknown>>;\n\nexport interface MatrxDataTableEditConfig<T> {\n /** Enable inline editing for columns with `editable` set. */\n enabled?: boolean;\n /**\n * Persist all pending edits. Called when the user clicks Save on the dirty pill.\n * Return resolved when done; throw/reject to keep the draft (with toast).\n */\n onSave: (edits: CellEditsMap, rows: T[]) => void | Promise<void>;\n /** Persist each committed cell immediately. Failed writes remain in the\n * dirty pill so the user can retry or cancel them. */\n autoSave?: boolean;\n /** Optional cancel hook (draft already discarded). */\n onCancel?: () => void;\n}\n\nexport interface MatrxDataTableHierarchyConfig<T> {\n /** Complete hierarchy when `data` is only the current controlled page. */\n rows?: T[];\n getParentId: (row: T) => string | null;\n /** Persist the exact structural intent represented by the drop shadow. */\n onMove: (row: T, move: MatrxDataTableHierarchyMove) => void | Promise<void>;\n /** Enables sibling insertion shadows in addition to parent/root drops. */\n manualOrder?: boolean;\n canReparent?: (row: T) => boolean;\n itemLabel?: (row: T) => string;\n rootDropLabel?: string;\n}\n\nexport interface MatrxDataTableHierarchyMove {\n parentId: string | null;\n /**\n * Insert immediately before this sibling. Null means first child for\n * \"inside\"/\"root\", and LAST sibling for \"after\" (target had no successor).\n */\n beforeId: string | null;\n position: \"before\" | \"after\" | \"inside\" | \"root\";\n targetId: string | null;\n}\n\n/**\n * Multi-row selection — a leading checkbox column plus a bulk bar that appears\n * only while rows are checked.\n *\n * OPT-IN and fully CONTROLLED: the consumer owns the id set, so selection\n * survives (or is deliberately cleared by) a re-fetch, a filter change, or an\n * optimistic list update — the table never holds hidden selection state that\n * can disagree with the surface around it.\n *\n * Why this is a primitive and not a per-surface checkbox column: a register\n * the user cannot clear in bulk is a register they stop reading, and the fifth\n * hand-rolled selection column — each with its own shift-click, its own\n * select-all semantics, its own bar — is exactly the fork `components/official/`\n * exists to prevent.\n *\n * Selection does not alter mobile horizontal scrolling. The complete row moves\n * as one surface below `sm`; no leading column is allowed to pin over the data.\n */\nexport interface MatrxDataTableSelectionConfig<T> {\n /** Selected row ids (`getRowId`). Ids not on the current page are kept. */\n selectedIds: string[];\n onSelectedIdsChange: (ids: string[]) => void;\n /**\n * The bulk bar's actions, given the currently-selected rows THAT ARE LOADED.\n * Selection can outlive a page change, so also take `selectedIds` when an\n * action only needs ids.\n */\n actions?: (selected: T[], selectedIds: string[]) => ReactNode;\n /**\n * Rows that cannot be acted on in bulk render NO checkbox at all — the cell\n * stays for alignment, the control is absent from the DOM. A greyed control\n * still advertises a choice the surface underneath would refuse.\n */\n isRowSelectable?: (row: T) => boolean;\n /** Singular noun for the bar's count (\"finding\" → \"3 findings selected\"). */\n noun?: string;\n}\n\n/** Table-owned state and actions exposed to an opt-in phone card renderer. */\nexport interface MatrxDataTableMobileCardControls {\n /** Render a declared column with the same editable/draft/link behavior as the grid. */\n renderCell: (columnId: string) => ReactNode;\n /** Whether this row is in the canonical selection set. */\n selected: boolean;\n /** Whether the consumer allows this row to be selected. */\n selectable: boolean;\n /** Update selection through the table's controlled/URL-backed contract. */\n onSelectedChange: (selected: boolean) => void;\n /**\n * The table's canonical per-row copy controls plus consumer row actions.\n * Render this instead of rebuilding either action path inside the card.\n */\n actions: ReactNode;\n}\n\nexport type MatrxDataTableDensity = \"condensed\" | \"normal\" | \"spacious\";\n\nexport interface MatrxDataTableProps<T> {\n data: T[];\n columns: MatrxColumnDef<T>[];\n /** Table-local visual density. An explicit value wins over the host default. */\n density?: MatrxDataTableDensity;\n /** Stable persistence identity for host-installed named views. */\n tableId?: string;\n /** Declared reset state for the host Saved Views control. */\n defaultViewSnapshot?: TableViewSnapshot;\n /** Working view tabs, on by default. Disable for embedded/single-purpose tables. */\n viewTabs?: boolean;\n /** Related-data controls shown at the right of the working-view tab strip. */\n relatedTableActions?: ReactNode;\n /** Optional URL/source-owned column order and visibility. */\n columnState?: {\n order: string[];\n hidden: string[];\n onChange: (next: { order: string[]; hidden: string[] }) => void;\n /** Optional source-owned desktop widths keyed by canonical column id. */\n widths?: Record<string, number>;\n /** Required to persist controlled width changes across remounts. */\n onWidthsChange?: (widths: Record<string, number>) => void;\n };\n /** Enables package-owned drag reordering in table headers. Default true. */\n reorderableColumns?: boolean;\n /** Enables desktop column resizing. Default true; handles are absent below `sm`. */\n resizableColumns?: boolean;\n columnManager?: { open: boolean; onOpenChange: (open: boolean) => void };\n getRowId: (row: T) => string;\n /**\n * Additional row identity included in local global search without becoming\n * a visible/sortable/filterable column. Use for canonical composite keys or\n * aliases whose displayed parts live in separate columns.\n *\n * Ignored in remote controlled mode, where the query owner applies search.\n */\n searchText?: (row: T) => string;\n /**\n * Hierarchy-aware local processing seam. The canonical table still owns the\n * toolbar, URL state, headers, pagination, editing, copy, and rendering; the\n * consumer only preserves domain ordering that a flat sort would destroy.\n *\n * The processor must honor every active query control in `state` and return\n * the complete filtered/sorted local result before pagination. It is ignored\n * in remote controlled mode, where `data` is already the queried page.\n */\n processLocalRows?: (rows: T[], state: MatrxDataTableQueryState) => T[];\n /** Initial local sort when neither URL state nor a controlled query owns it. */\n defaultSort?: SortState | null;\n isLoading?: boolean;\n /**\n * Background refresh state. Unlike `isLoading`, this preserves rendered rows\n * and shows only the table's non-blocking refresh indicator.\n */\n isFetching?: boolean;\n /**\n * Controlled query state for direct remote data sources. The component never\n * fetches data itself; it only emits state changes to the caller.\n */\n query?: MatrxDataTableQueryControl<T>;\n /**\n * Persist local query and record-view state in namespaced URL parameters.\n * This is intentionally opt-in and cannot be combined with controlled query\n * mode; remote tables use `useTableUrlState({ tableId })` in their query owner.\n */\n urlState?: MatrxDataTableUrlStateConfig;\n\n toolbar?: MatrxDataTableToolbar;\n /** Hide the package toolbar while retaining table-owned query behavior. */\n hideToolbar?: boolean;\n /** Hide numbered pagination; local rows remain available to the caller. */\n hidePagination?: boolean;\n /** Optional deferred Apply/Cancel copy for column filter popovers. */\n filterUi?: MatrxDataTableFilterUi;\n /** Row click opens the side panel unless `window.openOnRowClick` is true. */\n detail?: MatrxDataTableDetailConfig<T>;\n /** Panel icon opens a WindowPanel (page-local; supports ReactNode override). */\n window?: MatrxDataTableWindowConfig<T>;\n /** Copy + Copy for AI (rows + this view). Omit for the declared-column default; false suppresses it. */\n copy?: false | MatrxDataTableCopyConfig<T>;\n /** Inline edit session with floating Save/Cancel pill. */\n edit?: MatrxDataTableEditConfig<T>;\n /** Opt-in tree reparenting owned by the canonical row renderer. */\n hierarchy?: MatrxDataTableHierarchyConfig<T>;\n\n /** Controlled selection (selected row id for highlight). */\n selectedId?: string | null | undefined;\n onSelectedIdChange?: ((id: string | null) => void) | undefined;\n\n /** Controlled table-owned window row (normally supplied by URL state). */\n windowRowId?: string | null | undefined;\n onWindowRowIdChange?: ((id: string | null) => void) | undefined;\n\n /** Opt-in multi-row checkbox selection + a bulk action bar. */\n selection?: MatrxDataTableSelectionConfig<T>;\n\n /** Extra row actions rendered in a trailing Actions column. */\n rowActions?: (row: T, controls: MatrxDataTableRecordControls) => ReactNode;\n /** Extra rows rendered in the table footer with the same columns as data rows. */\n footerRows?: T[];\n /** Per-row presentation class, after canonical selection/highlight state. */\n rowClassName?: (row: T, index: number) => string | undefined;\n /** Highlight an index in the currently rendered page without selecting it. */\n highlightedIndex?: number | undefined;\n /** Receives the complete visible local view after local processing, before paging. Attaching after absence receives one snapshot; callback identity changes alone do not notify. */\n onViewChange?: (rows: T[]) => void;\n /**\n * Wrap the whole `<tr>`. Return `children` unchanged for no-op.\n *\n * `rowActions` only reaches the actions CELL, so anything that must own the\n * entire row — a right-click menu, a drag handle, a drop target — had no\n * seam and would have forced a surface to fork the table. THE INVENTORY LAW:\n * the fork is the defect, so the seam exists instead.\n *\n * Whatever you return must render `children` as a direct `<tbody>` child, so\n * the wrapper has to be a component that emits the `<tr>` unchanged\n * (`ItemContextMenu` does — it renders a Radix trigger with `asChild`).\n */\n rowWrapper?: (row: T, children: ReactNode) => ReactNode;\n\n emptyState?: MatrxDataTableEmptyState;\n /** Default 25. Pass 0 to show all. */\n pageSize?: number;\n /** Complete local results reveal on physical scroll by default. Numbered\n * paging is an explicit exception requiring its reason and approving owner. */\n localPagination?:\n | { mode?: \"progressive\" }\n | { mode: \"numbered\"; reason: string; approvedBy: string };\n pageSizeOptions?: number[];\n zebra?: boolean;\n className?: string;\n tableClassName?: string;\n /**\n * Optional compact row presentation rendered below `mobileCardsBreakpoint`\n * in place of the horizontal table. The caller supplies the record summary\n * because only the product surface knows which values and actions are\n * essential at narrow widths; MatrxDataTable still owns query state,\n * loading/empty states, and pagination.\n *\n * `controls.actions` carries the table-owned copy controls and consumer row\n * actions, so a card does not fork them. Prefer the default horizontal table\n * unless the product explicitly requires every essential value/action to be\n * discoverable without horizontal scrolling.\n */\n mobileCards?: (\n row: T,\n index: number,\n controls: MatrxDataTableMobileCardControls,\n ) => ReactNode;\n /** Card/table handoff. `sm` is phone-only; `lg` includes portrait tablets. */\n mobileCardsBreakpoint?: \"sm\" | \"lg\";\n /** Called after a row is selected for detail (in addition to opening the panel). */\n onRowOpen?: (row: T) => void;\n}\n\n/** Re-export for callers building custom agent payloads. */\nexport type { AgentPayloadInput };\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}