@snksergio/design-system 0.1.0
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.
- package/README.md +260 -0
- package/dist-lib/chunks/app-shell-BNTvOETJ.mjs +2681 -0
- package/dist-lib/chunks/app-shell-BNTvOETJ.mjs.map +1 -0
- package/dist-lib/chunks/app-shell-CDy42aNI.mjs +2663 -0
- package/dist-lib/chunks/app-shell-CDy42aNI.mjs.map +1 -0
- package/dist-lib/chunks/app-shell-mocks-kWIVSzLs.mjs +208 -0
- package/dist-lib/chunks/app-shell-mocks-kWIVSzLs.mjs.map +1 -0
- package/dist-lib/chunks/app-shell-mocks-oO_IV3Gw.mjs +207 -0
- package/dist-lib/chunks/app-shell-mocks-oO_IV3Gw.mjs.map +1 -0
- package/dist-lib/chunks/badge-B_2Zt52o.mjs +797 -0
- package/dist-lib/chunks/badge-B_2Zt52o.mjs.map +1 -0
- package/dist-lib/chunks/badge-DKpXURa1.mjs +813 -0
- package/dist-lib/chunks/badge-DKpXURa1.mjs.map +1 -0
- package/dist-lib/chunks/chat-v2-mocks-BV9Wha_Z.mjs +192 -0
- package/dist-lib/chunks/chat-v2-mocks-BV9Wha_Z.mjs.map +1 -0
- package/dist-lib/chunks/chat-v2-mocks-DvZRkhmz.mjs +193 -0
- package/dist-lib/chunks/chat-v2-mocks-DvZRkhmz.mjs.map +1 -0
- package/dist-lib/chunks/chip-group-CsKBBHW2.mjs +796 -0
- package/dist-lib/chunks/chip-group-CsKBBHW2.mjs.map +1 -0
- package/dist-lib/chunks/chip-group-D3D0i72q.mjs +780 -0
- package/dist-lib/chunks/chip-group-D3D0i72q.mjs.map +1 -0
- package/dist-lib/chunks/clientes-showcase-mocks-BMfbNNJh.mjs +185 -0
- package/dist-lib/chunks/clientes-showcase-mocks-BMfbNNJh.mjs.map +1 -0
- package/dist-lib/chunks/clientes-showcase-mocks-Cq9u3nGZ.mjs +169 -0
- package/dist-lib/chunks/clientes-showcase-mocks-Cq9u3nGZ.mjs.map +1 -0
- package/dist-lib/chunks/input-374MpdBL.mjs +72 -0
- package/dist-lib/chunks/input-374MpdBL.mjs.map +1 -0
- package/dist-lib/chunks/input-DF4XAWmr.mjs +56 -0
- package/dist-lib/chunks/input-DF4XAWmr.mjs.map +1 -0
- package/dist-lib/chunks/page-header-Dw-3wqAG.mjs +75 -0
- package/dist-lib/chunks/page-header-Dw-3wqAG.mjs.map +1 -0
- package/dist-lib/chunks/page-header-mC1gGtOI.mjs +76 -0
- package/dist-lib/chunks/page-header-mC1gGtOI.mjs.map +1 -0
- package/dist-lib/chunks/panel-Ds15whqp.mjs +9717 -0
- package/dist-lib/chunks/panel-Ds15whqp.mjs.map +1 -0
- package/dist-lib/chunks/panel-bzNmFlEZ.mjs +9737 -0
- package/dist-lib/chunks/panel-bzNmFlEZ.mjs.map +1 -0
- package/dist-lib/chunks/useTheme-BUPLZBMs.mjs +66 -0
- package/dist-lib/chunks/useTheme-BUPLZBMs.mjs.map +1 -0
- package/dist-lib/chunks/useTheme-Dee4mo-A.mjs +65 -0
- package/dist-lib/chunks/useTheme-Dee4mo-A.mjs.map +1 -0
- package/dist-lib/index.cjs +1207 -0
- package/dist-lib/index.cjs.map +1 -0
- package/dist-lib/index.d.ts +2 -0
- package/dist-lib/index.mjs +1209 -0
- package/dist-lib/index.mjs.map +1 -0
- package/dist-lib/preview/chat.cjs +1120 -0
- package/dist-lib/preview/chat.cjs.map +1 -0
- package/dist-lib/preview/chat.d.ts +6 -0
- package/dist-lib/preview/chat.mjs +1120 -0
- package/dist-lib/preview/chat.mjs.map +1 -0
- package/dist-lib/preview/clientes.cjs +897 -0
- package/dist-lib/preview/clientes.cjs.map +1 -0
- package/dist-lib/preview/clientes.d.ts +6 -0
- package/dist-lib/preview/clientes.mjs +897 -0
- package/dist-lib/preview/clientes.mjs.map +1 -0
- package/dist-lib/preview/dashboard.cjs +733 -0
- package/dist-lib/preview/dashboard.cjs.map +1 -0
- package/dist-lib/preview/dashboard.d.ts +4 -0
- package/dist-lib/preview/dashboard.mjs +733 -0
- package/dist-lib/preview/dashboard.mjs.map +1 -0
- package/dist-lib/preview/mocks.cjs +15 -0
- package/dist-lib/preview/mocks.cjs.map +1 -0
- package/dist-lib/preview/mocks.d.ts +2 -0
- package/dist-lib/preview/mocks.mjs +15 -0
- package/dist-lib/preview/mocks.mjs.map +1 -0
- package/dist-lib/theme.css +668 -0
- package/dist-lib/tokens.cjs +915 -0
- package/dist-lib/tokens.cjs.map +1 -0
- package/dist-lib/tokens.d.ts +2 -0
- package/dist-lib/tokens.mjs +915 -0
- package/dist-lib/tokens.mjs.map +1 -0
- package/package.json +142 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel-Ds15whqp.mjs","sources":["../../src/components/shadcn/alert-dialog.tsx","../../src/components/ui/AlertModal/alert-modal.styles.ts","../../src/components/ui/AlertModal/alert-modal.tsx","../../src/components/ui/Avatar/avatar.styles.ts","../../src/components/ui/Avatar/avatar.tsx","../../src/components/ui/Table/use-column-widths.ts","../../src/components/ui/Table/table.constants.ts","../../src/components/ui/TableToolbar/table-toolbar.styles.ts","../../src/components/ui/TableToolbar/table-toolbar.tsx","../../src/components/ui/TableToolbar/parts/toolbar-search.tsx","../../src/components/ui/TableToolbar/parts/toolbar-divider.tsx","../../src/components/ui/TableToolbar/parts/toolbar-segmented.tsx","../../src/components/ui/TableToolbar/parts/toolbar-tabs.tsx","../../src/components/ui/TableToolbar/parts/toolbar-tool-button.tsx","../../src/components/ui/TableToolbar/parts/toolbar-applied.tsx","../../src/components/ui/TableToolbar/parts/bulk-actions-bar.tsx","../../src/components/ui/TableToolbar/popovers/more-menu.tsx","../../src/components/shadcn/popover.tsx","../../src/components/ui/TableToolbar/popovers/cols-popover.tsx","../../src/components/ui/TableToolbar/popovers/sort-popover.tsx","../../src/components/ui/TableToolbar/popovers/views-popover.tsx","../../src/components/shadcn/switch.tsx","../../src/components/ui/FormField/form-field.styles.ts","../../src/components/ui/FormField/form-field.tsx","../../src/components/ui/FormField/form-field-input.tsx","../../src/components/ui/TableToolbar/popovers/add-view-modal.styles.ts","../../src/components/ui/TableToolbar/popovers/add-view-modal.tsx","../../src/components/ui/TableToolbar/parts/table-toolbar-views.tsx","../../src/components/ui/TableToolbar/popovers/filter-sql-parser.ts","../../src/components/shadcn/select.tsx","../../src/components/ui/TableToolbar/popovers/filter-popover.tsx","../../src/components/shadcn/pagination.tsx","../../src/components/ui/FooterTable/footer-table.tsx","../../src/components/ui/Kanban/kanban.styles.ts","../../src/components/ui/Kanban/hooks/use-kanban-dnd.ts","../../src/components/ui/Kanban/kanban.tsx","../../src/components/ui/DataTable/data-table.styles.ts","../../src/components/ui/DataTable/context/data-table-context.tsx","../../src/components/ui/DataTable/column-types/column-type-registry.ts","../../src/components/ui/DataTable/column-types/_filter-field.tsx","../../src/components/ui/DataTable/column-types/definitions/text-column-type.tsx","../../src/components/ui/DataTable/column-types/definitions/number-column-type.tsx","../../src/components/shadcn/calendar.tsx","../../src/components/ui/DataTable/column-types/definitions/date-column-type.tsx","../../src/components/ui/DataTable/column-types/definitions/select-column-type.tsx","../../src/components/ui/DataTable/column-types/definitions/multi-select-column-type.tsx","../../src/components/ui/DataTable/column-types/definitions/boolean-column-type.tsx","../../src/components/ui/DataTable/column-types/definitions/currency-column-type.tsx","../../src/components/ui/DataTable/column-types/definitions/percentage-column-type.tsx","../../src/components/ui/DataTable/column-types/definitions/email-column-type.tsx","../../src/components/ui/DataTable/column-types/definitions/phone-column-type.tsx","../../src/components/ui/DataTable/column-types/definitions/url-column-type.tsx","../../src/components/ui/DataTable/column-types/definitions/user-column-type.tsx","../../src/components/ui/DataTable/column-types/definitions/badge-column-type.tsx","../../src/components/ui/DataTable/column-types/definitions/tags-column-type.tsx","../../src/components/ui/DataTable/column-types/definitions/datetime-column-type.tsx","../../src/components/ui/DataTable/column-types/index.ts","../../src/components/ui/DataTable/hooks/use-data-table-columns.ts","../../src/components/ui/DataTable/hooks/use-data-table-sort.ts","../../src/components/ui/DataTable/hooks/use-data-table-pagination.ts","../../src/components/ui/DataTable/hooks/use-data-table-selection.ts","../../src/components/ui/DataTable/hooks/use-data-table-density.ts","../../src/components/ui/DataTable/hooks/use-data-table-search.ts","../../src/components/ui/DataTable/hooks/use-data-table-filters.ts","../../src/components/ui/DataTable/utils/resolve-value.ts","../../src/components/ui/DataTable/hooks/use-data-table-processor.ts","../../src/components/ui/DataTable/hooks/use-data-table-query.ts","../../src/components/ui/DataTable/hooks/use-data-table-export.ts","../../src/components/ui/DataTable/hooks/state-persistence-utils.ts","../../src/components/ui/DataTable/hooks/use-data-table-state-persistence.ts","../../src/components/ui/DataTable/services/saved-views-mock-service.ts","../../src/components/ui/DataTable/hooks/use-data-table-saved-views.ts","../../src/components/ui/DataTable/hooks/use-data-table-controller.ts","../../src/components/ui/DataTable/parts/data-table-empty.tsx","../../src/components/ui/DataTable/parts/data-table-loading.tsx","../../src/components/ui/DataTable/parts/data-table-no-results.tsx","../../src/components/ui/DataTable/parts/data-table-column-menu.tsx","../../src/components/ui/DataTable/parts/data-table-actions-cell.tsx","../../src/components/ui/DataTable/parts/sortable-head-cell.tsx","../../src/components/ui/DataTable/parts/data-table-edit-cell.tsx","../../src/components/ui/DataTable/parts/data-table-totalizer-row.tsx","../../src/components/ui/DataTable/parts/data-table-group-header-row.tsx","../../src/components/ui/DataTable/parts/data-table-group-content-row.tsx","../../src/components/ui/DataTable/utils/group-rows.ts","../../src/components/ui/DataTable/parts/data-table-row-expansion.tsx","../../src/components/ui/DataTable/utils/expand-rows.ts","../../src/components/ui/DataTable/utils/operator-mapping.ts","../../src/components/ui/DataTable/hooks/use-sort-popover-adapter.ts","../../src/components/ui/DataTable/hooks/use-cols-popover-adapter.ts","../../src/components/ui/DataTable/hooks/use-filter-popover-adapter.ts","../../src/components/ui/DataTable/hooks/use-data-table-view-mode.ts","../../src/components/ui/DataTable/data-table.tsx","../../src/components/ui/DataTable/parts/data-table-floating-bulk-bar.tsx","../../src/components/ui/DataTable/builders/preset-view.ts","../../src/components/ui/FloatingPanel/floating-panel.styles.ts","../../src/components/ui/FloatingPanel/use-floating-panel-resize.ts","../../src/components/ui/FloatingPanel/floating-panel.tsx","../../src/components/shadcn/textarea.tsx","../../src/components/ui/FormField/form-field-textarea.tsx","../../src/components/ui/FormField/form-field-select.tsx","../../src/components/ui/FormField/form-field-checkbox.tsx","../../src/components/ui/FormField/form-field-switch.tsx","../../src/components/shadcn/sheet.tsx","../../src/components/ui/Panel/panel.styles.ts","../../src/components/ui/Panel/panel-header.tsx","../../src/components/ui/Panel/panel-body.tsx","../../src/components/ui/Panel/panel-footer.tsx","../../src/components/ui/Panel/panel.tsx"],"sourcesContent":["import * as React from \"react\";\nimport * as AlertDialogPrimitive from \"@radix-ui/react-alert-dialog\";\n\nimport { cn } from \"@/lib/utils\";\n\n/**\n * AlertDialog — variante do Dialog pra confirmação destrutiva/crítica.\n *\n * Diferenças vs. Dialog:\n * - role=\"alertdialog\" (assistive tech anuncia diferente)\n * - Foco vai pro botão `Cancel` (mais seguro como ação default)\n * - Não fecha ao clicar fora ou apertar ESC (decisão forçada)\n *\n * Estilo alinhado com `.tbl-confirm-dialog` do sandbox: 420px, body 32/28/24,\n * radius-2xl, shadow-2xl, outline halo, ícone 56x56 com bg-tone-muted.\n *\n * Pra um wrapper \"one-shot\" com tone + ícone + botões → use <AlertModal>.\n */\n\nconst AlertDialog = AlertDialogPrimitive.Root;\nconst AlertDialogTrigger = AlertDialogPrimitive.Trigger;\nconst AlertDialogPortal = AlertDialogPrimitive.Portal;\n\nconst AlertDialogOverlay = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Overlay\n ref={ref}\n className={cn(\n \"fixed inset-0 z-50 bg-black/30 supports-[backdrop-filter]:backdrop-blur-sm\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className,\n )}\n {...props}\n />\n));\nAlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;\n\nconst AlertDialogContent = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>\n>(({ className, ...props }, ref) => (\n <AlertDialogPortal>\n <AlertDialogOverlay />\n <AlertDialogPrimitive.Content\n ref={ref}\n className={cn(\n \"fixed left-[50%] top-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] sm:max-w-[420px]\",\n \"translate-x-[-50%] translate-y-[-50%]\",\n \"rounded-radius-2xl bg-bg-surface text-fg-default\",\n \"border border-border-default shadow-sh-2xl outline-float\",\n \"duration-200\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n \"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n className,\n )}\n {...props}\n />\n </AlertDialogPortal>\n));\nAlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;\n\nconst AlertDialogHeader = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col items-center text-center gap-gp-lg\",\n \"px-pad-4xl pt-[32px] pb-pad-3xl\",\n className,\n )}\n {...props}\n />\n);\nAlertDialogHeader.displayName = \"AlertDialogHeader\";\n\nconst AlertDialogFooter = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n // Mobile: empilha vertical, confirm em cima (flex-col-reverse põe Cancel embaixo)\n // sm+: lado a lado horizontal\n <div\n className={cn(\n \"flex flex-col-reverse items-stretch gap-gp-md sm:flex-row\",\n \"px-pad-3xl pb-pad-3xl\",\n className,\n )}\n {...props}\n />\n);\nAlertDialogFooter.displayName = \"AlertDialogFooter\";\n\nconst AlertDialogTitle = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Title\n ref={ref}\n className={cn(\n \"text-[18px] font-bold tracking-[-0.01em] text-fg-default leading-tight\",\n className,\n )}\n {...props}\n />\n));\nAlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;\n\nconst AlertDialogDescription = React.forwardRef<\n React.ElementRef<typeof AlertDialogPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Description\n ref={ref}\n className={cn(\n \"text-[13px] leading-[1.5] text-fg-muted max-w-[340px]\",\n className,\n )}\n {...props}\n />\n));\nAlertDialogDescription.displayName =\n AlertDialogPrimitive.Description.displayName;\n\nconst AlertDialogAction = AlertDialogPrimitive.Action;\nconst AlertDialogCancel = AlertDialogPrimitive.Cancel;\n\nexport {\n AlertDialog,\n AlertDialogTrigger,\n AlertDialogPortal,\n AlertDialogOverlay,\n AlertDialogContent,\n AlertDialogHeader,\n AlertDialogFooter,\n AlertDialogTitle,\n AlertDialogDescription,\n AlertDialogAction,\n AlertDialogCancel,\n};\n","import { tv } from \"@/utils/tv\";\n\n/**\n * Ícone circular (56x56) com bg-tone-muted + fg-tone.\n * Alinhado com `.tbl-confirm-icon` do sandbox.\n */\nexport const alertModalIcon = tv({\n base: [\n \"inline-flex items-center justify-center\",\n \"size-[56px] shrink-0 rounded-radius-full\",\n \"[&_svg]:size-[26px]\",\n ],\n variants: {\n tone: {\n default: \"bg-bg-brand-subtle text-fg-brand\",\n neutral: \"bg-bg-muted text-fg-muted\",\n danger: \"bg-bg-danger-muted text-fg-danger\",\n warning: \"bg-bg-warning-muted text-fg-warning\",\n success: \"bg-bg-success-muted text-fg-success\",\n },\n },\n defaultVariants: { tone: \"default\" },\n});\n","import { AlertTriangle, AlertCircle, CheckCircle2, Info, X } from \"lucide-react\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from \"../../shadcn/alert-dialog\";\nimport { Button } from \"../Button/button\";\nimport { alertModalIcon } from \"./alert-modal.styles\";\nimport type { AlertModalProps, AlertModalTone } from \"./alert-modal.types\";\n\n/**\n * AlertModal — wrapper \"one-shot\" pro AlertDialog do shadcn.\n *\n * Cobre o caso comum de \"confirmação destrutiva\" (ex: excluir cliente):\n * <AlertModal\n * open={confirmDelete}\n * onOpenChange={setConfirmDelete}\n * tone=\"danger\"\n * title=\"Excluir cliente?\"\n * description='Esta ação não pode ser desfeita. O cliente \"Maria Silva\" será removido permanentemente.'\n * confirmLabel=\"Excluir cliente\"\n * onConfirm={handleDelete}\n * />\n *\n * Pra layouts customizados (sem ícone, com input dentro, etc), use o\n * <AlertDialog> primitive direto.\n */\n\nconst TONE_ICON: Record<AlertModalTone, React.ReactNode> = {\n default: null,\n neutral: <Info strokeWidth={2.2} />,\n danger: <AlertTriangle strokeWidth={2.2} />,\n warning: <AlertCircle strokeWidth={2.2} />,\n success: <CheckCircle2 strokeWidth={2.2} />,\n};\n\nconst TONE_BUTTON_COLOR: Record<\n AlertModalTone,\n \"primary\" | \"critical\" | \"warning\" | \"success\"\n> = {\n default: \"primary\",\n neutral: \"primary\",\n danger: \"critical\",\n warning: \"warning\",\n success: \"success\",\n};\n\nexport function AlertModal({\n open,\n onOpenChange,\n tone = \"default\",\n title,\n description,\n confirmLabel = \"Confirmar\",\n cancelLabel = \"Cancelar\",\n hideCancel,\n hideClose,\n onConfirm,\n icon,\n loading,\n className,\n}: AlertModalProps) {\n const iconNode = icon === undefined ? TONE_ICON[tone] : icon;\n\n const handleConfirm = (e: React.MouseEvent<HTMLButtonElement>) => {\n // Previne o close default do AlertDialogAction se loading — quem chamar\n // controla onOpenChange após o async terminar.\n if (loading) {\n e.preventDefault();\n return;\n }\n onConfirm?.();\n };\n\n return (\n <AlertDialog open={open} onOpenChange={onOpenChange}>\n <AlertDialogContent className={className}>\n {!hideClose && (\n <button\n type=\"button\"\n onClick={() => onOpenChange(false)}\n disabled={loading}\n aria-label=\"Fechar\"\n className=\"absolute top-pad-lg right-pad-lg z-10 grid place-items-center size-form-sm rounded-radius-md bg-transparent text-fg-muted opacity-55 transition-[background-color,color,opacity] outline-none hover:bg-bg-muted hover:text-fg-default hover:opacity-100 focus-visible:opacity-100 focus-visible:shadow-sh-ring disabled:pointer-events-none\"\n >\n <X className=\"size-4\" />\n </button>\n )}\n <AlertDialogHeader>\n {iconNode && (\n <div className={alertModalIcon({ tone })} aria-hidden=\"true\">\n {iconNode}\n </div>\n )}\n <AlertDialogTitle>{title}</AlertDialogTitle>\n {description && (\n <AlertDialogDescription>{description}</AlertDialogDescription>\n )}\n </AlertDialogHeader>\n <AlertDialogFooter>\n {!hideCancel && (\n <AlertDialogCancel asChild>\n <Button\n type=\"button\"\n color=\"secondary\"\n variant=\"outline\"\n size=\"md\"\n fullWidth\n disabled={loading}\n >\n {cancelLabel}\n </Button>\n </AlertDialogCancel>\n )}\n <AlertDialogAction asChild>\n <Button\n type=\"button\"\n color={TONE_BUTTON_COLOR[tone]}\n variant=\"filled\"\n size=\"md\"\n fullWidth\n loading={loading}\n onClick={handleConfirm}\n >\n {confirmLabel}\n </Button>\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n}\n","import { tv, type VariantProps } from \"@/utils/tv\";\n\n/**\n * Avatar styles — iGreen DS\n *\n * Circular badge with initials. No interactive states (no hover, no focus, no disabled).\n *\n * Size uses `size-comp-*` tokens (square: width = height):\n * xs = 20px (comp-2xs) | sm = 24px (comp-xs) | md = 28px (comp-sm)\n * lg = 32px (comp-md) | xl = 40px (comp-xl)\n *\n * Color applies bg + fg pairs from semantic tokens.\n * `_custom` is an internal-only variant used when `colorHex` overrides the\n * background via inline style — it intentionally applies no bg/fg so the\n * component can set them manually.\n *\n * Typography scales with size to keep initials proportional inside the circle.\n */\nexport const avatarVariants = tv({\n base: [\n \"inline-flex items-center justify-center\",\n \"shrink-0\",\n \"rounded-radius-full\",\n \"overflow-hidden\",\n \"leading-none\",\n \"font-bold\",\n \"select-none\",\n ],\n\n variants: {\n size: {\n xs: \"size-comp-2xs text-caption-sm\", // 20px / 11px\n sm: \"size-comp-xs text-caption-sm\", // 24px / 11px\n md: \"size-comp-sm text-caption-sm\", // 28px / 11px — default\n lg: \"size-comp-md text-caption-md\", // 32px / 13px\n xl: \"size-comp-xl text-label-sm\", // 40px / 14px\n },\n\n color: {\n brand: \"bg-bg-brand text-fg-on-brand\",\n success: \"bg-bg-success text-fg-on-success\",\n warning: \"bg-bg-warning text-fg-on-warning\",\n critical: \"bg-bg-danger text-fg-on-danger\",\n info: \"bg-bg-info text-fg-on-info\",\n muted: \"bg-bg-muted text-fg-muted\",\n /** Internal: used by colorHex override — no bg/fg applied. */\n _custom: \"\",\n },\n },\n\n defaultVariants: {\n size: \"md\",\n color: \"muted\",\n },\n});\n\nexport type AvatarVariantProps = VariantProps<typeof avatarVariants>;\n","import { forwardRef } from \"react\";\nimport { avatarVariants } from \"./avatar.styles\";\nimport type { AvatarProps } from \"./avatar.types\";\n\n/**\n * Avatar — circular badge with initials.\n *\n * Supports semantic `color` presets (brand, success, warning, critical, info, muted)\n * and a `colorHex` override for person-specific hex colors.\n *\n * When `colorHex` is provided, background is set via inline style and text\n * becomes `text-white` (decorative text over solid color — analogous to L-014).\n *\n * Accessibility:\n * - With `aria-label` → role=\"img\" (semantic avatar)\n * - Without `aria-label` → aria-hidden=\"true\" (decorative, inside a card/cell)\n */\nexport const Avatar = forwardRef<HTMLDivElement, AvatarProps>(\n function Avatar(\n {\n size,\n color,\n colorHex,\n children,\n className,\n style,\n \"aria-label\": ariaLabel,\n ...rest\n },\n ref,\n ) {\n const isHex = typeof colorHex === \"string\" && colorHex.startsWith(\"#\");\n\n const computedClassName = avatarVariants({\n size,\n color: isHex ? \"_custom\" : color,\n className: isHex ? [\"text-white\", className].filter(Boolean).join(\" \") : className,\n });\n\n const computedStyle = isHex\n ? { ...style, backgroundColor: colorHex }\n : style;\n\n return (\n <div\n ref={ref}\n className={computedClassName}\n style={computedStyle}\n {...(ariaLabel\n ? { role: \"img\", \"aria-label\": ariaLabel }\n : { \"aria-hidden\": true as const })}\n {...rest}\n >\n {children}\n </div>\n );\n },\n);\n\nAvatar.displayName = \"Avatar\";\n","import { useMemo } from \"react\";\nimport type { ColumnPinned } from \"./table.types\";\n\n/** Minimal column shape this hook needs. Real ColumnDef do DataTable é superset. */\nexport type WidthColumnInput = {\n field: string;\n width?: number;\n /** Default width usado quando `width` undefined. */\n defaultWidth?: number;\n pinned?: ColumnPinned;\n};\n\nexport type ColumnWidthsResult = {\n /** Largura efetiva por field (px). */\n widths: Record<string, number>;\n /** Offset sticky por field (px). Só faz sentido pra colunas pinned. */\n offsets: Record<string, number>;\n /** Total de largura ocupada pelas colunas pinned left. Usado pra calcular shadow lateral. */\n totalPinLeft: number;\n /** Total de largura ocupada pelas colunas pinned right. */\n totalPinRight: number;\n};\n\nconst DEFAULT_COLUMN_WIDTH = 160;\n\n/**\n * Calcula widths efetivos e offsets sticky cumulativos.\n *\n * Algoritmo:\n * 1. widths[field] = column.width ?? column.defaultWidth ?? DEFAULT_COLUMN_WIDTH\n * 2. Para colunas pinned=\"left\": offsets[field] = soma das widths das colunas pinned=left que vêm ANTES\n * 3. Para colunas pinned=\"right\": offsets[field] = soma das widths das colunas pinned=right que vêm DEPOIS\n * 4. Colunas não-pinned: offset = undefined\n *\n * @example\n * useColumnWidths([{field:'a',width:50,pinned:'left'}, {field:'b',width:80,pinned:'left'}, {field:'c'}])\n * → widths: {a:50, b:80, c:160}\n * → offsets: {a:0, b:50}\n * → totalPinLeft: 130, totalPinRight: 0\n */\nexport function useColumnWidths(\n columns: ReadonlyArray<WidthColumnInput>,\n): ColumnWidthsResult {\n return useMemo(() => {\n const widths: Record<string, number> = {};\n const offsets: Record<string, number> = {};\n let totalPinLeft = 0;\n let totalPinRight = 0;\n\n // Passo 1: widths efetivos\n for (const col of columns) {\n widths[col.field] =\n col.width ?? col.defaultWidth ?? DEFAULT_COLUMN_WIDTH;\n }\n\n // Passo 2: offsets left (acumulado da esquerda pra direita)\n let leftSum = 0;\n for (const col of columns) {\n if (col.pinned === \"left\") {\n offsets[col.field] = leftSum;\n leftSum += widths[col.field];\n }\n }\n totalPinLeft = leftSum;\n\n // Passo 3: offsets right (acumulado da direita pra esquerda)\n let rightSum = 0;\n for (let i = columns.length - 1; i >= 0; i--) {\n const col = columns[i];\n if (col.pinned === \"right\") {\n offsets[col.field] = rightSum;\n rightSum += widths[col.field];\n }\n }\n totalPinRight = rightSum;\n\n return { widths, offsets, totalPinLeft, totalPinRight };\n }, [columns]);\n}\n","/**\n * Constants compartilhadas do Table primitivo.\n *\n * Use estes valores em vez de duplicar literais — fonte única de verdade pra\n * larguras especiais, breakpoints, e identificadores de roles dentro do grid.\n */\n\n/** Largura padrão da coluna de seleção (checkbox header + body cells).\n * 56px = 28px checkbox + 14px padding lateral × 2. Calibrado pra hit area\n * WCAG mobile (44×44) com folga visual. */\nexport const SELECTION_COLUMN_WIDTH = 56;\n\n/** Altura do header de uma linha de tabela. Usada por skeleton, totalizer,\n * group header e quick filter row pra alinhar visualmente com a header bar. */\nexport const TABLE_HEADER_HEIGHT = 42;\n","import { tv } from \"@/utils/tv\";\n\n/**\n * Styles compartilhados das partes do TableToolbar.\n * Cada `tv()` corresponde a um sub-componente em `parts/`.\n *\n * Specs alinhadas com `.tbl-toolbar` do design-and-table-v2.\n */\n\n/* ── Root ──────────────────────────────────────────────────────────── */\n/**\n * Gaps responsivos:\n * - Mobile (< md): gap menor pra search + 2 botões caberem na mesma linha\n * - Desktop (≥ md): gap mais respirado (16px root, 10px left, 8px actions)\n */\nexport const toolbarRoot = tv({\n base: [\n \"flex items-center justify-between flex-wrap\",\n \"gap-gp-md md:gap-gp-2xl\", // 8px → 16px\n ],\n});\n\nexport const toolbarLeft = tv({\n base: [\n \"flex flex-1 items-center flex-wrap min-w-0\",\n \"gap-gp-sm md:gap-[10px]\", // 6px → 10px\n \"[&>*]:shrink-0\", // items hug, sem squeeze interno\n ],\n});\n\nexport const toolbarActions = tv({\n base: [\n \"flex items-center flex-wrap shrink-0\",\n \"gap-gp-sm md:gap-gp-md\", // 6px → 8px\n \"[&>*]:shrink-0\", // items hug, sem squeeze interno\n ],\n});\n\n/* ── Divider vertical ─────────────────────────────────────────────── */\nexport const toolbarDivider = tv({\n base: \"w-[1px] h-[24px] bg-border-default shrink-0 mx-[6px] self-center\",\n});\n\n/* ── Search input expansível ──────────────────────────────────────── */\n/**\n * Mobile (< md): fluido (`flex-1`) — ocupa o espaço restante, sem aumentar/diminuir width no foco.\n * Desktop (≥ md): width fixo 200px rest → 300px no focus-within OU quando tem valor.\n *\n * O `focus-within:` desktop expande automaticamente quando o input está focado.\n * A variant `expanded: true` mantém expandido mesmo sem foco (quando há valor).\n */\nexport const toolbarSearch = tv({\n base: [\n \"relative flex items-center gap-gp-md cursor-text\",\n \"h-form-lg px-[14px] rounded-radius-lg\",\n \"bg-bg-surface dark:bg-bg-muted\",\n \"border border-border-subtle dark:border-border-input\",\n \"shadow-sh-sm dark:shadow-sh-none\",\n \"text-fg-default\",\n // Mobile fluido / desktop width fixo + animação no focus\n \"flex-1 min-w-0 md:flex-initial\",\n \"md:w-[200px] md:focus-within:w-[300px]\",\n \"transition-[width,border-color,background-color,box-shadow] duration-[220ms] ease-[cubic-bezier(0.4,0,0.2,1)]\",\n \"focus-within:border-border-brand focus-within:shadow-sh-ring\",\n \"[&_svg]:size-[14px] [&_svg]:text-fg-muted [&_svg]:shrink-0\",\n ],\n variants: {\n /** Quando true, mantém expandido (300px) mesmo sem foco — útil quando tem valor (desktop only) */\n expanded: {\n true: \"md:w-[300px]\",\n false: \"\",\n },\n },\n defaultVariants: { expanded: false },\n});\n\nexport const toolbarSearchInput = tv({\n base: [\n \"flex-1 min-w-0 bg-transparent border-0 outline-none\",\n \"text-[13px] text-fg-default\",\n \"placeholder:text-fg-muted\",\n ],\n});\n\n/**\n * Dot indicator (filtros aplicados) — pequeno círculo brand no canto superior direito.\n *\n * NOTA: `ToolbarToolButton` agora compõe o `Button` do DS — seu estilo vem do\n * Button (color/variant/size). Esse helper só pinta o ponto de \"tem aplicado\".\n */\nexport const toolbarToolDot = tv({\n base: [\n \"absolute -top-[4px] -right-[4px] z-[2] pointer-events-none\",\n \"size-[13px] rounded-radius-full\",\n \"bg-bg-brand border-2 border-bg-canvas\",\n ],\n});\n\n/* ── Segmented (density-toggle, view-mode-toggle) ───────────────── */\nexport const toolbarSegmented = tv({\n base: [\n \"items-center gap-[2px] p-[3px]\",\n \"bg-bg-muted rounded-radius-lg\",\n \"h-form-lg\",\n ],\n variants: {\n fluid: {\n true: \"flex w-full\",\n false: \"inline-flex shrink-0\",\n },\n },\n defaultVariants: { fluid: false },\n});\n\nexport const toolbarSegmentedButton = tv({\n base: [\n \"grid place-items-center\",\n \"h-[34px] min-w-[36px] px-pad-md\",\n \"rounded-radius-md border-0 bg-transparent cursor-pointer outline-none\",\n \"text-[13px] text-fg-muted\",\n \"transition-[background-color,color,box-shadow] duration-150\",\n \"hover:text-fg-default\",\n \"focus-visible:shadow-sh-ring\",\n \"[&_svg]:size-[14px]\",\n \"disabled:opacity-50 disabled:pointer-events-none\",\n ],\n variants: {\n isActive: {\n true: \"bg-bg-accent text-fg-default font-semibold shadow-sh-sm\",\n false: \"\",\n },\n fluid: {\n true: \"flex-1\",\n false: \"shrink-0\",\n },\n },\n defaultVariants: { isActive: false, fluid: false },\n});\n\n/* ── View tabs group (Todos/Meus/Ativos…) ───────────────────────── */\nexport const toolbarTabs = tv({\n base: [\n \"items-center gap-[2px] p-[3px]\",\n \"bg-bg-muted rounded-radius-lg\",\n \"h-form-lg max-w-full overflow-x-auto\",\n \"[scrollbar-width:none] [&::-webkit-scrollbar]:hidden\",\n ],\n variants: {\n fluid: {\n true: \"flex w-full\",\n false: \"inline-flex\",\n },\n },\n defaultVariants: { fluid: false },\n});\n\nexport const toolbarTabWrap = tv({\n base: [\n \"relative inline-flex items-center\",\n \"rounded-radius-md\",\n \"transition-[background-color,box-shadow,padding-right] duration-[220ms] ease-[cubic-bezier(0.4,0,0.2,1)]\",\n ],\n variants: {\n isActive: {\n true: \"bg-bg-accent shadow-sh-sm\",\n false: \"\",\n },\n fluid: {\n true: \"flex-1 justify-center\",\n false: \"shrink-0\",\n },\n },\n defaultVariants: { isActive: false, fluid: false },\n});\n\nexport const toolbarTabButton = tv({\n base: [\n \"inline-flex items-center gap-gp-sm h-[34px] px-[14px]\",\n \"rounded-radius-md border-0 bg-transparent cursor-pointer outline-none\",\n \"text-[13px] font-medium text-fg-muted whitespace-nowrap\",\n \"transition-[color,padding-right] duration-[220ms] ease-[cubic-bezier(0.4,0,0.2,1)]\",\n \"hover:text-fg-default\",\n \"focus-visible:shadow-sh-ring\",\n ],\n variants: {\n isActive: {\n true: \"text-fg-default font-semibold\",\n false: \"\",\n },\n fluid: {\n true: \"flex-1 justify-center\",\n false: \"\",\n },\n },\n defaultVariants: { isActive: false, fluid: false },\n});\n\n/**\n * Botão \"X\" pra fechar tab custom — escondido por trás do tab (margin -18px),\n * desliza pra fora ao hover do wrap.\n */\nexport const toolbarTabClose = tv({\n base: [\n \"grid place-items-center size-[18px] -ml-[18px]\",\n \"rounded-radius-full border-0 bg-transparent text-fg-muted cursor-pointer\",\n \"opacity-0 scale-[0.6] origin-center pointer-events-none\",\n \"transition-[margin-left,opacity,transform,background-color,color] duration-[220ms] ease-[cubic-bezier(0.4,0,0.2,1)]\",\n \"group-hover/wrap:ml-0 group-hover/wrap:opacity-100 group-hover/wrap:scale-100 group-hover/wrap:pointer-events-auto\",\n \"hover:bg-bg-accent hover:text-fg-default\",\n \"[&_svg]:size-[11px]\",\n ],\n});\n\n/* ── Applied filters (chips abaixo da toolbar) ──────────────────── */\n/**\n * Espaçamento: toolbar → 16px → divider (border-top) → 16px → chips.\n * `mt-pad-3xl` afasta o border-top da toolbar; `pt-pad-3xl` afasta o\n * conteúdo interno (chips) do border.\n */\nexport const toolbarApplied = tv({\n base: \"flex items-center flex-wrap gap-gp-md\",\n variants: {\n /**\n * Separator (margem topo 16px + border + padding 16px) entre toolbar\n * header e chips. Default `true`. Espaçamento total: 16px → divider → 16px → chips.\n */\n separator: {\n true: \"mt-pad-2xl pt-pad-2xl border-t border-border-default\",\n false: \"\",\n },\n },\n defaultVariants: {\n separator: true,\n },\n});\n\nexport const toolbarAppliedChip = tv({\n base: [\n \"inline-flex items-center gap-gp-md\",\n \"h-form-md pl-pad-sm pr-pad-lg\",\n \"bg-bg-surface dark:bg-bg-muted\",\n \"border border-dashed border-border-input rounded-radius-lg\",\n \"text-[12px] text-fg-default\",\n \"transition-[background-color,border-color] duration-150\",\n ],\n variants: {\n interactive: {\n true: [\n \"cursor-pointer\",\n \"hover:bg-bg-muted-hover hover:border-border-default\",\n \"dark:hover:bg-bg-accent\",\n \"focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-ring-brand\",\n ],\n },\n },\n});\n\nexport const toolbarAppliedChipRemove = tv({\n base: [\n \"grid place-items-center size-[18px] shrink-0\",\n \"rounded-radius-full border-0 bg-transparent text-fg-subtle cursor-pointer outline-none\",\n \"transition-colors duration-150\",\n \"hover:text-fg-default\",\n \"focus-visible:shadow-sh-ring\",\n \"[&_svg]:size-[14px]\",\n ],\n});\n\nexport const toolbarAppliedChipName = tv({\n base: \"font-semibold text-fg-default\",\n});\n\nexport const toolbarAppliedChipOp = tv({\n base: \"text-fg-muted text-[11.5px]\",\n});\n\nexport const toolbarAppliedChipValue = tv({\n base: [\n \"inline-flex items-center h-[22px] px-pad-md\",\n \"rounded-radius-sm\",\n \"bg-bg-muted dark:bg-bg-accent\",\n \"text-[12px] font-medium text-fg-default\",\n ],\n});\n\nexport const toolbarAppliedClearLink = tv({\n base: [\n \"ml-pad-sm text-[12px] font-medium text-fg-brand cursor-pointer outline-none\",\n \"bg-transparent border-0 p-0\",\n \"transition-opacity duration-150\",\n \"hover:underline underline-offset-2\",\n \"focus-visible:underline\",\n \"disabled:opacity-50 disabled:pointer-events-none\",\n ],\n});\n\n/* ── Bulk actions bar ─────────────────────────────────────────────── */\n/**\n * Spec alinhada com `.tbl-bulk-bar` do design-and-table-v2:\n * - padding 10px 14px, gap 12px, radius xl (12px)\n * - bg-brand-subtle + border-brand + fg-brand\n * - flex-wrap pra mobile cair em coluna naturalmente\n */\nexport const bulkBarRoot = tv({\n base: [\n \"flex items-center flex-wrap gap-gp-xl\",\n \"py-[10px] px-[14px] rounded-radius-xl\",\n \"bg-bg-brand-subtle border border-border-brand text-fg-brand\",\n ],\n});\n\nexport const bulkBarCount = tv({\n base: [\n \"inline-flex items-center gap-gp-md shrink-0\",\n \"text-[13px] font-semibold\",\n \"text-fg-brand dark:text-fg-default\",\n \"[&_svg]:size-[14px]\",\n ],\n});\n\nexport const bulkBarActions = tv({\n base: [\n \"flex items-center flex-wrap gap-gp-sm flex-1 min-w-0\",\n \"[&>*]:shrink-0\",\n ],\n});\n\nexport const bulkBarClear = tv({\n base: [\n \"shrink-0 ml-auto\",\n \"bg-transparent border-0 p-0 cursor-pointer outline-none\",\n \"text-[12px] font-semibold text-fg-brand\",\n \"transition-opacity duration-150\",\n \"hover:underline underline-offset-2\",\n \"focus-visible:underline\",\n \"disabled:opacity-50 disabled:pointer-events-none\",\n ],\n});\n","import type { ReactNode } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { toolbarActions, toolbarLeft, toolbarRoot } from \"./table-toolbar.styles\";\n\n/**\n * TableToolbar — container root da toolbar de tabela.\n *\n * Layout default: flex justify-between em duas zonas (left + actions).\n * Dumb: recebe `left` e `actions` como slots ReactNode — o consumer monta\n * livremente cada zona com as partes (`ToolbarSearch`, `ToolbarSegmented`,\n * `ToolbarTabs`, `ToolbarToolButton`, `ToolbarDivider`).\n *\n * Modo bulk: quando `bulkBar` é passado, ele substitui o conteúdo inteiro\n * da toolbar. Use com `<BulkActionsBar count={...}>` — ele auto-some quando\n * `count === 0`, então passe-o direto na prop sem condicional externo:\n *\n * <TableToolbar\n * left={...}\n * actions={...}\n * bulkBar={<BulkActionsBar count={selected.length} onClear={...}>...</BulkActionsBar>}\n * />\n *\n * Pra filtros aplicados (chips), use `<ToolbarApplied>` LOGO ABAIXO da toolbar.\n */\nexport type TableToolbarProps = {\n /** Conteúdo da zona esquerda (search, view mode, tabs, \"+\"). */\n left?: ReactNode;\n /** Conteúdo da zona direita (filtrar, ordenar, cols, density, exportar). */\n actions?: ReactNode;\n /**\n * Quando renderizado (não null/false), substitui left+actions pela view de\n * ações em massa. Combina com `<BulkActionsBar>` (que retorna null quando\n * count=0), assim o swap fica automático sem condicional no consumer.\n */\n bulkBar?: ReactNode;\n className?: string;\n};\n\nexport function TableToolbar({\n left,\n actions,\n bulkBar,\n className,\n}: TableToolbarProps) {\n if (bulkBar) {\n return <div className={cn(\"w-full\", className)}>{bulkBar}</div>;\n }\n return (\n <div className={cn(toolbarRoot(), className)}>\n <div className={toolbarLeft()}>{left}</div>\n <div className={toolbarActions()}>{actions}</div>\n </div>\n );\n}\n","import { forwardRef } from \"react\";\nimport { Search } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { toolbarSearch, toolbarSearchInput } from \"../table-toolbar.styles\";\n\nexport type ToolbarSearchProps = Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n \"size\"\n> & {\n /** className do wrapper (não do input) */\n wrapperClassName?: string;\n /** Largura expandida quando focus ou tem value. Default true. */\n autoExpand?: boolean;\n};\n\n/**\n * ToolbarSearch — input de busca compacto que expande no foco / quando tem valor.\n *\n * Wrapper é um `<label>` semântico — clicar em qualquer parte (ícone, espaço\n * vazio, etc) foca o input nativamente. Sem JS necessário.\n *\n * Dumb: estado vem de fora via `value` + `onChange`.\n */\nexport const ToolbarSearch = forwardRef<HTMLInputElement, ToolbarSearchProps>(\n (\n {\n value,\n placeholder = \"Buscar...\",\n className,\n wrapperClassName,\n autoExpand = true,\n \"aria-label\": ariaLabel = \"Buscar\",\n ...inputProps\n },\n ref,\n ) => {\n const hasValue = Boolean(value);\n const expanded = autoExpand ? hasValue : false;\n\n return (\n <label className={cn(toolbarSearch({ expanded }), wrapperClassName)}>\n <Search strokeWidth={1.8} aria-hidden=\"true\" />\n <input\n ref={ref}\n type=\"text\"\n value={value}\n placeholder={placeholder}\n aria-label={ariaLabel}\n className={cn(toolbarSearchInput(), className)}\n {...inputProps}\n />\n </label>\n );\n },\n);\nToolbarSearch.displayName = \"ToolbarSearch\";\n","import { cn } from \"@/lib/utils\";\nimport { toolbarDivider } from \"../table-toolbar.styles\";\n\nexport type ToolbarDividerProps = React.HTMLAttributes<HTMLSpanElement>;\n\n/**\n * Divisor vertical 1px × 24px usado entre grupos da toolbar.\n */\nexport function ToolbarDivider({ className, ...props }: ToolbarDividerProps) {\n return (\n <span\n aria-hidden=\"true\"\n className={cn(toolbarDivider(), className)}\n {...props}\n />\n );\n}\n","import { cn } from \"@/lib/utils\";\nimport {\n toolbarSegmented,\n toolbarSegmentedButton,\n} from \"../table-toolbar.styles\";\nimport type { ToolbarSegmentedItem } from \"../table-toolbar.types\";\n\nexport type ToolbarSegmentedProps<TValue extends string = string> = {\n /** Valor atualmente selecionado */\n value: TValue;\n onValueChange: (value: TValue) => void;\n items: ToolbarSegmentedItem<TValue>[];\n /** Aria-label do radiogroup */\n ariaLabel?: string;\n /** Quando `true`, ocupa toda a largura disponível e cada item vira flex-1. */\n fluid?: boolean;\n className?: string;\n};\n\n/**\n * ToolbarSegmented — grupo de botões segmentado (track bg-muted, item ativo bg-accent).\n * Padrão usado por: density-toggle (3 níveis), view-mode-toggle (table/kanban).\n *\n * `fluid` faz o grupo ocupar 100% do pai e cada item dividir o espaço igualmente\n * (útil em sheet/drawer mobile).\n */\nexport function ToolbarSegmented<TValue extends string = string>({\n value,\n onValueChange,\n items,\n ariaLabel,\n fluid,\n className,\n}: ToolbarSegmentedProps<TValue>) {\n return (\n <div\n role=\"radiogroup\"\n aria-label={ariaLabel}\n className={cn(toolbarSegmented({ fluid }), className)}\n >\n {items.map((item) => {\n const isActive = item.value === value;\n return (\n <button\n key={item.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={isActive}\n aria-pressed={isActive}\n aria-label={item.label}\n title={item.label}\n disabled={item.disabled}\n onClick={() => onValueChange(item.value)}\n className={toolbarSegmentedButton({ isActive, fluid })}\n >\n {item.children}\n </button>\n );\n })}\n </div>\n );\n}\n","import { X } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport {\n toolbarTabButton,\n toolbarTabClose,\n toolbarTabs,\n toolbarTabWrap,\n} from \"../table-toolbar.styles\";\nimport type { ToolbarTab } from \"../table-toolbar.types\";\n\nexport type ToolbarTabsProps = {\n tabs: ToolbarTab[];\n activeId: string;\n onSelect: (id: string) => void;\n /** Callback do X em tabs custom. Se omitido, X não dispara nada (só visual). */\n onClose?: (id: string) => void;\n ariaLabel?: string;\n /** Quando `true`, ocupa toda a largura disponível e cada tab vira flex-1. */\n fluid?: boolean;\n className?: string;\n};\n\n/**\n * ToolbarTabs — grupo de view tabs salvas (Todos / Meus / Ativos / Royals…).\n * Tabs com `custom: true` exibem botão X (escondido no rest, visível no hover do wrap).\n *\n * `fluid` faz cada tab dividir o espaço igualmente (útil em sheet/drawer mobile).\n */\nexport function ToolbarTabs({\n tabs,\n activeId,\n onSelect,\n onClose,\n ariaLabel = \"Views salvas\",\n fluid,\n className,\n}: ToolbarTabsProps) {\n return (\n <div\n role=\"tablist\"\n aria-label={ariaLabel}\n className={cn(toolbarTabs({ fluid }), className)}\n >\n {tabs.map((tab) => {\n const isActive = tab.id === activeId;\n return (\n <div\n key={tab.id}\n className={cn(\"group/wrap\", toolbarTabWrap({ isActive, fluid }))}\n >\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={isActive}\n onClick={() => onSelect(tab.id)}\n className={toolbarTabButton({ isActive, fluid })}\n >\n <span>{tab.name}</span>\n </button>\n {tab.custom && (\n <button\n type=\"button\"\n aria-label=\"Fechar view\"\n className={toolbarTabClose()}\n onClick={(e) => {\n e.stopPropagation();\n onClose?.(tab.id);\n }}\n >\n <X strokeWidth={2.4} />\n </button>\n )}\n </div>\n );\n })}\n </div>\n );\n}\n","import { forwardRef, type ReactNode } from \"react\";\nimport { Button } from \"../../Button/button\";\nimport { cn } from \"@/lib/utils\";\nimport { toolbarToolDot } from \"../table-toolbar.styles\";\n\nexport type ToolbarToolButtonProps = Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n \"children\" | \"color\"\n> & {\n /** Ícone à esquerda */\n icon?: ReactNode;\n /** Label do botão. Se omitido, vira icon-only (40×40). */\n label?: ReactNode;\n /** Borda+texto em brand (estado \"tem filtros aplicados\") */\n isActive?: boolean;\n /** Mostra dot indicator no canto superior direito (filtros aplicados) */\n hasIndicator?: boolean;\n};\n\n/**\n * ToolbarToolButton — botão usado nas actions da toolbar (Filtrar/Exportar/Ordenar/Cols/More).\n *\n * **Implementação:** usa `<Button>` do DS por baixo. Visual vem direto do Button\n * (`secondary outline` no rest, `primary soft` em isActive). Só adicionamos\n * `border-border-brand` no isActive (variant soft não tem border) e wrapper\n * `relative` pra ancorar o dot indicator.\n *\n * Variantes:\n * - Com label → size=\"md\"\n * - Sem label → size=\"icon-md\" (40×40)\n * - isActive → primary soft com border-brand\n * - hasIndicator → dot brand absoluto no canto\n */\nexport const ToolbarToolButton = forwardRef<\n HTMLButtonElement,\n ToolbarToolButtonProps\n>(\n (\n {\n icon,\n label,\n isActive,\n hasIndicator,\n className,\n ...rest\n },\n ref,\n ) => {\n const iconOnly = !label;\n return (\n <Button\n ref={ref}\n color={isActive ? \"primary\" : \"secondary\"}\n variant={isActive ? \"soft\" : \"outline\"}\n size={iconOnly ? \"icon-md\" : \"md\"}\n iconLeft={iconOnly ? undefined : icon}\n className={cn(\n \"relative\",\n // Active: Button primary soft não tem border — adicionamos brand\n isActive && \"border-border-brand hover:border-border-brand\",\n className,\n )}\n {...rest}\n >\n {iconOnly ? icon : label}\n {hasIndicator && (\n <span className={toolbarToolDot()} aria-hidden=\"true\" />\n )}\n </Button>\n );\n },\n);\nToolbarToolButton.displayName = \"ToolbarToolButton\";\n\n/* ── Save button \"+\" — Button ghost icon-only ─────────────────── */\n\nexport type ToolbarSaveButtonProps = Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n \"color\"\n> & {\n isOpen?: boolean;\n};\n\n/**\n * ToolbarSaveButton — botão \"+\" pra abrir o popover de visões salvas.\n * Usa `<Button>` do DS (variant=ghost, size=icon-md). Quando `isOpen`,\n * aplica o visual de hover persistente.\n */\nexport const ToolbarSaveButton = forwardRef<\n HTMLButtonElement,\n ToolbarSaveButtonProps\n>(({ className, isOpen, children, ...rest }, ref) => (\n <Button\n ref={ref}\n color=\"secondary\"\n variant=\"ghost\"\n size=\"icon-md\"\n className={cn(\n isOpen && \"bg-bg-muted text-fg-default\",\n className,\n )}\n {...rest}\n >\n {children}\n </Button>\n));\nToolbarSaveButton.displayName = \"ToolbarSaveButton\";\n","import type { ReactNode } from \"react\";\nimport { CircleX } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport {\n toolbarApplied,\n toolbarAppliedChip,\n toolbarAppliedChipName,\n toolbarAppliedChipOp,\n toolbarAppliedChipRemove,\n toolbarAppliedChipValue,\n toolbarAppliedClearLink,\n} from \"../table-toolbar.styles\";\nimport type { AppliedFilter, AppliedFilterOp } from \"../table-toolbar.types\";\n\n/** Helper exportado pra renderizar um valor como tag estilizada — uso em renderChip custom. */\nexport const toolbarAppliedTagClass = toolbarAppliedChipValue;\n\nexport type ToolbarAppliedProps = {\n filters: AppliedFilter[];\n onRemove: (id: string) => void;\n onClearAll?: () => void;\n /** Label do link \"Limpar todos\". Default \"Limpar todos\". Passe `null` pra esconder. */\n clearLabel?: React.ReactNode | null;\n /** Mapa operador → símbolo exibido (ex: { eq: \"=\", contains: \"contém\" }) */\n opLabels?: Partial<Record<string, string>>;\n /**\n * Render custom do chip — recebe o chip default (`<span>` com a estrutura\n * padrao) e permite envolver (ex: com PopoverTrigger). Use pra adicionar\n * comportamento (click reabre edicao) mantendo o layout visual.\n *\n * 2º param `isPendingOpen` informa se este chip está marcado como\n * \"abrir popover automaticamente\" via `pendingOpenId` — consumer usa pra\n * controlar `open={isPendingOpen}` do Popover wrapper.\n */\n renderChip?: (\n filter: AppliedFilter,\n defaultChip: ReactNode,\n isPendingOpen: boolean,\n ) => ReactNode;\n /**\n * Mostra separator (margem-topo + border) entre o toolbar header e os chips.\n * Default `true` (uso standalone). Setar `false` quando ja ha gap externo\n * (ex: dentro do DataTable que controla espacamento via wrapper).\n */\n separator?: boolean;\n /**\n * ID de chip que deve abrir popover automaticamente (controlled).\n * Quando definido, `renderChip` recebe `isPendingOpen=true` pro chip\n * com `filter.id === pendingOpenId`. Pattern usado pra \"filter shortcut\"\n * do header — clicar ícone na coluna abre o popover do chip aqui.\n */\n pendingOpenId?: string | null;\n /** Disparado quando o pending muda (null = popover fechado ou cleared). */\n onPendingOpenIdChange?: (next: string | null) => void;\n className?: string;\n};\n\nconst DEFAULT_OP_LABELS: Record<AppliedFilterOp, string> = {\n eq: \"=\",\n neq: \"≠\",\n contains: \"contém\",\n gt: \">\",\n lt: \"<\",\n};\n\n/**\n * ToolbarApplied — chips dos filtros aplicados (renderiza embaixo da toolbar).\n *\n * Quando `filters` está vazio, retorna `null` (sem render).\n * Cada chip tem: [X remove] [Nome] [Operador] [Valor formatado]\n * Link \"Limpar todos\" à direita se houver mais de 0 filtros.\n *\n * Componente dumb: o consumer mantém o array de filtros e implementa o\n * delete/clear. Para gerenciar estado com menos boilerplate, veja `useToolbarFilters`.\n */\nexport function ToolbarApplied({\n filters,\n onRemove,\n onClearAll,\n clearLabel = \"Limpar todos\",\n opLabels,\n renderChip,\n separator = true,\n pendingOpenId,\n className,\n}: ToolbarAppliedProps) {\n if (filters.length === 0) return null;\n\n const resolveOp = (op: AppliedFilterOp): string =>\n opLabels?.[op] ?? DEFAULT_OP_LABELS[op] ?? String(op);\n\n return (\n <div className={cn(toolbarApplied({ separator }), className)}>\n {filters.map((f) => {\n const isPendingOpen = pendingOpenId === f.id;\n const defaultChip = (\n <span className={toolbarAppliedChip({ interactive: !!renderChip })}>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onRemove(f.id);\n }}\n aria-label=\"Remover filtro\"\n className={toolbarAppliedChipRemove()}\n >\n <CircleX strokeWidth={2} aria-hidden=\"true\" />\n </button>\n <span className={toolbarAppliedChipName()}>{f.columnLabel}</span>\n <span className={toolbarAppliedChipOp()}>{resolveOp(f.op)}</span>\n {Array.isArray(f.value) ? (\n <span className=\"inline-flex items-center gap-gp-2xs\">\n {(f.value as ReactNode[]).map((v, i) => (\n <span key={i} className={toolbarAppliedChipValue()}>\n {v}\n </span>\n ))}\n </span>\n ) : (\n <span className={toolbarAppliedChipValue()}>{f.value}</span>\n )}\n </span>\n );\n return (\n <div key={f.id} className=\"inline-flex\">\n {renderChip\n ? renderChip(f, defaultChip, isPendingOpen)\n : defaultChip}\n </div>\n );\n })}\n {clearLabel !== null && onClearAll && (\n <button\n type=\"button\"\n onClick={onClearAll}\n className={toolbarAppliedClearLink()}\n >\n {clearLabel}\n </button>\n )}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Check } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"../../Button/button\";\nimport {\n bulkBarRoot,\n bulkBarCount,\n bulkBarActions,\n bulkBarClear,\n} from \"../table-toolbar.styles\";\n\n/**\n * BulkActionsBar — barra de ações em massa (versão da toolbar quando há\n * itens selecionados na tabela).\n *\n * Visual alinhado com `.tbl-bulk-bar` do design-and-table-v2:\n * - fundo brand-subtle, borda brand, radius xl\n * - contagem à esquerda (ícone Check + label dinâmica)\n * - ações no meio (botões outline primary; danger usa soft critical)\n * - link \"Cancelar seleção\" no final\n *\n * Renderização condicional: quando `count === 0`, retorna `null`.\n * Use como `bulkBar` prop do `<TableToolbar>` pra trocar a view inteira,\n * ou renderize solto onde precisar.\n */\nexport type BulkActionsBarProps = {\n /** Quantidade de itens selecionados. Quando 0, o componente não renderiza. */\n count: number;\n /**\n * Label da contagem. Default: `${count} selecionado(s)`.\n * Recebe `count` pra você customizar singular/plural.\n */\n countLabel?: (count: number) => ReactNode;\n /** Callback do link \"Cancelar seleção\". */\n onClear?: () => void;\n /** Texto do link de limpar. Default: \"Cancelar seleção\". */\n clearLabel?: ReactNode;\n /** Ações da barra — use `<BulkActionButton>` ou compose como quiser. */\n children?: ReactNode;\n className?: string;\n};\n\nexport function BulkActionsBar({\n count,\n countLabel,\n onClear,\n clearLabel = \"Cancelar seleção\",\n children,\n className,\n}: BulkActionsBarProps) {\n if (count <= 0) return null;\n\n const label =\n typeof countLabel === \"function\"\n ? countLabel(count)\n : `${count} selecionado${count > 1 ? \"s\" : \"\"}`;\n\n return (\n <div\n role=\"toolbar\"\n aria-label=\"Ações em massa\"\n className={cn(bulkBarRoot(), className)}\n >\n <div className={bulkBarCount()}>\n <Check strokeWidth={2.4} />\n {label}\n </div>\n <div className={bulkBarActions()}>{children}</div>\n {onClear ? (\n <button type=\"button\" onClick={onClear} className={bulkBarClear()}>\n {clearLabel}\n </button>\n ) : null}\n </div>\n );\n}\n\n/* ── BulkActionButton ──────────────────────────────────────────────── */\n\nexport type BulkActionButtonProps = {\n icon?: ReactNode;\n children?: ReactNode;\n /** \"default\" usa primary outline; \"danger\" usa critical soft. */\n variant?: \"default\" | \"danger\";\n onClick?: React.MouseEventHandler<HTMLButtonElement>;\n disabled?: boolean;\n className?: string;\n /** aria-label quando só ícone. */\n \"aria-label\"?: string;\n};\n\n/**\n * Helper que padroniza o botão de ação dentro da bulk bar.\n * Usa `<Button>` do DS por baixo, com shape=\"pill\":\n *\n * default → primary outline pill xs\n * - light: bg-surface + border-brand + fg-brand\n * - dark : bg transparente + border + fg-brand (verde brilhante)\n *\n * danger → critical soft pill xs\n * - light/dark: bg-danger-muted + fg-danger (sem overrides)\n */\nexport function BulkActionButton({\n icon,\n children,\n variant = \"default\",\n onClick,\n disabled,\n className,\n ...rest\n}: BulkActionButtonProps) {\n // No dark, default vira transparente (sem bg-surface) e perde a shadow.\n // Danger ganha border-danger-muted pra destacar o botão destrutivo.\n const darkOverrides =\n variant === \"danger\"\n ? \"border border-border-danger-muted\"\n : \"dark:bg-transparent dark:shadow-sh-none\";\n\n return (\n <Button\n color={variant === \"danger\" ? \"critical\" : \"primary\"}\n variant={variant === \"danger\" ? \"soft\" : \"outline\"}\n size=\"xs\"\n shape=\"pill\"\n iconLeft={icon}\n onClick={onClick}\n disabled={disabled}\n className={cn(darkOverrides, className)}\n {...rest}\n >\n {children}\n </Button>\n );\n}\n","import type { ReactNode } from \"react\";\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"../../../shadcn/dropdown-menu\";\n\nexport type MoreMenuProps = {\n /** Botão que dispara o menu (geralmente `<ToolbarToolButton icon={<MoreHorizontal />}>`) */\n trigger: ReactNode;\n /** Itens do menu — use `MoreMenuItem`, `MoreMenuCheckboxItem`, `MoreMenuSeparator`. */\n children: ReactNode;\n /** Estado controlado (opcional — auto-gerencia se omitido). */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Alinhamento do menu em relação ao trigger. Default `\"end\"` (alinha à direita). */\n align?: \"start\" | \"center\" | \"end\";\n /** Espaço entre trigger e menu (px). Default 6. */\n sideOffset?: number;\n /** className extra no DropdownMenuContent (caso queira ajustar min-width). */\n className?: string;\n};\n\n/**\n * MoreMenu — popover de \"...\" (mais ações) da TableToolbar.\n *\n * Wrapper fino do `<DropdownMenu>` do shadcn com defaults pra contexto de\n * toolbar (`align=\"end\"`, `sideOffset=6`). Pra customizar items use os aliases:\n *\n * <MoreMenu trigger={<ToolbarToolButton ... />}>\n * <MoreMenuItem onSelect={...}>\n * <Grid3x3 />\n * Mostrar bordas entre colunas\n * </MoreMenuItem>\n * <MoreMenuItem onSelect={...}>\n * <Maximize2 />\n * Tela cheia\n * </MoreMenuItem>\n * <MoreMenuSeparator />\n * <MoreMenuItem variant=\"destructive\" onSelect={...}>\n * <Trash2 />\n * Resetar visualização\n * </MoreMenuItem>\n * </MoreMenu>\n *\n * Aliases re-exportam os primitives equivalentes do DropdownMenu:\n * - `MoreMenuItem` → `DropdownMenuItem` (com variant?: \"default\" | \"destructive\")\n * - `MoreMenuCheckboxItem` → `DropdownMenuCheckboxItem` (toggle com check)\n * - `MoreMenuRadioGroup` + `MoreMenuRadioItem` → escolha única\n * - `MoreMenuSeparator` → `DropdownMenuSeparator` (1px divider)\n * - `MoreMenuLabel` → `DropdownMenuLabel` (heading discreto)\n */\nexport function MoreMenu({\n trigger,\n children,\n open,\n onOpenChange,\n align = \"end\",\n sideOffset = 6,\n className,\n}: MoreMenuProps) {\n return (\n <DropdownMenu open={open} onOpenChange={onOpenChange}>\n <DropdownMenuTrigger asChild>{trigger}</DropdownMenuTrigger>\n <DropdownMenuContent\n align={align}\n sideOffset={sideOffset}\n className={className}\n >\n {children}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n\n/* ── Aliases — items prontos pro MoreMenu ──────────────────────────── */\nexport {\n DropdownMenuItem as MoreMenuItem,\n DropdownMenuCheckboxItem as MoreMenuCheckboxItem,\n DropdownMenuRadioGroup as MoreMenuRadioGroup,\n DropdownMenuRadioItem as MoreMenuRadioItem,\n DropdownMenuSeparator as MoreMenuSeparator,\n DropdownMenuLabel as MoreMenuLabel,\n};\n","import * as React from \"react\";\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\";\n\nimport { cn } from \"@/lib/utils\";\n\n/**\n * Popover — primitives baixo nível pra menus flutuantes (Cols, Sort, Filter, Views).\n *\n * Visual unificado com DropdownMenu/Select: bg-bg-dropdown (frosted-glass no\n * dark via `before:backdrop-blur-2xl`), border-default, radius 12px, shadow-lg\n * + outline-float (halo). Padronizado pra evitar inconsistência visual entre\n * menus de ação (DropdownMenu) e menus de configuração (Popover de Filtros,\n * Sort, Cols, Views).\n *\n * Não tem `Item` próprio — o consumer monta o conteúdo do popover livremente.\n * Pra menus de ação com items semânticos, prefira `DropdownMenu`.\n */\n\nconst Popover = PopoverPrimitive.Root;\nconst PopoverTrigger = PopoverPrimitive.Trigger;\nconst PopoverAnchor = PopoverPrimitive.Anchor;\nconst PopoverClose = PopoverPrimitive.Close;\n\ntype PopoverContentProps = React.ComponentPropsWithoutRef<\n typeof PopoverPrimitive.Content\n> & {\n /**\n * Renderiza o conteúdo SEM `<Portal>`. Útil quando o conteúdo interno usa\n * libs como dnd-kit que conflitam com o transform do Floating UI do Portal.\n * Default `false` (usa portal — comportamento padrão).\n */\n disablePortal?: boolean;\n};\n\nconst PopoverContent = React.forwardRef<\n React.ElementRef<typeof PopoverPrimitive.Content>,\n PopoverContentProps\n>(\n (\n { className, align = \"center\", sideOffset = 6, disablePortal, ...props },\n ref,\n ) => {\n const content = (\n <PopoverPrimitive.Content\n ref={ref}\n align={align}\n sideOffset={sideOffset}\n className={cn(\n \"relative z-50\",\n // Unificado com DropdownMenu/Select: bg-bg-dropdown (frosted no dark)\n // + border-border-default + outline-float. O `before` pseudo-element\n // aplica o blur backdrop (necessário pra bg-bg-dropdown semi-transparente\n // render correto no dark mode).\n \"bg-bg-dropdown\",\n \"border border-border-default rounded-[12px] shadow-sh-lg outline-float\",\n \"before:pointer-events-none before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:backdrop-blur-2xl before:backdrop-saturate-150\",\n \"text-fg-default\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n \"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n \"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2\",\n \"data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n className,\n )}\n {...props}\n />\n );\n\n if (disablePortal) return content;\n\n return <PopoverPrimitive.Portal>{content}</PopoverPrimitive.Portal>;\n },\n);\nPopoverContent.displayName = PopoverPrimitive.Content.displayName;\n\nexport { Popover, PopoverTrigger, PopoverAnchor, PopoverClose, PopoverContent };\n","import { useState, type ComponentType, type ReactNode } from \"react\";\nimport { GripVertical, Pin, PinOff } from \"lucide-react\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../../../shadcn/popover\";\nimport { Checkbox } from \"../../../shadcn/checkbox\";\nimport { cn } from \"@/lib/utils\";\n\n/* ── Types ────────────────────────────────────────────────────────── */\nexport type ColsPopoverColumn = {\n key: string;\n label: ReactNode;\n /** Ícone do tipo (lucide component) */\n icon?: ComponentType<{ className?: string }>;\n};\n\nexport type ColsPopoverProps = {\n trigger: ReactNode;\n columns: ColsPopoverColumn[];\n visibleCols: Set<string>;\n onVisibleChange: (next: Set<string>) => void;\n pinnedCols: Set<string>;\n onPinnedChange: (next: Set<string>) => void;\n /**\n * Callback de reordenação. Quando passado, ativa o grip drag handle\n * e as linhas se tornam arrastáveis (HTML5 drag).\n */\n onColumnsReorder?: (next: ColsPopoverColumn[]) => void;\n title?: ReactNode;\n hideShowAll?: boolean;\n hideOnlyPinned?: boolean;\n showAllLabel?: ReactNode;\n onlyPinnedLabel?: ReactNode;\n align?: \"start\" | \"center\" | \"end\";\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n className?: string;\n};\n\n/**\n * ColsPopover — popover de gerenciamento de colunas da tabela.\n *\n * Funcionalidades:\n * - Toggle visibility (checkbox por coluna)\n * - Toggle pin (botão pin que aparece em hover ou quando fixado)\n * - Drag-reorder (HTML5 nativo, ativado pelo grip — quando `onColumnsReorder` é passado)\n * - Atalhos \"Mostrar todas\" / \"Só fixadas\" no footer\n *\n * Dumb: visible/pinned/order vêm do consumer via props.\n *\n * NOTA: usa HTML5 drag nativo em vez de dnd-kit pra evitar conflito com o\n * `transform` aplicado pelo Radix Popover (Floating UI) — coordenadas do\n * dnd-kit ficam off quando dentro do popover.\n */\nexport function ColsPopover({\n trigger,\n columns,\n visibleCols,\n onVisibleChange,\n pinnedCols,\n onPinnedChange,\n onColumnsReorder,\n title = \"Colunas visíveis\",\n hideShowAll,\n hideOnlyPinned,\n showAllLabel = \"Mostrar todas\",\n onlyPinnedLabel = \"Só fixadas\",\n align = \"end\",\n open,\n onOpenChange,\n className,\n}: ColsPopoverProps) {\n const reorderable = Boolean(onColumnsReorder);\n\n /* ── Drag state ──────────────────────────────────────────────── */\n // `grippedIndex` = row que recebeu mousedown no grip → permite drag dessa row\n const [grippedIndex, setGrippedIndex] = useState<number | null>(null);\n const [dragIndex, setDragIndex] = useState<number | null>(null);\n const [dropIndex, setDropIndex] = useState<number | null>(null);\n\n const toggleVisible = (key: string) => {\n const next = new Set(visibleCols);\n next.has(key) ? next.delete(key) : next.add(key);\n onVisibleChange(next);\n };\n const togglePin = (key: string) => {\n const next = new Set(pinnedCols);\n next.has(key) ? next.delete(key) : next.add(key);\n onPinnedChange(next);\n };\n\n const showAll = () => onVisibleChange(new Set(columns.map((c) => c.key)));\n const onlyPinned = () => onVisibleChange(new Set([...pinnedCols]));\n\n const handleDragStart = (e: React.DragEvent, index: number) => {\n if (grippedIndex !== index) {\n e.preventDefault();\n return;\n }\n setDragIndex(index);\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", String(index));\n };\n\n const handleDragOver = (e: React.DragEvent, index: number) => {\n if (dragIndex === null) return;\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n if (dropIndex !== index) setDropIndex(index);\n };\n\n const handleDrop = (e: React.DragEvent, index: number) => {\n if (dragIndex === null) return;\n e.preventDefault();\n if (dragIndex !== index) {\n const next = [...columns];\n const [moved] = next.splice(dragIndex, 1);\n next.splice(index, 0, moved);\n onColumnsReorder?.(next);\n }\n setDragIndex(null);\n setDropIndex(null);\n setGrippedIndex(null);\n };\n\n const handleDragEnd = () => {\n setDragIndex(null);\n setDropIndex(null);\n setGrippedIndex(null);\n };\n\n return (\n <Popover open={open} onOpenChange={onOpenChange}>\n <PopoverTrigger asChild>{trigger}</PopoverTrigger>\n <PopoverContent\n align={align}\n className={cn(\n \"w-[320px] max-w-[calc(100vw-32px)] max-h-[min(480px,calc(100vh-80px))] p-0 flex flex-col min-h-0 overflow-hidden\",\n className,\n )}\n >\n {/* Header */}\n <div className=\"flex-none px-pad-xl py-pad-2xl border-b border-border-default\">\n <h3 className=\"text-[11px] font-semibold text-fg-muted uppercase tracking-wide leading-none m-0\">\n {title}\n </h3>\n </div>\n\n {/* List */}\n <div\n className={cn(\n \"flex-1 min-h-0 overflow-y-auto p-[6px] flex flex-col gap-[2px]\",\n \"[scrollbar-width:thin] [scrollbar-color:var(--color-border-default)_transparent]\",\n \"[&::-webkit-scrollbar]:w-[6px]\",\n \"[&::-webkit-scrollbar-thumb]:bg-border-default [&::-webkit-scrollbar-thumb]:rounded-full\",\n \"[&::-webkit-scrollbar-track]:bg-transparent\",\n )}\n >\n {columns.map((col, index) => {\n const Icon = col.icon;\n const checked = visibleCols.has(col.key);\n const isPinned = pinnedCols.has(col.key);\n const isDragging = dragIndex === index;\n const isDropTarget =\n dragIndex !== null && dropIndex === index && dragIndex !== index;\n const dropAbove = isDropTarget && dragIndex! > index;\n const dropBelow = isDropTarget && dragIndex! < index;\n\n return (\n <div\n key={col.key}\n draggable={reorderable && grippedIndex === index}\n onDragStart={(e) => handleDragStart(e, index)}\n onDragOver={(e) => handleDragOver(e, index)}\n onDrop={(e) => handleDrop(e, index)}\n onDragEnd={handleDragEnd}\n className={cn(\n \"group/row flex items-center gap-gp-lg px-pad-md py-[4px] rounded-radius-md\",\n \"transition-[opacity,box-shadow] duration-150\",\n \"hover:bg-bg-muted\",\n isDragging && \"opacity-40\",\n dropAbove && \"shadow-[inset_0_2px_0_0_var(--color-border-brand)]\",\n dropBelow && \"shadow-[inset_0_-2px_0_0_var(--color-border-brand)]\",\n )}\n >\n {reorderable && (\n <span\n onMouseDown={() => setGrippedIndex(index)}\n onMouseUp={() => {\n // Se soltou sem iniciar drag, limpa\n if (dragIndex === null) setGrippedIndex(null);\n }}\n className=\"grid place-items-center size-[16px] shrink-0 text-fg-subtle cursor-grab active:cursor-grabbing select-none [&_svg]:size-[14px]\"\n aria-label=\"Arrastar pra reordenar\"\n >\n <GripVertical strokeWidth={1.8} />\n </span>\n )}\n <Checkbox\n id={`col-vis-${col.key}`}\n checked={checked}\n onCheckedChange={() => toggleVisible(col.key)}\n aria-label={\n typeof col.label === \"string\"\n ? `Mostrar ${col.label}`\n : undefined\n }\n />\n {Icon && (\n <Icon className=\"size-[14px] shrink-0 text-fg-muted\" />\n )}\n <label\n htmlFor={`col-vis-${col.key}`}\n className=\"flex-1 text-[13px] font-medium text-fg-default cursor-pointer truncate\"\n >\n {col.label}\n </label>\n <button\n type=\"button\"\n onClick={() => togglePin(col.key)}\n aria-pressed={isPinned}\n aria-label={\n typeof col.label === \"string\"\n ? isPinned\n ? `Desfixar ${col.label}`\n : `Fixar ${col.label}`\n : undefined\n }\n title={isPinned ? \"Desfixar coluna\" : \"Fixar coluna\"}\n className={cn(\n \"grid place-items-center size-[28px] shrink-0\",\n \"rounded-radius-md bg-transparent text-fg-muted\",\n \"transition-[opacity,background-color,color] duration-150\",\n \"outline-none focus-visible:opacity-100 focus-visible:bg-bg-muted\",\n \"hover:bg-bg-muted hover:text-fg-default\",\n \"[&_svg]:size-[14px]\",\n isPinned\n ? \"opacity-100 text-fg-brand bg-bg-brand-subtle hover:bg-bg-brand-subtle-hover hover:text-fg-brand\"\n : \"opacity-0 group-hover/row:opacity-100\",\n )}\n >\n {isPinned ? (\n <Pin strokeWidth={2.2} />\n ) : (\n <PinOff strokeWidth={1.8} />\n )}\n </button>\n </div>\n );\n })}\n </div>\n\n {/* Footer split */}\n {(!hideShowAll || !hideOnlyPinned) && (\n <div className=\"flex-none flex items-center justify-between gap-gp-md px-pad-2xl min-h-[44px] border-t border-border-default\">\n {!hideShowAll ? (\n <button\n type=\"button\"\n onClick={showAll}\n className=\"text-[12px] font-medium text-fg-brand bg-transparent border-0 p-0 cursor-pointer outline-none hover:underline focus-visible:underline underline-offset-2\"\n >\n {showAllLabel}\n </button>\n ) : (\n <span />\n )}\n {!hideOnlyPinned && (\n <button\n type=\"button\"\n onClick={onlyPinned}\n className=\"text-[12px] font-medium text-fg-brand bg-transparent border-0 p-0 cursor-pointer outline-none hover:underline focus-visible:underline underline-offset-2\"\n >\n {onlyPinnedLabel}\n </button>\n )}\n </div>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n","import type { ComponentType, ReactNode } from \"react\";\nimport { ArrowDown, ArrowUp, Plus, X } from \"lucide-react\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../../../shadcn/popover\";\nimport { cn } from \"@/lib/utils\";\nimport type { SortDirection } from \"../table-toolbar.types\";\n\n/* ── Types ────────────────────────────────────────────────────────── */\n// Re-export pra backward-compat (consumers que importavam daqui).\nexport type { SortDirection };\n\nexport type SortPopoverColumn = {\n key: string;\n label: ReactNode;\n /** Ícone do tipo (lucide component) */\n icon?: ComponentType<{ className?: string }>;\n};\n\nexport type SortPopoverCriterion = {\n /** Key da coluna sendo ordenada */\n key: string;\n /** Direção da ordenação */\n dir: SortDirection;\n};\n\nexport type SortPopoverProps = {\n /** Botão que abre o popover */\n trigger: ReactNode;\n\n /** Lista completa de colunas disponíveis pra ordenação */\n columns: SortPopoverColumn[];\n\n /** Array de critérios atuais (na ordem de prioridade) */\n sortBy: SortPopoverCriterion[];\n onSortByChange: (next: SortPopoverCriterion[]) => void;\n\n /** Título da section principal (default \"Ordenação\") */\n title?: ReactNode;\n /** Mensagem quando não há critérios (default \"Sem critérios de ordenação.\") */\n emptyMessage?: ReactNode;\n /** Label da section de adicionar (default \"Adicionar ordenação por\") */\n addSectionLabel?: ReactNode;\n /** Label do link \"Limpar\" no footer (default \"Limpar\") */\n clearLabel?: ReactNode;\n\n /** Alinhamento do popover. Default \"end\" */\n align?: \"start\" | \"center\" | \"end\";\n /** Estado controlado (opcional) */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n\n className?: string;\n};\n\n/**\n * SortPopover — popover de ordenação multi-coluna da tabela.\n *\n * - Lista os critérios atuais (chave + direção asc/desc + prefixo posicional)\n * - Toggle de direção asc ↔ desc por critério\n * - Remove individual via X\n * - Section pra adicionar critérios novos (apenas colunas ainda não usadas)\n * - Footer \"Limpar\" quando há critérios\n *\n * Componente dumb: `sortBy` (array de critérios) vem do consumer.\n * Use `useToolbarSort()` hook se quiser gerenciamento de estado pronto.\n */\nexport function SortPopover({\n trigger,\n columns,\n sortBy,\n onSortByChange,\n title = \"Ordenação\",\n emptyMessage = \"Sem critérios de ordenação.\",\n addSectionLabel = \"Adicionar ordenação por\",\n clearLabel = \"Limpar\",\n align = \"end\",\n open,\n onOpenChange,\n className,\n}: SortPopoverProps) {\n const usedKeys = new Set(sortBy.map((s) => s.key));\n const available = columns.filter((c) => !usedKeys.has(c.key));\n\n const toggleDir = (index: number) => {\n const next = [...sortBy];\n next[index] = {\n ...next[index],\n dir: next[index].dir === \"asc\" ? \"desc\" : \"asc\",\n };\n onSortByChange(next);\n };\n\n const remove = (index: number) =>\n onSortByChange(sortBy.filter((_, i) => i !== index));\n\n const addSort = (key: string) =>\n onSortByChange([...sortBy, { key, dir: \"asc\" }]);\n\n const clearAll = () => onSortByChange([]);\n\n return (\n <Popover open={open} onOpenChange={onOpenChange}>\n <PopoverTrigger asChild>{trigger}</PopoverTrigger>\n <PopoverContent\n align={align}\n className={cn(\n \"w-[300px] max-w-[calc(100vw-32px)] max-h-[min(480px,calc(100vh-80px))] p-0 flex flex-col min-h-0 overflow-hidden\",\n className,\n )}\n >\n {/* Header separado — padrao igual FilterPopover/ColsPopover */}\n <div className=\"flex-none flex items-center justify-between gap-gp-md px-pad-xl py-pad-lg border-b border-border-default\">\n <h3 className=\"text-[11px] font-semibold text-fg-muted uppercase tracking-wide leading-none m-0\">\n {title}\n </h3>\n </div>\n <div\n className={cn(\n \"flex-1 min-h-0 overflow-y-auto\",\n \"[scrollbar-width:thin] [scrollbar-color:var(--color-border-default)_transparent]\",\n \"[&::-webkit-scrollbar]:w-[6px]\",\n \"[&::-webkit-scrollbar-thumb]:bg-border-default [&::-webkit-scrollbar-thumb]:rounded-full\",\n \"[&::-webkit-scrollbar-track]:bg-transparent\",\n )}\n >\n {/* ── Section: Critérios atuais ───────────────────────── */}\n <section className=\"px-pad-xl py-pad-lg border-b border-border-default\">\n {sortBy.length === 0 ? (\n <p className=\"text-[12px] text-fg-muted m-0 py-pad-sm\">\n {emptyMessage}\n </p>\n ) : (\n <div className=\"flex flex-col gap-[2px]\">\n {sortBy.map((s, i) => {\n const col = columns.find((c) => c.key === s.key);\n return (\n <div\n key={s.key}\n className=\"group/row flex items-center gap-gp-md px-pad-md py-[4px] rounded-radius-md hover:bg-bg-muted\"\n >\n <span className=\"text-[11px] text-fg-subtle shrink-0\">\n {i === 0 ? \"Por\" : \"depois por\"}\n </span>\n <span className=\"flex-1 text-[13px] font-medium text-fg-default truncate\">\n {col?.label ?? s.key}\n </span>\n <button\n type=\"button\"\n onClick={() => toggleDir(i)}\n className={cn(\n \"inline-flex items-center gap-gp-xs h-[22px] px-pad-md shrink-0\",\n \"rounded-radius-sm bg-bg-muted text-fg-default text-[11.5px] font-medium\",\n \"outline-none cursor-pointer\",\n \"hover:bg-bg-muted-hover focus-visible:bg-bg-muted-hover\",\n \"[&_svg]:size-[12px]\",\n )}\n aria-label={\n s.dir === \"asc\"\n ? \"Mudar para descendente\"\n : \"Mudar para ascendente\"\n }\n >\n {s.dir === \"asc\" ? <ArrowUp /> : <ArrowDown />}\n {s.dir === \"asc\" ? \"asc\" : \"desc\"}\n </button>\n <button\n type=\"button\"\n onClick={() => remove(i)}\n aria-label=\"Remover critério\"\n className={cn(\n \"grid place-items-center size-[22px] shrink-0\",\n \"rounded-radius-sm bg-transparent text-fg-muted\",\n \"outline-none cursor-pointer\",\n \"transition-[opacity,background-color,color] duration-150\",\n \"opacity-0 group-hover/row:opacity-100\",\n \"hover:bg-bg-muted hover:text-fg-default\",\n \"focus-visible:opacity-100 focus-visible:bg-bg-muted\",\n \"[&_svg]:size-[12px]\",\n )}\n >\n <X strokeWidth={2.2} />\n </button>\n </div>\n );\n })}\n </div>\n )}\n </section>\n\n {/* ── Section: Adicionar ─────────────────────────────── */}\n {available.length > 0 && (\n <section className=\"px-pad-xl py-pad-lg\">\n <h4 className=\"text-[11px] font-semibold text-fg-muted uppercase tracking-wide leading-none m-0 mb-pad-md\">\n {addSectionLabel}\n </h4>\n <div className=\"flex flex-col gap-[2px]\">\n {available.map((col) => {\n const Icon = col.icon;\n return (\n <button\n key={col.key}\n type=\"button\"\n onClick={() => addSort(col.key)}\n className={cn(\n \"group/add flex items-center gap-gp-md w-full\",\n \"px-pad-md py-pad-sm rounded-radius-md\",\n \"bg-transparent border-0 cursor-pointer outline-none text-left\",\n \"hover:bg-bg-muted focus-visible:bg-bg-muted\",\n \"transition-colors duration-150\",\n )}\n >\n {Icon && (\n <Icon className=\"size-[14px] shrink-0 text-fg-muted\" />\n )}\n <span className=\"flex-1 text-[13px] font-medium text-fg-default truncate\">\n {col.label}\n </span>\n <Plus\n className=\"size-[14px] shrink-0 text-fg-muted opacity-50 group-hover/add:opacity-100 group-hover/add:text-fg-brand transition-[opacity,color]\"\n strokeWidth={2}\n />\n </button>\n );\n })}\n </div>\n </section>\n )}\n </div>\n\n {/* ── Footer ────────────────────────────────────────────── */}\n {sortBy.length > 0 && (\n <div className=\"flex-none flex items-center justify-start gap-gp-md px-pad-2xl min-h-[44px] border-t border-border-default\">\n <button\n type=\"button\"\n onClick={clearAll}\n className=\"text-[12px] font-medium text-fg-brand bg-transparent border-0 p-0 cursor-pointer outline-none hover:underline focus-visible:underline underline-offset-2\"\n >\n {clearLabel}\n </button>\n </div>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n","import { useMemo, useState, type ReactNode } from \"react\";\nimport { Plus, Search, Trash2 } from \"lucide-react\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../../../shadcn/popover\";\nimport { cn } from \"@/lib/utils\";\n\n/* ── Types ────────────────────────────────────────────────────────── */\nexport type ViewsPopoverView = {\n id: string;\n name: ReactNode;\n /**\n * Quem é o dono da view. Se igual a `myOwnerKey` (default `\"me\"`), a view\n * é considerada \"minha\" — mostra o botão de delete e cai na tab \"Pessoais\".\n * Caso contrário, é uma view compartilhada (mostra autor).\n */\n owner: string;\n /** Nome do autor exibido quando não é \"minha\" */\n ownerName?: string;\n};\n\nexport type ViewsPopoverProps = {\n /** Botão que abre o popover (geralmente `<ToolbarSaveButton>`) */\n trigger: ReactNode;\n\n /** Lista completa de views disponíveis */\n views: ViewsPopoverView[];\n\n /** ID da view atualmente ativa */\n activeViewId?: string;\n /** Aplicar/selecionar uma view (clique no item) */\n onApply?: (view: ViewsPopoverView) => void;\n /** Excluir uma view \"minha\" */\n onDelete?: (id: string) => void;\n /** Clicar em \"Salvar visão atual\" (footer) */\n onCreate?: () => void;\n\n /**\n * Key que identifica views \"minhas\" (default `\"me\"`).\n * Views com `owner === myOwnerKey` mostram delete e ficam na tab Pessoais.\n */\n myOwnerKey?: string;\n\n /** Esconde as tabs Todos/Pessoais (mostra todas as views direto) */\n hideTabs?: boolean;\n /** Esconde o input de busca */\n hideSearch?: boolean;\n /** Esconde o botão \"Salvar visão atual\" no footer */\n hideCreate?: boolean;\n\n /** Labels customizáveis */\n allTabLabel?: ReactNode;\n myTabLabel?: ReactNode;\n searchPlaceholder?: string;\n createLabel?: ReactNode;\n /** Mensagem de estado vazio (com search ativa) */\n emptySearchMessage?: (query: string) => ReactNode;\n /** Mensagem de estado vazio (sem search) */\n emptyMessage?: ReactNode;\n\n /** Alinhamento do popover. Default \"start\" */\n align?: \"start\" | \"center\" | \"end\";\n /** Estado controlado (opcional) */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n\n className?: string;\n};\n\n/**\n * ViewsPopover — popover de visualizações salvas da tabela.\n *\n * - Tabs `Todos` / `Pessoais` (filtra por `owner === myOwnerKey`)\n * - Search local por nome ou autor\n * - Lista com estado ativo + botão delete em views \"minhas\"\n * - Footer \"Salvar visão atual\" pra criar nova\n *\n * Dumb: `views` + `activeViewId` vêm do consumer. Tabs e search são state interno.\n */\nexport function ViewsPopover({\n trigger,\n views,\n activeViewId,\n onApply,\n onDelete,\n onCreate,\n myOwnerKey = \"me\",\n hideTabs,\n hideSearch,\n hideCreate,\n allTabLabel = \"Todos\",\n myTabLabel = \"Pessoais\",\n searchPlaceholder = \"Buscar\",\n createLabel = \"Salvar visão atual\",\n emptySearchMessage = (q) => `Nenhuma visão pra \"${q}\".`,\n emptyMessage = \"Nenhuma visão disponível.\",\n align = \"start\",\n open,\n onOpenChange,\n className,\n}: ViewsPopoverProps) {\n const [tab, setTab] = useState<\"all\" | \"mine\">(\"all\");\n const [search, setSearch] = useState(\"\");\n\n const filtered = useMemo(() => {\n const baseList = hideTabs\n ? views\n : tab === \"mine\"\n ? views.filter((v) => v.owner === myOwnerKey)\n : views;\n const q = search.trim().toLowerCase();\n if (!q) return baseList;\n return baseList.filter((v) => {\n const name = typeof v.name === \"string\" ? v.name.toLowerCase() : \"\";\n const author = (v.ownerName ?? \"\").toLowerCase();\n return name.includes(q) || author.includes(q);\n });\n }, [views, tab, search, myOwnerKey, hideTabs]);\n\n return (\n <Popover open={open} onOpenChange={onOpenChange}>\n <PopoverTrigger asChild>{trigger}</PopoverTrigger>\n <PopoverContent\n align={align}\n role=\"dialog\"\n aria-label=\"Visualizações\"\n className={cn(\n \"w-[280px] max-w-[calc(100vw-32px)] max-h-[min(480px,calc(100vh-80px))] p-0 flex flex-col min-h-0 overflow-hidden\",\n className,\n )}\n >\n {/* Tabs */}\n {!hideTabs && (\n <div\n role=\"tablist\"\n className=\"flex-none flex items-center gap-[2px] p-[3px] m-pad-md mb-0 bg-bg-muted rounded-radius-md\"\n >\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={tab === \"all\"}\n onClick={() => setTab(\"all\")}\n className={cn(\n \"flex-1 h-form-sm px-pad-lg rounded-radius-sm\",\n \"text-[12px] font-medium cursor-pointer outline-none\",\n \"transition-[background-color,color,box-shadow] duration-150\",\n tab === \"all\"\n ? \"bg-bg-accent text-fg-default font-semibold shadow-sh-sm\"\n : \"bg-transparent text-fg-muted hover:text-fg-default\",\n )}\n >\n {allTabLabel}\n </button>\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={tab === \"mine\"}\n onClick={() => setTab(\"mine\")}\n className={cn(\n \"flex-1 h-form-sm px-pad-lg rounded-radius-sm\",\n \"text-[12px] font-medium cursor-pointer outline-none\",\n \"transition-[background-color,color,box-shadow] duration-150\",\n tab === \"mine\"\n ? \"bg-bg-accent text-fg-default font-semibold shadow-sh-sm\"\n : \"bg-transparent text-fg-muted hover:text-fg-default\",\n )}\n >\n {myTabLabel}\n </button>\n </div>\n )}\n\n {/* Search */}\n {!hideSearch && (\n <label className=\"flex-none flex items-center gap-gp-md mx-pad-md mt-pad-md h-form-md px-pad-xl rounded-radius-lg bg-bg-input dark:bg-bg-muted border border-border-input shadow-sh-sm dark:shadow-sh-none cursor-text focus-within:border-border-brand focus-within:shadow-sh-ring transition-[border-color,box-shadow] duration-150\">\n <Search\n strokeWidth={1.8}\n aria-hidden=\"true\"\n className=\"size-[14px] text-fg-muted shrink-0\"\n />\n <input\n type=\"text\"\n placeholder={searchPlaceholder}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n autoFocus\n className=\"flex-1 min-w-0 bg-transparent border-0 outline-none text-[13px] text-fg-default placeholder:text-fg-muted\"\n />\n </label>\n )}\n\n {/* List */}\n <div\n role=\"list\"\n className={cn(\n \"flex-1 min-h-0 overflow-y-auto p-pad-md flex flex-col gap-[2px]\",\n \"[scrollbar-width:thin] [scrollbar-color:var(--color-border-default)_transparent]\",\n \"[&::-webkit-scrollbar]:w-[6px]\",\n \"[&::-webkit-scrollbar-thumb]:bg-border-default [&::-webkit-scrollbar-thumb]:rounded-full\",\n \"[&::-webkit-scrollbar-track]:bg-transparent\",\n )}\n >\n {filtered.length === 0 ? (\n <p className=\"text-[12px] text-fg-muted m-0 px-pad-md py-pad-2xl text-center\">\n {search.trim() ? emptySearchMessage(search.trim()) : emptyMessage}\n </p>\n ) : (\n filtered.map((view) => {\n const isActive = view.id === activeViewId;\n const isMine = view.owner === myOwnerKey;\n return (\n <div\n key={view.id}\n role=\"listitem\"\n className={cn(\n \"group/view flex items-stretch gap-[2px] rounded-radius-md\",\n isActive && \"bg-bg-brand-subtle\",\n )}\n >\n <button\n type=\"button\"\n onClick={() => onApply?.(view)}\n className={cn(\n \"flex-1 flex items-center gap-gp-md min-w-0\",\n \"px-pad-md py-pad-sm rounded-radius-md\",\n \"bg-transparent border-0 cursor-pointer outline-none text-left\",\n \"transition-[background-color,color] duration-150\",\n isActive\n ? \"text-fg-brand hover:bg-bg-brand-subtle-hover\"\n : \"text-fg-default hover:bg-bg-muted focus-visible:bg-bg-muted\",\n )}\n >\n <span\n className={cn(\n \"flex-1 text-[13px] truncate\",\n isActive ? \"font-semibold\" : \"font-medium\",\n )}\n >\n {view.name}\n </span>\n {!isMine && view.ownerName && (\n <span className=\"text-[11px] text-fg-muted shrink-0\">\n por {view.ownerName}\n </span>\n )}\n </button>\n {isMine && onDelete && (\n <button\n type=\"button\"\n onClick={() => onDelete(view.id)}\n aria-label={\n typeof view.name === \"string\"\n ? `Excluir ${view.name}`\n : \"Excluir\"\n }\n title=\"Excluir\"\n className={cn(\n \"grid place-items-center size-[28px] shrink-0 self-center\",\n \"mr-pad-sm\", // respiro da borda direita (= sandbox)\n \"rounded-radius-md bg-transparent text-fg-muted\",\n \"outline-none cursor-pointer\",\n \"transition-[opacity,background-color,color] duration-150\",\n \"opacity-0 group-hover/view:opacity-100\",\n \"hover:bg-bg-danger-muted hover:text-fg-danger\",\n \"focus-visible:opacity-100 focus-visible:bg-bg-muted\",\n \"[&_svg]:size-[14px]\",\n )}\n >\n <Trash2 strokeWidth={1.8} />\n </button>\n )}\n </div>\n );\n })\n )}\n </div>\n\n {/* Footer \"Salvar visão atual\" */}\n {!hideCreate && onCreate && (\n <div className=\"flex-none p-pad-md border-t border-border-default\">\n <button\n type=\"button\"\n onClick={onCreate}\n className={cn(\n \"flex items-center justify-center gap-gp-sm w-full\",\n \"h-form-md px-pad-xl rounded-radius-lg\",\n \"bg-bg-surface dark:bg-bg-muted\",\n \"border border-border-subtle dark:border-border-input\",\n \"shadow-sh-sm dark:shadow-sh-none\",\n \"text-[13px] font-semibold text-fg-default dark:text-fg-muted\",\n \"outline-none cursor-pointer\",\n \"transition-[background-color,color,box-shadow] duration-150\",\n \"hover:bg-bg-muted-hover hover:text-fg-default\",\n \"focus-visible:shadow-sh-ring\",\n \"[&_svg]:size-[14px]\",\n )}\n >\n <Plus strokeWidth={2.2} />\n {createLabel}\n </button>\n </div>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n","import * as React from \"react\"\nimport * as SwitchPrimitives from \"@radix-ui/react-switch\"\n\nimport { cn } from \"@/lib/utils\"\n\n/**\n * Switch — alinhado com `.tbl-toggle` do design-and-table-v2.\n *\n * Specs:\n * - Track: 42x24, radius-full\n * - off light: bg-emphasis (gray[100] — visível em fundo branco)\n * - off dark: bg-accent (alpha branco 12% — visível em fundo escuro)\n * - on: bg-brand\n * - Thumb: 20x20, white com shadow, transform 0.18s\n * - Focus: shadow-sh-ring (brand glow)\n */\nconst Switch = React.forwardRef<\n React.ElementRef<typeof SwitchPrimitives.Root>,\n React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>\n>(({ className, ...props }, ref) => (\n <SwitchPrimitives.Root\n className={cn(\n \"peer relative inline-flex h-[24px] w-[42px] shrink-0 cursor-pointer items-center\",\n \"rounded-radius-full\",\n \"transition-[background-color,box-shadow] duration-150 outline-none\",\n \"data-[state=unchecked]:bg-bg-emphasis dark:data-[state=unchecked]:bg-bg-accent\",\n \"data-[state=checked]:bg-bg-brand\",\n \"focus-visible:shadow-sh-ring\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n ref={ref}\n >\n <SwitchPrimitives.Thumb\n className={cn(\n \"pointer-events-none block size-[20px] rounded-radius-full bg-white\",\n \"shadow-[0_1px_2px_rgba(0,0,0,0.10)]\",\n \"transition-transform duration-[180ms] ease-[cubic-bezier(0.4,0,0.2,1)]\",\n \"data-[state=unchecked]:translate-x-[2px]\",\n \"data-[state=checked]:translate-x-[20px]\"\n )}\n />\n </SwitchPrimitives.Root>\n))\nSwitch.displayName = SwitchPrimitives.Root.displayName\n\nexport { Switch }\n","import { tv } from \"@/utils/tv\";\n\n/**\n * Form field styles — alinhado com `.tbl-form-field` do sandbox.\n *\n * Spec: flex column gap 7px (label / field / message).\n */\nexport const formFieldRoot = tv({\n base: \"flex flex-col gap-[7px] w-full\",\n});\n\nexport const formFieldLabel = tv({\n base: [\n \"text-[12.5px] font-semibold tracking-[0.01em] leading-none\",\n \"text-fg-default dark:text-fg-muted\",\n \"select-none\",\n ],\n variants: {\n disabled: {\n true: \"opacity-50 cursor-not-allowed\",\n },\n },\n});\n\nexport const formFieldRequired = tv({\n base: \"ml-[2px] text-fg-danger\",\n});\n\nexport const formFieldMessage = tv({\n base: \"text-[11.5px] leading-snug\",\n variants: {\n state: {\n default: \"text-fg-muted\",\n error: \"text-fg-danger\",\n warning: \"text-fg-warning\",\n success: \"text-fg-success\",\n },\n },\n defaultVariants: { state: \"default\" },\n});\n","import { useId } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport {\n formFieldRoot,\n formFieldLabel,\n formFieldRequired,\n formFieldMessage,\n} from \"./form-field.styles\";\nimport type { FormFieldBaseProps, FieldState } from \"./form-field.types\";\n\nexport type FormFieldProps = FormFieldBaseProps & {\n /** O field em si (Input, Select, Textarea, Checkbox, Switch, etc) — recebe id automático */\n children: (ctx: { id: string; state: FieldState }) => ReactNode;\n /** Hide quando o field é \"self-contained\" (ex: Checkbox com label inline) */\n hideLabel?: boolean;\n /** Marcar field como disabled (afeta cor do label) */\n disabled?: boolean;\n};\n\n/**\n * FormField — base wrapper compartilhado por FormFieldInput, FormFieldSelect, etc.\n *\n * Estrutura:\n * [Label + required asterisk] (top)\n * [Field (passado via children render-prop)]\n * [Helper text OR error/warning/success message] (bottom)\n *\n * Mensagem é decidida pela prioridade: error → warning → success → helperText.\n * O `id` gerado é passado ao child via render-prop pra linkar `htmlFor` no label.\n */\nexport function FormField({\n label,\n required,\n helperText,\n state = \"default\",\n errorMessage,\n warningMessage,\n successMessage,\n className,\n id: idProp,\n children,\n hideLabel,\n disabled,\n}: FormFieldProps) {\n const autoId = useId();\n const id = idProp ?? autoId;\n\n // Priority: error → warning → success → helper\n let message: ReactNode = helperText;\n let messageState: FieldState = \"default\";\n if (state === \"error\" && errorMessage) {\n message = errorMessage;\n messageState = \"error\";\n } else if (state === \"warning\" && warningMessage) {\n message = warningMessage;\n messageState = \"warning\";\n } else if (state === \"success\" && successMessage) {\n message = successMessage;\n messageState = \"success\";\n }\n\n return (\n <div className={cn(formFieldRoot(), className)}>\n {label && !hideLabel && (\n <label\n htmlFor={id}\n className={formFieldLabel({ disabled })}\n >\n {label}\n {required && <span className={formFieldRequired()} aria-hidden=\"true\">*</span>}\n </label>\n )}\n {children({ id, state })}\n {message && (\n <p\n className={formFieldMessage({ state: messageState })}\n role={messageState === \"error\" ? \"alert\" : undefined}\n >\n {message}\n </p>\n )}\n </div>\n );\n}\n","import { forwardRef, type ReactNode } from \"react\";\nimport { Input, type InputProps } from \"../../shadcn/input\";\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n InputGroupText,\n} from \"../../shadcn/input-group\";\nimport { FormField } from \"./form-field\";\nimport type { FormFieldBaseProps } from \"./form-field.types\";\n\n/**\n * FormFieldInput — wrapper \"one-shot\" pra um campo de texto.\n *\n * Renderização condicional:\n * - sem addon → renderiza <Input> puro\n * - com `startAddon` ou `endAddon` → renderiza <InputGroup> com InputGroupInput\n *\n * Os addons aceitam string (renderiza como InputGroupText, ex \"R$\") ou ReactNode\n * (ícone, botão — passa direto). Não há mais startIcon vs startAdornment: o\n * InputGroup trata ambos via composição.\n */\nexport type FormFieldInputProps = FormFieldBaseProps &\n Omit<InputProps, \"state\" | \"id\"> & {\n /** Conteúdo à esquerda. String vira `<InputGroupText>`, ReactNode (ícone/botão) passa direto. */\n startAddon?: ReactNode;\n /** Conteúdo à direita. Mesma regra do startAddon. */\n endAddon?: ReactNode;\n };\n\nfunction renderAddon(content: ReactNode, key: string): ReactNode {\n if (typeof content === \"string\") {\n return (\n <InputGroupAddon key={key} align={key === \"start\" ? \"inline-start\" : \"inline-end\"}>\n <InputGroupText>{content}</InputGroupText>\n </InputGroupAddon>\n );\n }\n return (\n <InputGroupAddon key={key} align={key === \"start\" ? \"inline-start\" : \"inline-end\"}>\n {content}\n </InputGroupAddon>\n );\n}\n\nexport const FormFieldInput = forwardRef<HTMLInputElement, FormFieldInputProps>(\n (\n {\n label,\n required,\n helperText,\n state,\n errorMessage,\n warningMessage,\n successMessage,\n className,\n id,\n startAddon,\n endAddon,\n ...inputProps\n },\n ref,\n ) => {\n const hasAddon = startAddon !== undefined || endAddon !== undefined;\n // Separa o `size` do CVA pra usar no wrapper — InputGroupInput recebe os\n // demais HTML attrs (sem o size, que no <input> nativo seria number).\n const { size, ...inputHtmlProps } = inputProps;\n\n return (\n <FormField\n label={label}\n required={required}\n helperText={helperText}\n state={state}\n errorMessage={errorMessage}\n warningMessage={warningMessage}\n successMessage={successMessage}\n className={className}\n id={id}\n disabled={inputProps.disabled}\n >\n {({ id: fieldId, state: fieldState }) =>\n hasAddon ? (\n <InputGroup state={fieldState} size={size ?? undefined}>\n {startAddon !== undefined && renderAddon(startAddon, \"start\")}\n <InputGroupInput ref={ref} id={fieldId} {...inputHtmlProps} />\n {endAddon !== undefined && renderAddon(endAddon, \"end\")}\n </InputGroup>\n ) : (\n <Input\n ref={ref}\n id={fieldId}\n state={fieldState}\n size={size}\n {...inputHtmlProps}\n />\n )\n }\n </FormField>\n );\n },\n);\nFormFieldInput.displayName = \"FormFieldInput\";\n","import { tv } from \"@/utils/tv\";\n\n/**\n * Slots tv() pro AddViewModal — replica literal do modal do sandbox\n * /design-and-table-v2 (TblViewsModal).\n *\n * Valores fora da escala DS (14px gap, 18px gap, 22px py, 13.5/17px font,\n * 3px gap) usados como arbitrary — calibração visual exata do sandbox.\n * Quando o token semantico existe na medida certa (form-lg, form-md,\n * radius-lg, pad-4xl=24, etc), usar o token.\n */\n\nexport const dialog = tv({\n base: [\n // Override do DialogContent default (grid + p-pad-4xl + rounded-radius-base + shadow-sh-xl)\n \"!gap-0 !p-0\",\n \"!max-w-[540px] w-[calc(100%-32px)]\",\n \"border border-border-default\", // sandbox tem border 1px solid — DialogContent default não traz\n \"!rounded-radius-2xl !shadow-sh-2xl\", // radius-2xl=18px (sandbox quer 16, mantemos token DS)\n \"outline-float\", // halo 6px alpha em volta — match sandbox\n \"flex flex-col overflow-hidden\",\n ],\n});\n\n/**\n * Close button manual — substitui o padrão do DialogContent (que usa\n * opacity-70 + cor herdada). Sandbox: 28×28, text-fg-muted, opacity 0.55 →\n * 1 no hover + bg-muted no hover.\n */\nexport const closeBtn = tv({\n base: [\n \"absolute top-[14px] right-[14px] z-[1]\",\n \"grid place-items-center size-[28px]\",\n \"rounded-radius-md bg-transparent border-0 cursor-pointer\",\n \"text-fg-muted opacity-55\",\n \"transition-[background-color,color,opacity] duration-150\",\n \"hover:bg-bg-muted hover:text-fg-default hover:opacity-100\",\n \"focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-ring-brand\",\n \"dark:hover:bg-bg-muted-hover\",\n ],\n});\n\nexport const head = tv({\n base: [\n \"flex items-center gap-[14px]\", // sandbox 14px (não tem na escala)\n \"px-pad-4xl pt-pad-4xl pb-pad-3xl\", // 24/24/20 — sandbox literal\n \"border-b border-border-default\",\n ],\n});\n\nexport const headIcon = tv({\n base: [\n \"shrink-0 grid place-items-center size-form-lg\", // 40×40 — sandbox\n \"bg-bg-muted border border-border-input rounded-radius-lg\",\n \"text-fg-default\",\n \"dark:bg-bg-accent dark:border-border-subtle\",\n ],\n});\n\nexport const headTitleWrap = tv({\n base: [\n \"flex-1 min-w-0\",\n // Reserva espaço pro X close do DialogContent (absolute right-4 / size ~24px)\n // — evita sobreposição quando o título quebra ou é longo (mobile estreito).\n \"pr-pad-3xl\",\n ],\n});\n\nexport const title = tv({\n base: [\n \"m-0 mb-[2px]\",\n // leading-[1.3] balanceia o bloco verticalmente com o icon container 40px\n // (leading-none deixava o glyph colado no top → parecia subido).\n \"text-[17px] font-bold leading-[1.3]\",\n \"text-fg-default\",\n \"tracking-[-0.01em]\",\n ],\n});\n\nexport const sub = tv({\n base: \"m-0 text-[12.5px] text-fg-muted leading-[1.45]\",\n});\n\nexport const body = tv({\n base: \"flex flex-col gap-[18px] px-pad-4xl py-[22px]\",\n});\n\nexport const toggleRow = tv({\n base: [\n \"flex items-center gap-gp-xl\", // 12px — sandbox\n \"px-pad-2xl py-[14px]\", // 16 / 14 — sandbox\n \"bg-bg-muted border border-border-default rounded-radius-xl\", // radius-xl=14px (sandbox quer 12, mantemos token DS)\n \"cursor-pointer transition-[background-color,border-color] duration-200\",\n ],\n variants: {\n on: {\n true: \"bg-bg-brand-subtle border-border-brand\",\n },\n },\n});\n\nexport const toggleIcon = tv({\n base: [\n \"shrink-0 grid place-items-center size-form-md rounded-radius-lg\", // 36×36 / radius-lg=10px\n \"bg-bg-surface border border-border-subtle text-fg-default\",\n \"dark:bg-bg-accent dark:border-border-input dark:text-fg-muted\",\n \"transition-[background-color,border-color,color] duration-200\",\n ],\n variants: {\n on: {\n true: \"!bg-bg-surface !border-border-brand !text-fg-brand\",\n },\n },\n});\n\nexport const toggleText = tv({\n base: \"flex-1 min-w-0 flex flex-col gap-[3px]\",\n});\n\nexport const toggleLabel = tv({\n base: \"text-[13.5px] font-semibold text-fg-default leading-[1.3]\",\n});\n\nexport const toggleDesc = tv({\n base: \"text-[12px] text-fg-muted leading-[1.45]\",\n});\n\nexport const foot = tv({\n base: [\n \"flex items-center justify-end gap-gp-lg\", // 10px — sandbox\n \"px-pad-4xl pt-pad-md pb-[22px]\", // 24 / 8 / 22 — sandbox literal\n ],\n});\n","import { useEffect, useState } from \"react\";\nimport { Eye, Users, X } from \"lucide-react\";\nimport { Dialog, DialogContent, DialogClose } from \"../../../shadcn/dialog\";\nimport { Switch } from \"../../../shadcn/switch\";\nimport { Button } from \"../../Button/button\";\nimport { FormFieldInput } from \"../../FormField/form-field-input\";\nimport {\n dialog,\n closeBtn,\n head,\n headIcon,\n headTitleWrap,\n title,\n sub,\n body,\n toggleRow,\n toggleIcon,\n toggleText,\n toggleLabel,\n toggleDesc,\n foot,\n} from \"./add-view-modal.styles\";\n\nexport type AddViewModalSubmit = {\n name: string;\n isPublic: boolean;\n};\n\nexport type AddViewModalProps = {\n /** Controlled open. */\n open: boolean;\n /** Callback de fechamento (X, ESC, overlay click, ou apos submit). */\n onClose: () => void;\n /** Disparado quando user clica em Salvar Visao com nome valido. */\n onSubmit?: (data: AddViewModalSubmit) => void | Promise<void>;\n};\n\n/**\n * Modal \"Adicionar nova visao\" — replica do sandbox /design-and-table-v2.\n * Header: icon container (Eye) + titulo + sub + X custom no canto direito.\n * Body: campo \"Nome da visao\" + toggle card \"Tornar publica\".\n * Footer: Fechar (outline secondary) + Salvar Visao (primary, disabled se nome vazio).\n *\n * Reseta state ao fechar. Card toggle inteiro eh <label> — click em qualquer\n * area liga o Switch. Enter no input dispara submit.\n */\nexport function AddViewModal({ open, onClose, onSubmit }: AddViewModalProps) {\n const [name, setName] = useState(\"\");\n const [isPublic, setIsPublic] = useState(false);\n\n useEffect(() => {\n if (!open) {\n setName(\"\");\n setIsPublic(false);\n }\n }, [open]);\n\n const handleSave = async () => {\n const trimmed = name.trim();\n if (!trimmed) return;\n await onSubmit?.({ name: trimmed, isPublic });\n onClose();\n };\n\n return (\n <Dialog open={open} onOpenChange={(o) => !o && onClose()}>\n <DialogContent\n className={dialog()}\n hideClose\n aria-labelledby=\"add-view-modal-title\"\n aria-describedby=\"add-view-modal-sub\"\n >\n <DialogClose className={closeBtn()} aria-label=\"Fechar\">\n <X className=\"size-icon-sm\" />\n </DialogClose>\n\n <header className={head()}>\n <span className={headIcon()} aria-hidden=\"true\">\n <Eye className=\"size-icon-md\" strokeWidth={1.7} />\n </span>\n <div className={headTitleWrap()}>\n <h3 id=\"add-view-modal-title\" className={title()}>\n Adicionar nova visão\n </h3>\n <p id=\"add-view-modal-sub\" className={sub()}>\n Salve sua configuração atual de filtros e colunas\n </p>\n </div>\n </header>\n\n <div className={body()}>\n <FormFieldInput\n label=\"Nome da visão\"\n placeholder=\"Ex: Royals em atendimento\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n handleSave();\n }\n }}\n autoFocus\n />\n\n <label className={toggleRow({ on: isPublic })}>\n <span className={toggleIcon({ on: isPublic })} aria-hidden=\"true\">\n <Users className=\"size-icon-sm\" />\n </span>\n <span className={toggleText()}>\n <span className={toggleLabel()}>Tornar esta visão pública</span>\n <span className={toggleDesc()}>\n Outros usuários da sua equipe poderão visualizar e usar esta visão\n </span>\n </span>\n <Switch checked={isPublic} onCheckedChange={setIsPublic} />\n </label>\n </div>\n\n <footer className={foot()}>\n <Button\n color=\"secondary\"\n variant=\"outline\"\n size=\"md\"\n onClick={onClose}\n >\n Fechar\n </Button>\n <Button\n color=\"primary\"\n variant=\"filled\"\n size=\"md\"\n onClick={handleSave}\n disabled={!name.trim()}\n >\n Salvar Visão\n </Button>\n </footer>\n </DialogContent>\n </Dialog>\n );\n}\n","import { useEffect, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport { Plus } from \"lucide-react\";\nimport { ToolbarDivider } from \"./toolbar-divider\";\nimport { ToolbarTabs } from \"./toolbar-tabs\";\nimport { ToolbarSaveButton } from \"./toolbar-tool-button\";\nimport { ViewsPopover, type ViewsPopoverView } from \"../popovers/views-popover\";\nimport {\n AddViewModal,\n type AddViewModalSubmit,\n} from \"../popovers/add-view-modal\";\nimport { AlertModal } from \"../../AlertModal\";\n\n/** ID fixo da tab \"Default\" — virtual (nao tem entrada no storage). */\nexport const DEFAULT_VIEW_ID = \"__default__\";\n\nexport type TableToolbarViewsItem = ViewsPopoverView;\n\nexport type TableToolbarViewsProps = {\n /** Lista completa de views salvas (sem Default — esse e injetado internamente). */\n views: TableToolbarViewsItem[];\n /** ID da view atualmente aplicada. `null`/`undefined` ⇒ tab Default ativa. */\n activeViewId?: string | null;\n /** Aplicar uma view (click numa tab OU click num item do popover). */\n onApply: (id: string) => void;\n /** Resetar pra \"Default\" (limpar filtros, sort, cols, density). */\n onApplyDefault: () => void;\n /**\n * Excluir PERMANENTEMENTE uma view do storage. So eh chamado apos\n * confirmacao via AlertModal danger — disparado pelo lixinho no popover.\n *\n * X em tab NAO chama isso (apenas remove da barra — view continua salva).\n */\n onDelete: (id: string) => void | Promise<void>;\n /** Disparado quando user salva uma nova view via modal. */\n onSave: (data: AddViewModalSubmit) => void | Promise<void>;\n /** Quantas tabs ficam visiveis (incluindo Default). Default 3 — Default + ate 2 views customizadas. */\n maxTabs?: number;\n /** Key que identifica views \"minhas\" (default `\"me\"`). Controla X em tab e delete no popover. */\n myOwnerKey?: string;\n /** Slot opcional pra divider antes das tabs (default renderiza um ToolbarDivider). */\n divider?: ReactNode;\n /** Esconde o divider default — usado quando ja ha um divider adjacente. */\n hideDivider?: boolean;\n};\n\n/**\n * TableToolbarViews — **compound component** (smart) de Saved Views.\n *\n * ⚠️ **Pattern compound smart** — este é um dos POUCOS componentes do TableToolbar\n * que mantém estado interno (`tabViewIds`, `addModalOpen`, `confirmDeleteView`).\n * É uma exceção consciente ao princípio dumb do toolbar: orquestra 4 filhos\n * (ToolbarTabs + ViewsPopover + AddViewModal + AlertModal) como \"bloco pronto\".\n *\n * **Quando usar este compound**: caso de uso saved views completo (CRM admin).\n * **Quando NÃO usar**: se precisar reordenar/customizar a interação entre os\n * 4 filhos, COMPONHA OS PARTS DIRETAMENTE — ToolbarTabs + ViewsPopover +\n * AddViewModal + AlertModal são exportados standalone pelo TableToolbar. Você\n * controla os 4 states (open, deleting, etc) e a ordem visual.\n *\n * Renderiza no slot esquerdo do TableToolbar:\n * 1. ToolbarDivider\n * 2. ToolbarTabs com \"Default\" + ate (maxTabs - 1) views como tabs\n * - Default sem X (custom: false)\n * - Views minhas com X — X apenas remove da barra (view continua salva)\n * 3. ViewsPopover via ToolbarSaveButton \"+\"\n * - Click no item: pina como tab + aplica + fecha popover\n * - Lixinho no item: abre AlertModal danger pra exclusao definitiva\n * - Footer \"Salvar visao atual\": abre AddViewModal mode create\n * 4. AddViewModal (estado interno) — disparado pelo footer do popover\n * 5. AlertModal danger (estado interno) — confirma exclusao definitiva\n *\n * Distinção crítica:\n * - X em tab → unpin (cosmetico, view fica no popover/storage)\n * - Lixinho no popover → confirm + delete permanente (chama onDelete)\n *\n * Comportamento de pin (push-out):\n * - `tabViewIds` eh um state local com as view IDs que ocupam slots de tab.\n * - Inicializa com as (maxTabs - 1) primeiras views.\n * - Click numa view que NAO esta como tab: pina (push out da ultima se cheio).\n * - X em tab: remove o ID daqui (sem promover proxima).\n * - View deletada permanente: remove o ID daqui (se estiver).\n * - View nova criada: anexa se ha slot livre.\n * - Re-mount (reload) reseta — pega as N-1 primeiras de novo.\n */\nexport function TableToolbarViews({\n views,\n activeViewId,\n onApply,\n onApplyDefault,\n onDelete,\n onSave,\n maxTabs = 3,\n myOwnerKey = \"me\",\n divider,\n hideDivider,\n}: TableToolbarViewsProps) {\n const maxCustomTabs = Math.max(0, maxTabs - 1);\n\n /* ── State: tabs pinadas (IDs) ─────────────────────────────────── */\n\n const initialIds = useMemo(\n () => views.slice(0, maxCustomTabs).map((v) => v.id),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n );\n const [tabViewIds, setTabViewIds] = useState<string[]>(initialIds);\n\n // Sync: quando uma view some, tira do state; quando nova chega, anexa se tem slot\n const prevIdsRef = useRef<string[]>(views.map((v) => v.id));\n useEffect(() => {\n const currentIds = views.map((v) => v.id);\n const removedIds = prevIdsRef.current.filter((id) => !currentIds.includes(id));\n const addedIds = currentIds.filter((id) => !prevIdsRef.current.includes(id));\n prevIdsRef.current = currentIds;\n\n if (removedIds.length === 0 && addedIds.length === 0) return;\n\n setTabViewIds((prev) => {\n let next = prev.filter((id) => !removedIds.includes(id));\n for (const id of addedIds) {\n if (next.length >= maxCustomTabs) break;\n next = [...next, id];\n }\n return next;\n });\n }, [views, maxCustomTabs]);\n\n /* ── State: modal create + popover open + confirm delete ──────── */\n\n const [addModalOpen, setAddModalOpen] = useState(false);\n const [popoverOpen, setPopoverOpen] = useState(false);\n const [confirmDeleteView, setConfirmDeleteView] =\n useState<TableToolbarViewsItem | null>(null);\n\n /* ── Tabs effective: Default + views pinadas ────────────────────── */\n\n const tabs = useMemo(() => {\n const customTabs = tabViewIds\n .map((id) => views.find((v) => v.id === id))\n .filter((v): v is TableToolbarViewsItem => !!v)\n .map((v) => ({\n id: v.id,\n name: typeof v.name === \"string\" ? v.name : String(v.name),\n custom: v.owner === myOwnerKey,\n }));\n return [{ id: DEFAULT_VIEW_ID, name: \"Default\", custom: false }, ...customTabs];\n }, [tabViewIds, views, myOwnerKey]);\n\n const effectiveActiveId = activeViewId ?? DEFAULT_VIEW_ID;\n\n /* ── Handlers ──────────────────────────────────────────────────── */\n\n const handleTabSelect = (id: string) => {\n if (id === DEFAULT_VIEW_ID) {\n onApplyDefault();\n } else {\n onApply(id);\n }\n };\n\n /** X em tab — APENAS remove da barra de tabs. Nao deleta a view. */\n const handleTabUnpin = (id: string) => {\n setTabViewIds((prev) => prev.filter((x) => x !== id));\n if (id === activeViewId) onApplyDefault();\n };\n\n /**\n * Click no item da lista do popover: pina como tab (push-out da ultima\n * se ja estiver cheio) + aplica como ativa + fecha popover.\n */\n const handlePopoverItemClick = (v: ViewsPopoverView) => {\n setTabViewIds((prev) => {\n if (prev.includes(v.id)) return prev;\n const next = [...prev, v.id];\n if (next.length > maxCustomTabs) next.shift();\n return next;\n });\n onApply(v.id);\n setPopoverOpen(false);\n };\n\n const handleCreateClick = () => {\n setPopoverOpen(false);\n setTimeout(() => setAddModalOpen(true), 0);\n };\n\n /** Lixinho na lista do popover — pede confirmacao. */\n const handleAskDelete = (id: string) => {\n const view = views.find((v) => v.id === id);\n if (!view) return;\n setConfirmDeleteView(view);\n };\n\n const handleConfirmDelete = async () => {\n if (!confirmDeleteView) return;\n await onDelete(confirmDeleteView.id);\n setConfirmDeleteView(null);\n };\n\n return (\n <>\n {hideDivider ? null : divider ?? <ToolbarDivider />}\n\n <ToolbarTabs\n tabs={tabs}\n activeId={effectiveActiveId}\n onSelect={handleTabSelect}\n onClose={handleTabUnpin}\n ariaLabel=\"Visões salvas\"\n />\n\n <ViewsPopover\n open={popoverOpen}\n onOpenChange={setPopoverOpen}\n trigger={\n <ToolbarSaveButton aria-label=\"Visões salvas\">\n <Plus strokeWidth={2.4} />\n </ToolbarSaveButton>\n }\n views={views}\n activeViewId={activeViewId ?? undefined}\n myOwnerKey={myOwnerKey}\n onApply={handlePopoverItemClick}\n onDelete={handleAskDelete}\n onCreate={handleCreateClick}\n />\n\n <AddViewModal\n open={addModalOpen}\n onClose={() => setAddModalOpen(false)}\n onSubmit={onSave}\n />\n\n <AlertModal\n tone=\"danger\"\n open={!!confirmDeleteView}\n onOpenChange={(o) => !o && setConfirmDeleteView(null)}\n title=\"Excluir visão\"\n description={\n confirmDeleteView\n ? `Tem certeza que deseja excluir a visão \"${typeof confirmDeleteView.name === \"string\" ? confirmDeleteView.name : String(confirmDeleteView.name)}\"? Esta ação não pode ser desfeita.`\n : \"\"\n }\n confirmLabel=\"Excluir\"\n cancelLabel=\"Cancelar\"\n onConfirm={handleConfirmDelete}\n />\n </>\n );\n}\n","/**\n * Parser SQL-like simples — converte texto livre em FilterPopoverEntry[].\n *\n * Subset suportado:\n * `field operator value`\n * `field operator \"quoted value\"`\n * `field1 = X AND field2 > Y`\n * `field1 = X OR field2 = Y`\n *\n * Operadores: `=` `!=` `<>` `>` `<` `>=` `<=` `contains` `like`\n * Logical: AND, OR (case-insensitive). Sem parenteses, sem nested.\n *\n * Output: { entries, logicOperator } ou { error: string }.\n *\n * Mapeamento de operadores texto → FilterPopoverEntry.op:\n * = | == → \"eq\"\n * != | <> → \"neq\"\n * contains → \"contains\"\n * like → \"contains\"\n * > → \"gt\"\n * < → \"lt\"\n * >= → \"gte\"\n * <= → \"lte\"\n */\n\nexport type ParsedFilterEntry = {\n field: string;\n op: \"eq\" | \"neq\" | \"contains\" | \"gt\" | \"lt\" | \"gte\" | \"lte\";\n value: string;\n};\n\nexport type ParseResult =\n | { ok: true; entries: ParsedFilterEntry[]; logicOperator: \"AND\" | \"OR\" }\n | { ok: false; error: string };\n\nconst OP_MAP: Record<string, ParsedFilterEntry[\"op\"]> = {\n \"=\": \"eq\",\n \"==\": \"eq\",\n \"!=\": \"neq\",\n \"<>\": \"neq\",\n \">\": \"gt\",\n \"<\": \"lt\",\n \">=\": \"gte\",\n \"<=\": \"lte\",\n contains: \"contains\",\n like: \"contains\",\n};\n\nconst OP_REGEX = /(>=|<=|!=|<>|==|=|>|<|\\bcontains\\b|\\blike\\b)/i;\n\nfunction unquote(s: string): string {\n const t = s.trim();\n if ((t.startsWith('\"') && t.endsWith('\"')) || (t.startsWith(\"'\") && t.endsWith(\"'\"))) {\n return t.slice(1, -1);\n }\n return t;\n}\n\nexport function parseSqlFilter(input: string): ParseResult {\n const trimmed = input.trim();\n if (!trimmed) return { ok: true, entries: [], logicOperator: \"AND\" };\n\n // Detect logical operator (AND/OR) — assume um único conector\n const upperLogic = / AND | OR /i;\n const logicMatch = trimmed.match(upperLogic);\n const logicOperator: \"AND\" | \"OR\" = logicMatch?.[0]?.trim().toUpperCase() === \"OR\" ? \"OR\" : \"AND\";\n\n // Split por AND/OR (case-insensitive)\n const parts = trimmed\n .split(/\\s+(?:AND|OR)\\s+/i)\n .map((p) => p.trim())\n .filter(Boolean);\n\n const entries: ParsedFilterEntry[] = [];\n for (const part of parts) {\n const match = part.match(OP_REGEX);\n if (!match) {\n return { ok: false, error: `Sem operador em \"${part}\". Use =, !=, >, <, contains.` };\n }\n const opText = match[0].toLowerCase();\n const op = OP_MAP[opText];\n if (!op) {\n return { ok: false, error: `Operador desconhecido \"${match[0]}\".` };\n }\n const [fieldRaw, valueRaw] = part.split(OP_REGEX, 1).concat(\n part.slice(part.indexOf(match[0]) + match[0].length),\n );\n const field = fieldRaw?.trim();\n const value = unquote(valueRaw ?? \"\");\n if (!field) {\n return { ok: false, error: `Campo ausente em \"${part}\".` };\n }\n if (!value) {\n return { ok: false, error: `Valor ausente em \"${part}\".` };\n }\n entries.push({ field, op, value });\n }\n\n return { ok: true, entries, logicOperator };\n}\n\n/** Converte FilterPopoverEntry[] de volta pra string SQL-like. */\nexport function entriesToSql(\n entries: ParsedFilterEntry[],\n logicOperator: \"AND\" | \"OR\" = \"AND\",\n): string {\n const opText: Record<ParsedFilterEntry[\"op\"], string> = {\n eq: \"=\",\n neq: \"!=\",\n contains: \"contains\",\n gt: \">\",\n lt: \"<\",\n gte: \">=\",\n lte: \"<=\",\n };\n return entries\n .map((e) => {\n const needsQuote = /\\s|[\"']/.test(e.value);\n const v = needsQuote ? `\"${e.value.replace(/\"/g, '\\\\\"')}\"` : e.value;\n return `${e.field} ${opText[e.op]} ${v}`;\n })\n .join(` ${logicOperator} `);\n}\n","import * as React from \"react\"\nimport * as SelectPrimitive from \"@radix-ui/react-select\"\nimport { Check, ChevronDown, ChevronUp } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Select = SelectPrimitive.Root\n\nconst SelectGroup = SelectPrimitive.Group\n\nconst SelectValue = SelectPrimitive.Value\n\nexport type SelectTriggerState = \"default\" | \"error\" | \"warning\" | \"success\";\n\nconst SelectTrigger = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger> & {\n state?: SelectTriggerState;\n }\n>(({ className, children, state = \"default\", ...props }, ref) => (\n <SelectPrimitive.Trigger\n ref={ref}\n className={cn(\n \"flex min-h-form-lg w-full items-center justify-between gap-gp-md\",\n \"rounded-radius-lg px-pad-xl\",\n \"bg-bg-input dark:bg-bg-muted\",\n \"hover:bg-bg-input-hover dark:hover:bg-bg-muted-hover\",\n \"border border-border-input\",\n \"text-[13px] text-fg-default\",\n \"transition-[color,box-shadow,background-color,border-color] outline-none\",\n \"data-[placeholder]:text-fg-muted data-[placeholder]:opacity-70\",\n state === \"default\" && \"focus-visible:border-border-brand data-[state=open]:border-border-brand focus-visible:shadow-sh-ring data-[state=open]:shadow-sh-ring\",\n state === \"error\" && \"border-border-danger-muted focus-visible:border-border-danger-muted data-[state=open]:border-border-danger-muted focus-visible:shadow-sh-ring-danger data-[state=open]:shadow-sh-ring-danger\",\n state === \"warning\" && \"border-border-warning-muted focus-visible:border-border-warning-muted data-[state=open]:border-border-warning-muted focus-visible:shadow-sh-ring-warning data-[state=open]:shadow-sh-ring-warning\",\n state === \"success\" && \"border-border-success-muted focus-visible:border-border-success-muted data-[state=open]:border-border-success-muted focus-visible:shadow-sh-ring-success data-[state=open]:shadow-sh-ring-success\",\n \"disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-bg-input dark:disabled:hover:bg-bg-muted\",\n \"[&>span]:line-clamp-1\",\n className\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDown className=\"size-4 text-fg-muted shrink-0\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n))\nSelectTrigger.displayName = SelectPrimitive.Trigger.displayName\n\nconst SelectScrollUpButton = React.forwardRef<\n React.ElementRef<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-pad-xs\",\n className\n )}\n {...props}\n >\n <ChevronUp className=\"h-4 w-4\" />\n </SelectPrimitive.ScrollUpButton>\n))\nSelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName\n\nconst SelectScrollDownButton = React.forwardRef<\n React.ElementRef<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-pad-xs\",\n className\n )}\n {...props}\n >\n <ChevronDown className=\"h-4 w-4\" />\n </SelectPrimitive.ScrollDownButton>\n))\nSelectScrollDownButton.displayName =\n SelectPrimitive.ScrollDownButton.displayName\n\nconst SelectContent = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>\n>(({ className, children, position = \"popper\", ...props }, ref) => (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n ref={ref}\n className={cn(\n \"relative z-50 max-h-[--radix-select-content-available-height] min-w-[8rem] overflow-y-auto overflow-x-hidden\",\n \"rounded-[12px] bg-bg-dropdown border border-border-default shadow-sh-lg outline-float\",\n \"before:pointer-events-none before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:backdrop-blur-2xl before:backdrop-saturate-150\",\n \"text-fg-default\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n \"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n \"origin-[--radix-select-content-transform-origin]\",\n position === \"popper\" &&\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n className\n )}\n position={position}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n \"p-pad-sm\",\n position === \"popper\" &&\n \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]\"\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n))\nSelectContent.displayName = SelectPrimitive.Content.displayName\n\nconst SelectLabel = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Label\n ref={ref}\n className={cn(\"py-pad-sm pl-8 pr-2 text-label-sm text-fg-muted\", className)}\n {...props}\n />\n))\nSelectLabel.displayName = SelectPrimitive.Label.displayName\n\nconst SelectItem = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Item\n ref={ref}\n className={cn(\n \"relative flex w-full cursor-default select-none items-center gap-pad-md\",\n \"rounded-radius-sm py-pad-md pl-8 pr-pad-lg\",\n \"text-[13px] font-medium text-fg-muted\",\n \"outline-none transition-colors\",\n \"focus:bg-bg-muted focus:text-fg-default\",\n \"data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n \"[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-fg-muted\",\n \"focus:[&_svg]:text-fg-default\",\n className\n )}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <Check className=\"h-4 w-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n))\nSelectItem.displayName = SelectPrimitive.Item.displayName\n\nconst SelectSeparator = React.forwardRef<\n React.ElementRef<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-border\", className)}\n {...props}\n />\n))\nSelectSeparator.displayName = SelectPrimitive.Separator.displayName\n\nexport {\n Select,\n SelectGroup,\n SelectValue,\n SelectTrigger,\n SelectContent,\n SelectLabel,\n SelectItem,\n SelectSeparator,\n SelectScrollUpButton,\n SelectScrollDownButton,\n}\n","import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { Filter, Plus, Trash2 } from \"lucide-react\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../../../shadcn/popover\";\nimport { parseSqlFilter, entriesToSql } from \"./filter-sql-parser\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../../shadcn/select\";\nimport { Button } from \"../../Button/button\";\nimport { cn } from \"@/lib/utils\";\n\n/* ── Types ────────────────────────────────────────────────────────── */\nexport type FilterPopoverColumn = {\n key: string;\n /** Label da coluna (exibido no select) */\n label: string;\n /** Tipo do valor — define o input renderizado. Default `\"text\"`. */\n type?: \"text\" | \"number\" | \"select\";\n /** Opções pro select (quando `type=\"select\"`) */\n options?: Array<{ value: string; label: string }>;\n /** Tipo original do ColumnTypeRegistry (date, currency, etc) — opcional,\n * passado pelo DataTable pra `renderValueInput` resolver o input correto. */\n filterType?: string;\n};\n\nexport type FilterPopoverOperator = {\n id: string;\n label: string;\n};\n\nexport type FilterPopoverEntry = {\n id: string;\n columnKey: string;\n op: string;\n /** Valor do filtro — `unknown` pra carregar string, array (multiSelect/tags),\n * tupla (between/date range), número, etc. Native fallback rendering coage\n * pra string via toString; `renderValueInput` recebe o valor puro. */\n value: unknown;\n};\n\nexport type FilterPopoverProps = {\n /** Botão que abre o popover */\n trigger: ReactNode;\n\n /** Lista de colunas filtráveis */\n columns: FilterPopoverColumn[];\n /** Lista de operadores. Default `DEFAULT_FILTER_OPERATORS` (eq/neq/contains/gt/lt) */\n operators?: FilterPopoverOperator[];\n\n /** Array de filtros atuais */\n filters: FilterPopoverEntry[];\n onFiltersChange: (next: FilterPopoverEntry[]) => void;\n\n /** Habilita a tab \"Avançado\" com textarea livre. Default `false`. */\n enableAdvanced?: boolean;\n\n /** Título (default \"Filtros\") */\n title?: ReactNode;\n /** Label do conjuntor — primeiro item / demais */\n conjLabels?: { first: ReactNode; rest: ReactNode };\n\n /** Override do input de valor — Fase G.1.\n * Quando passado, FilterPopover delega o render do input pro consumer\n * (que conhece o tipo da coluna e usa ColumnTypeRegistry). Sem este prop,\n * cai no fallback nativo (select/number/text por `column.type`).\n * `value` e `onChange` são `unknown` pra suportar arrays (multiSelect/tags),\n * tuplas (between), datas, etc — sem perder shape via stringify. */\n renderValueInput?: (params: {\n column: FilterPopoverColumn;\n operator: string;\n value: unknown;\n onChange: (next: unknown) => void;\n }) => ReactNode;\n\n /** Alinhamento */\n align?: \"start\" | \"center\" | \"end\";\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n className?: string;\n};\n\nexport const DEFAULT_FILTER_OPERATORS: FilterPopoverOperator[] = [\n { id: \"eq\", label: \"é\" },\n { id: \"neq\", label: \"não é\" },\n { id: \"contains\", label: \"contém\" },\n { id: \"gt\", label: \"maior que\" },\n { id: \"lt\", label: \"menor que\" },\n];\n\nfunction generateId(): string {\n if (typeof crypto !== \"undefined\" && \"randomUUID\" in crypto) {\n return crypto.randomUUID();\n }\n return `f_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n}\n\n/** Filter row tem valor real preenchido?\n * - String vazia, null, array vazio/só nulls = vazio (pula)\n * - Operadores isEmpty/isNotEmpty não precisam de valor (sempre ativos) */\nfunction isFilterEntryActive(entry: FilterPopoverEntry): boolean {\n if (entry.op === \"isEmpty\" || entry.op === \"isNotEmpty\") return true;\n const v = entry.value;\n if (v == null) return false;\n if (typeof v === \"string\") return v.length > 0;\n if (Array.isArray(v)) {\n return v.some((x) => x != null && (typeof x === \"string\" ? x.length > 0 : true));\n }\n return true;\n}\n\n/* ── Filter Row Editor ───────────────────────────────────────────── */\ntype FilterRowEditorProps = {\n filter: FilterPopoverEntry;\n index: number;\n columns: FilterPopoverColumn[];\n operators: FilterPopoverOperator[];\n conjLabels: { first: ReactNode; rest: ReactNode };\n onChange: (next: FilterPopoverEntry) => void;\n onRemove: () => void;\n /** Override do input de valor — passado da prop top-level pra delegar\n * ao consumer (que conhece o tipo via registry). Quando undefined, usa\n * fallback nativo (select/number/text). */\n renderValueInput?: FilterPopoverProps[\"renderValueInput\"];\n};\n\n/**\n * Classes compartilhadas pra trigger/input — mesma altura, padding e box-sizing\n * pra evitar resize visual entre os campos.\n */\nconst FIELD_BASE = cn(\n \"min-h-form-md h-form-md min-w-0 w-full\",\n \"rounded-radius-md\",\n \"text-[13px]\",\n);\n\nconst INPUT_FIELD = cn(\n FIELD_BASE,\n \"px-pad-xl\",\n \"bg-bg-input dark:bg-bg-muted\",\n \"border border-border-input text-fg-default\",\n \"placeholder:text-fg-muted outline-none\",\n \"transition-[border-color,box-shadow] duration-150\",\n \"focus:border-border-brand focus:shadow-sh-ring\",\n);\n\nfunction FilterRowEditor({\n filter,\n index,\n columns,\n operators,\n conjLabels,\n onChange,\n onRemove,\n renderValueInput,\n}: FilterRowEditorProps) {\n const col = columns.find((c) => c.key === filter.columnKey);\n const isSelect = col?.type === \"select\";\n const inputType = col?.type === \"number\" ? \"number\" : \"text\";\n // Quando consumer passa renderValueInput, delega 100% (registry-aware).\n // Senão, usa fallback nativo (select/number/text).\n const customValueInput =\n renderValueInput && col\n ? renderValueInput({\n column: col,\n operator: filter.op,\n value: filter.value,\n onChange: (v) => onChange({ ...filter, value: v }),\n })\n : null;\n // Coerce pra string só pro native fallback (select/input). renderValueInput\n // recebe o valor puro (unknown) pra preservar shapes (arrays/tuplas/etc).\n const stringValue =\n typeof filter.value === \"string\"\n ? filter.value\n : filter.value == null\n ? \"\"\n : String(filter.value);\n\n return (\n <div\n className={cn(\n // Mobile: vertical (1 select por linha). sm+: horizontal alinhado.\n \"flex flex-col sm:flex-row sm:items-center gap-gp-md\",\n )}\n >\n <span className=\"text-[11px] text-fg-muted shrink-0 sm:w-[18px] sm:text-center\">\n {index === 0 ? conjLabels.first : conjLabels.rest}\n </span>\n {/* Campo (flex 1) */}\n <div className=\"w-full sm:flex-[1_1_0%] sm:basis-0 min-w-0\">\n <Select\n value={filter.columnKey}\n onValueChange={(v) =>\n onChange({ ...filter, columnKey: v, value: \"\" })\n }\n >\n <SelectTrigger\n className={cn(FIELD_BASE, \"px-pad-xl gap-gp-md\")}\n aria-label=\"Campo\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {columns.map((c) => (\n <SelectItem key={c.key} value={c.key}>\n {c.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n {/* Operador (flex 0.7 em desktop — menor, dá mais espaço pro valor) */}\n <div className=\"w-full sm:flex-[0.7_1_0%] sm:basis-0 min-w-0 sm:min-w-[80px]\">\n <Select\n value={filter.op}\n onValueChange={(v) => onChange({ ...filter, op: v })}\n >\n <SelectTrigger\n className={cn(FIELD_BASE, \"px-pad-xl gap-gp-md\")}\n aria-label=\"Operador\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {operators.map((o) => (\n <SelectItem key={o.id} value={o.id}>\n {o.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n {/* Valor (flex 1.3 — maior em desktop). Em mobile ocupa linha inteira.\n Quando `renderValueInput` passado (DataTable usa registry-aware),\n delega ao consumer. Fallback: select/number/text nativo. */}\n <div className=\"w-full sm:flex-[1.3_1_0%] sm:basis-0 min-w-0\">\n {customValueInput ? (\n customValueInput\n ) : isSelect ? (\n <Select\n value={stringValue}\n onValueChange={(v) => onChange({ ...filter, value: v })}\n >\n <SelectTrigger\n className={cn(FIELD_BASE, \"px-pad-xl gap-gp-md\")}\n aria-label=\"Valor\"\n >\n <SelectValue placeholder=\"Selecione…\" />\n </SelectTrigger>\n <SelectContent>\n {col!.options?.map((o) => (\n <SelectItem key={o.value} value={o.value}>\n {o.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ) : (\n <input\n type={inputType}\n value={stringValue}\n onChange={(e) => onChange({ ...filter, value: e.target.value })}\n placeholder=\"Valor\"\n aria-label=\"Valor\"\n className={INPUT_FIELD}\n />\n )}\n </div>\n {/* Remover (Button do DS, mesma altura do input). Em mobile alinha à direita. */}\n <Button\n color=\"secondary\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label=\"Remover condição\"\n onClick={onRemove}\n className=\"shrink-0 self-end sm:self-auto hover:bg-bg-danger-muted hover:text-fg-danger focus-visible:bg-bg-muted\"\n >\n <Trash2 strokeWidth={1.8} />\n </Button>\n </div>\n );\n}\n\n/**\n * FilterPopover — popover de filtros estilo query builder.\n *\n * Modo Visual (default):\n * - Lista de condições com campo/operador/valor\n * - Botão pra adicionar condição (sticky no rodapé do body, fora do scroll)\n * - Empty state com CTA\n *\n * Modo Avançado (opt-in via `enableAdvanced`):\n * - Textarea livre estilo SQL (sem parser real — apenas demo)\n *\n * Dumb: `filters` (array de entries) vem do consumer. Use o hook\n * `useToolbarFilters()` se quiser gerenciamento de estado pronto.\n */\nexport function FilterPopover({\n trigger,\n columns,\n operators = DEFAULT_FILTER_OPERATORS,\n filters,\n onFiltersChange,\n enableAdvanced,\n title = \"Filtros\",\n conjLabels = { first: \"Se\", rest: \"E\" },\n renderValueInput,\n align = \"end\",\n open,\n onOpenChange,\n className,\n}: FilterPopoverProps) {\n const [mode, setMode] = useState<\"visual\" | \"advanced\">(\"visual\");\n const [advancedText, setAdvancedText] = useState(\"\");\n const [advancedError, setAdvancedError] = useState<string | null>(null);\n\n // Quando entra no modo advanced, hidrata textarea com filters atuais\n useEffect(() => {\n if (mode === \"advanced\") {\n setAdvancedText(\n entriesToSql(\n filters.map((f) => ({\n field: f.columnKey,\n op: f.op as any,\n // Coerce pra string só pro modo SQL (arrays/tuplas viram representação flat)\n value:\n typeof f.value === \"string\"\n ? f.value\n : f.value == null\n ? \"\"\n : String(f.value),\n })),\n \"AND\",\n ),\n );\n setAdvancedError(null);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [mode]);\n\n const validCount = filters.filter((f) => f.value).length;\n\n const updateRow = (id: string, next: FilterPopoverEntry) =>\n onFiltersChange(filters.map((f) => (f.id === id ? next : f)));\n\n const removeRow = (id: string) =>\n onFiltersChange(filters.filter((f) => f.id !== id));\n\n const addRow = () => {\n const firstCol = columns[0];\n if (!firstCol) return;\n onFiltersChange([\n ...filters,\n {\n id: generateId(),\n columnKey: firstCol.key,\n op: operators[0]?.id ?? \"eq\",\n value: \"\",\n },\n ]);\n };\n\n const clearAll = () => onFiltersChange([]);\n\n /** Aplica o textarea SQL — parseia e converte em FilterPopoverEntry[]. */\n const applyAdvanced = () => {\n const result = parseSqlFilter(advancedText);\n if (!result.ok) {\n setAdvancedError(result.error);\n return;\n }\n setAdvancedError(null);\n // Valida que campos existem nas colunas\n const validKeys = new Set(columns.map((c) => c.key));\n const valid = result.entries.filter((e) => validKeys.has(e.field));\n const invalid = result.entries.filter((e) => !validKeys.has(e.field));\n if (invalid.length > 0) {\n setAdvancedError(\n `Campos desconhecidos: ${invalid.map((e) => e.field).join(\", \")}`,\n );\n return;\n }\n onFiltersChange(\n valid.map((e) => ({\n id: generateId(),\n columnKey: e.field,\n op: e.op,\n value: e.value,\n })),\n );\n setMode(\"visual\");\n };\n\n // Ao fechar o popover, remove linhas em branco (user clicou \"+ Adicionar\"\n // mas não preencheu valor). Delay de 500ms pra evitar piscada — durante a\n // animação de close-out a UI já está sumindo, fazer mutação no estado\n // causaria flash visível (rows removendo enquanto popover fade-out).\n // Se user reabrir antes do timeout, cancela cleanup (preserva linhas).\n const cleanupTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const handleOpenChange = (next: boolean) => {\n // Cancela cleanup pendente em qualquer transição\n if (cleanupTimeoutRef.current) {\n clearTimeout(cleanupTimeoutRef.current);\n cleanupTimeoutRef.current = null;\n }\n if (!next) {\n cleanupTimeoutRef.current = setTimeout(() => {\n const active = filters.filter(isFilterEntryActive);\n if (active.length !== filters.length) {\n onFiltersChange(active);\n }\n cleanupTimeoutRef.current = null;\n }, 500);\n }\n onOpenChange?.(next);\n };\n\n // Cleanup no unmount — evita memory leak se componente desmontar com timer ativo\n useEffect(() => {\n return () => {\n if (cleanupTimeoutRef.current) {\n clearTimeout(cleanupTimeoutRef.current);\n }\n };\n }, []);\n\n return (\n <Popover open={open} onOpenChange={handleOpenChange}>\n <PopoverTrigger asChild>{trigger}</PopoverTrigger>\n <PopoverContent\n align={align}\n className={cn(\n \"w-[560px] max-w-[calc(100vw-32px)] max-h-[min(480px,calc(100vh-80px))] p-0 flex flex-col min-h-0 overflow-hidden\",\n className,\n )}\n >\n {/* Header com tabs */}\n <div className=\"flex-none flex items-center justify-between gap-gp-md px-pad-xl py-pad-lg border-b border-border-default\">\n <h3 className=\"text-[11px] font-semibold text-fg-muted uppercase tracking-wide leading-none m-0\">\n {title}\n </h3>\n {enableAdvanced && (\n <div\n role=\"tablist\"\n className=\"inline-flex items-center gap-[2px] p-[2px] bg-bg-muted rounded-radius-md h-[34px]\"\n >\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={mode === \"visual\"}\n onClick={() => setMode(\"visual\")}\n className={cn(\n \"h-[30px] px-pad-lg rounded-radius-sm text-[12px] font-medium cursor-pointer outline-none\",\n \"transition-[background-color,color,box-shadow] duration-150\",\n mode === \"visual\"\n ? \"bg-bg-accent text-fg-default font-semibold shadow-sh-sm\"\n : \"bg-transparent text-fg-muted hover:text-fg-default\",\n )}\n >\n Visual\n </button>\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={mode === \"advanced\"}\n onClick={() => setMode(\"advanced\")}\n className={cn(\n \"h-[30px] px-pad-lg rounded-radius-sm text-[12px] font-medium cursor-pointer outline-none\",\n \"transition-[background-color,color,box-shadow] duration-150\",\n mode === \"advanced\"\n ? \"bg-bg-accent text-fg-default font-semibold shadow-sh-sm\"\n : \"bg-transparent text-fg-muted hover:text-fg-default\",\n )}\n >\n Avançado\n </button>\n </div>\n )}\n </div>\n\n {/* Body */}\n {mode === \"visual\" ? (\n filters.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center text-center px-pad-2xl py-pad-4xl\">\n <Filter\n strokeWidth={1.6}\n className=\"size-[20px] text-fg-muted mb-pad-xl\"\n />\n <p className=\"text-[13px] font-semibold text-fg-default m-0\">\n Nenhuma condição\n </p>\n <p className=\"text-[12px] text-fg-muted m-0 mt-pad-2xs mb-pad-2xl\">\n Adicione filtros pra refinar a lista.\n </p>\n <button\n type=\"button\"\n onClick={addRow}\n className={cn(\n \"inline-flex items-center gap-gp-sm h-form-md px-pad-2xl rounded-radius-lg\",\n \"bg-bg-brand text-fg-on-brand\",\n \"text-[13px] font-semibold cursor-pointer outline-none\",\n \"transition-[background-color] duration-150\",\n \"hover:bg-bg-brand-hover focus-visible:shadow-sh-ring\",\n \"[&_svg]:size-[14px]\",\n )}\n >\n <Plus strokeWidth={2.4} />\n Adicionar condição\n </button>\n </div>\n ) : (\n <>\n {/* List scrollable */}\n <div\n className={cn(\n \"flex-1 min-h-0 overflow-y-auto\",\n \"[scrollbar-width:thin] [scrollbar-color:var(--color-border-default)_transparent]\",\n \"[&::-webkit-scrollbar]:w-[6px]\",\n \"[&::-webkit-scrollbar-thumb]:bg-border-default [&::-webkit-scrollbar-thumb]:rounded-full\",\n \"[&::-webkit-scrollbar-track]:bg-transparent\",\n )}\n >\n <div className=\"flex flex-col gap-gp-2xl sm:gap-gp-md p-pad-xl\">\n {filters.map((f, i) => (\n <FilterRowEditor\n key={f.id}\n filter={f}\n index={i}\n columns={columns}\n operators={operators}\n conjLabels={conjLabels}\n onChange={(next) => updateRow(f.id, next)}\n onRemove={() => removeRow(f.id)}\n renderValueInput={renderValueInput}\n />\n ))}\n </div>\n </div>\n {/* Add button — fora do scroll, full-width, dashed */}\n <div className=\"flex-none px-pad-xl pb-pad-xl pt-0\">\n <button\n type=\"button\"\n onClick={addRow}\n className={cn(\n \"flex items-center justify-center gap-gp-sm w-full\",\n \"min-h-form-md px-pad-xl rounded-radius-md\",\n \"bg-transparent text-fg-muted\",\n \"border border-dashed border-border-default\",\n \"text-[13px] font-medium cursor-pointer outline-none\",\n \"transition-[background-color,color,border-color] duration-150\",\n \"hover:bg-bg-muted hover:text-fg-default hover:border-border-default\",\n \"focus-visible:bg-bg-muted focus-visible:text-fg-default\",\n \"[&_svg]:size-[14px]\",\n )}\n >\n <Plus strokeWidth={2.2} />\n Adicionar condição\n </button>\n </div>\n </>\n )\n ) : (\n <div className=\"flex-1 min-h-0 flex flex-col gap-gp-md p-pad-xl overflow-y-auto\">\n <span className=\"text-[11px] text-fg-muted\">\n Editor livre — sintaxe estilo SQL. Operadores: <code>=</code>{\" \"}\n <code>!=</code> <code>></code> <code><</code>{\" \"}\n <code>contains</code>. Conectores: <code>AND</code>{\" \"}\n <code>OR</code>.\n </span>\n <textarea\n spellCheck={false}\n value={advancedText}\n onChange={(e) => {\n setAdvancedText(e.target.value);\n setAdvancedError(null);\n }}\n rows={8}\n placeholder={`-- Ex:\\nstatus = \"active\"\\nAND value > 1000`}\n className={cn(\n \"w-full px-pad-xl py-pad-md rounded-radius-md\",\n \"bg-bg-input dark:bg-bg-muted\",\n \"border\",\n advancedError ? \"border-border-critical\" : \"border-border-input\",\n \"text-[12px] font-mono text-fg-default placeholder:text-fg-muted\",\n \"outline-none resize-y\",\n \"transition-[border-color,box-shadow] duration-150\",\n advancedError\n ? \"focus:border-border-critical focus:shadow-sh-ring-danger\"\n : \"focus:border-border-brand focus:shadow-sh-ring\",\n )}\n />\n {advancedError && (\n <p className=\"text-[11px] text-fg-critical\">\n {advancedError}\n </p>\n )}\n <button\n type=\"button\"\n onClick={applyAdvanced}\n className={cn(\n \"self-end px-pad-xl h-form-md rounded-radius-md\",\n \"bg-bg-brand text-fg-on-brand\",\n \"text-[12px] font-semibold\",\n \"hover:bg-bg-brand-hover focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-ring-brand\",\n \"transition-[background-color,box-shadow] duration-150\",\n )}\n >\n Aplicar\n </button>\n </div>\n )}\n\n {/* Footer */}\n <div className=\"flex-none flex items-center justify-between gap-gp-md px-pad-xl min-h-[44px] border-t border-border-default\">\n <button\n type=\"button\"\n onClick={clearAll}\n disabled={filters.length === 0}\n className={cn(\n \"text-[12px] font-medium text-fg-brand bg-transparent border-0 p-0 cursor-pointer outline-none\",\n \"hover:underline focus-visible:underline underline-offset-2\",\n \"disabled:opacity-50 disabled:pointer-events-none disabled:no-underline\",\n )}\n >\n Limpar todos\n </button>\n <span className=\"text-[11px] text-fg-muted\">\n {validCount === 0\n ? \"Nenhum filtro ativo\"\n : `${validCount} ${\n validCount > 1 ? \"condições ativas\" : \"condição ativa\"\n }`}\n </span>\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n","import * as React from \"react\";\nimport {\n ChevronLeft,\n ChevronRight,\n ChevronsLeft,\n ChevronsRight,\n MoreHorizontal,\n} from \"lucide-react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\n\n/**\n * Pagination — primitives baixo nível pra paginação.\n *\n * Visual alinhado com `.tbl-footer-right` do design-and-table-v2:\n * - Nav buttons (« ‹ › »): 36×36 com border, radius-lg\n * - Pages container: bg-muted, radius-lg, padding 3px (segmented look)\n * - Page item: 30×30 transparente; active = bg-accent + shadow-sm + font-semibold\n *\n * Pra um wrapper \"one-shot\" com pageSize + range + nav → use <FooterTable>.\n */\n\n/* ── Root nav ────────────────────────────────────────────────────────── */\nconst Pagination = ({\n className,\n ...props\n}: React.ComponentProps<\"nav\">) => (\n <nav\n role=\"navigation\"\n aria-label=\"Paginação\"\n className={cn(\"inline-flex items-center gap-gp-xs\", className)}\n {...props}\n />\n);\nPagination.displayName = \"Pagination\";\n\n/* ── Content (container das page items — visual segmented) ──────────── */\nconst PaginationContent = React.forwardRef<\n HTMLUListElement,\n React.ComponentProps<\"ul\">\n>(({ className, ...props }, ref) => (\n <ul\n ref={ref}\n className={cn(\n \"inline-flex items-center gap-[2px]\",\n \"bg-bg-muted rounded-radius-lg p-[3px] mx-gp-sm h-form-md\",\n className,\n )}\n {...props}\n />\n));\nPaginationContent.displayName = \"PaginationContent\";\n\n/* ── Item wrapper (li) ───────────────────────────────────────────────── */\nconst PaginationItem = React.forwardRef<\n HTMLLIElement,\n React.ComponentProps<\"li\">\n>(({ className, ...props }, ref) => (\n <li ref={ref} className={cn(\"\", className)} {...props} />\n));\nPaginationItem.displayName = \"PaginationItem\";\n\n/* ── Link (número) — dentro do PaginationContent ──────────────────── */\nconst paginationLinkVariants = cva(\n [\n \"inline-flex items-center justify-center\",\n \"min-w-[30px] h-[30px] px-pad-md\",\n \"rounded-radius-md text-[13px] font-medium tabular-nums\",\n \"outline-none cursor-pointer transition-[background-color,color,box-shadow]\",\n \"focus-visible:shadow-sh-ring\",\n \"disabled:opacity-50 disabled:pointer-events-none\",\n ],\n {\n variants: {\n isActive: {\n true: \"bg-bg-accent text-fg-default font-semibold shadow-sh-sm\",\n false: \"bg-transparent text-fg-muted hover:text-fg-default\",\n },\n },\n defaultVariants: { isActive: false },\n },\n);\n\nexport type PaginationLinkProps = {\n isActive?: boolean;\n} & React.ButtonHTMLAttributes<HTMLButtonElement> &\n VariantProps<typeof paginationLinkVariants>;\n\nconst PaginationLink = React.forwardRef<\n HTMLButtonElement,\n PaginationLinkProps\n>(({ className, isActive, type = \"button\", ...props }, ref) => (\n <button\n ref={ref}\n type={type}\n aria-current={isActive ? \"page\" : undefined}\n className={cn(paginationLinkVariants({ isActive }), className)}\n {...props}\n />\n));\nPaginationLink.displayName = \"PaginationLink\";\n\n/* ── Nav buttons (« ‹ › ») — fora do Content, com border individual ── */\nconst paginationNavVariants = cva([\n \"inline-flex items-center justify-center shrink-0\",\n \"size-form-md rounded-radius-lg\",\n \"border border-border-default bg-transparent text-fg-default\",\n \"outline-none cursor-pointer transition-[background-color,color,opacity,border-color,box-shadow]\",\n \"hover:bg-bg-muted\",\n \"focus-visible:shadow-sh-ring\",\n \"disabled:opacity-35 disabled:pointer-events-none\",\n \"[&_svg]:size-4\",\n]);\n\ntype NavBtnProps = React.ButtonHTMLAttributes<HTMLButtonElement>;\n\nconst PaginationPrevious = React.forwardRef<HTMLButtonElement, NavBtnProps>(\n ({ className, type = \"button\", \"aria-label\": ariaLabel, ...props }, ref) => (\n <button\n ref={ref}\n type={type}\n aria-label={ariaLabel ?? \"Página anterior\"}\n className={cn(paginationNavVariants(), className)}\n {...props}\n >\n <ChevronLeft />\n </button>\n ),\n);\nPaginationPrevious.displayName = \"PaginationPrevious\";\n\nconst PaginationNext = React.forwardRef<HTMLButtonElement, NavBtnProps>(\n ({ className, type = \"button\", \"aria-label\": ariaLabel, ...props }, ref) => (\n <button\n ref={ref}\n type={type}\n aria-label={ariaLabel ?? \"Próxima página\"}\n className={cn(paginationNavVariants(), className)}\n {...props}\n >\n <ChevronRight />\n </button>\n ),\n);\nPaginationNext.displayName = \"PaginationNext\";\n\nconst PaginationFirst = React.forwardRef<HTMLButtonElement, NavBtnProps>(\n ({ className, type = \"button\", \"aria-label\": ariaLabel, ...props }, ref) => (\n <button\n ref={ref}\n type={type}\n aria-label={ariaLabel ?? \"Primeira página\"}\n className={cn(paginationNavVariants(), className)}\n {...props}\n >\n <ChevronsLeft />\n </button>\n ),\n);\nPaginationFirst.displayName = \"PaginationFirst\";\n\nconst PaginationLast = React.forwardRef<HTMLButtonElement, NavBtnProps>(\n ({ className, type = \"button\", \"aria-label\": ariaLabel, ...props }, ref) => (\n <button\n ref={ref}\n type={type}\n aria-label={ariaLabel ?? \"Última página\"}\n className={cn(paginationNavVariants(), className)}\n {...props}\n >\n <ChevronsRight />\n </button>\n ),\n);\nPaginationLast.displayName = \"PaginationLast\";\n\n/* ── Ellipsis ────────────────────────────────────────────────────────── */\nconst PaginationEllipsis = ({\n className,\n ...props\n}: React.ComponentProps<\"span\">) => (\n <span\n aria-hidden=\"true\"\n className={cn(\n \"inline-flex items-center justify-center min-w-[22px] h-[30px]\",\n \"text-[13px] text-fg-muted tracking-wider select-none\",\n className,\n )}\n {...props}\n >\n <MoreHorizontal className=\"size-4\" />\n </span>\n);\nPaginationEllipsis.displayName = \"PaginationEllipsis\";\n\n/**\n * Helper — gera array de páginas com ellipsis.\n *\n * Regras:\n * - Total ≤ 7 páginas → mostra todas\n * - Senão → [1, 2, …, page-1, page, page+1, …, last-1, last]\n *\n * Retorna `number[]` com `\"ellipsis\"` como string nos gaps.\n *\n * Ex (page=5, total=20): [1, 2, \"ellipsis\", 4, 5, 6, \"ellipsis\", 19, 20]\n */\nexport function getPaginationRange(page: number, total: number): (number | \"ellipsis\")[] {\n if (total <= 7) return Array.from({ length: total }, (_, i) => i + 1);\n const set = new Set([1, 2, total - 1, total, page - 1, page, page + 1]);\n const sorted = [...set]\n .filter((n) => n >= 1 && n <= total)\n .sort((a, b) => a - b);\n const out: (number | \"ellipsis\")[] = [];\n sorted.forEach((n, i) => {\n if (i > 0 && n - sorted[i - 1] > 1) out.push(\"ellipsis\");\n out.push(n);\n });\n return out;\n}\n\nexport {\n Pagination,\n PaginationContent,\n PaginationItem,\n PaginationLink,\n PaginationPrevious,\n PaginationNext,\n PaginationFirst,\n PaginationLast,\n PaginationEllipsis,\n paginationLinkVariants,\n paginationNavVariants,\n};\n","import {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../shadcn/select\";\nimport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationFirst,\n PaginationItem,\n PaginationLast,\n PaginationLink,\n PaginationNext,\n PaginationPrevious,\n getPaginationRange,\n} from \"../../shadcn/pagination\";\nimport { cn } from \"@/lib/utils\";\nimport type { FooterTableProps } from \"./footer-table.types\";\n\nconst DEFAULT_PAGE_SIZES = [10, 25, 50, 100];\n\n/**\n * FooterTable — footer completo de tabela com paginação + page-size + range.\n *\n * Compõe:\n * - Select de \"Linhas\" por página (Select do shadcn)\n * - Range \"1–10 de 87 rows\"\n * - Contagem de seleção opcional (\"· 1 selecionado\")\n * - Pagination (« ‹ pages › ») com ellipsis automática\n *\n * Layout: flex justify-between, mobile empilha (flex-col).\n *\n * Replica o `.tbl-footer` do design-and-table-v2.\n */\nexport function FooterTable({\n totalCount,\n page,\n pageSize,\n onPageChange,\n onPageSizeChange,\n pageSizeOptions = DEFAULT_PAGE_SIZES,\n selectionCount = 0,\n pageSizeLabel = \"Linhas\",\n rowLabel = \"rows\",\n locale = \"pt-BR\",\n hidePageSize,\n hideRange,\n hideFirstLast,\n className,\n}: FooterTableProps) {\n const lastPage = Math.max(1, Math.ceil(totalCount / pageSize));\n const safePage = Math.min(Math.max(1, page), lastPage);\n const start = totalCount === 0 ? 0 : (safePage - 1) * pageSize + 1;\n const end = Math.min(safePage * pageSize, totalCount);\n const pages = getPaginationRange(safePage, lastPage);\n\n const fmt = (n: number) => n.toLocaleString(locale);\n\n return (\n <footer\n className={cn(\n // Mobile: empilha vertical (left em cima, paginação embaixo)\n \"flex flex-col sm:flex-row sm:items-center sm:justify-between\",\n \"gap-gp-2xl px-pad-xs pt-pad-xl\",\n \"text-[13px] text-fg-default\",\n className,\n )}\n >\n {/* ── Left: pageSize + range + selection ───────────────────── */}\n <div className=\"flex flex-wrap items-center gap-gp-2xl\">\n {!hidePageSize && (\n <label className=\"inline-flex items-center gap-gp-md text-fg-muted\">\n <span className=\"font-medium\">{pageSizeLabel}</span>\n <Select\n value={String(pageSize)}\n onValueChange={(v) => {\n onPageSizeChange(Number(v));\n onPageChange(1);\n }}\n >\n <SelectTrigger\n className=\"min-h-form-md w-auto pl-pad-2xl pr-pad-xl gap-gp-lg\"\n aria-label={pageSizeLabel}\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {pageSizeOptions.map((n) => (\n <SelectItem key={n} value={String(n)}>\n {n}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n )}\n\n {!hideRange && (\n <span className=\"text-fg-muted whitespace-nowrap\">\n <strong className=\"font-semibold text-fg-default\">\n {fmt(start)}–{fmt(end)}\n </strong>\n {\" de \"}\n <strong className=\"font-semibold text-fg-default\">\n {fmt(totalCount)}\n </strong>\n {\" \"}{rowLabel}\n </span>\n )}\n\n {selectionCount > 0 && (\n <span className=\"text-fg-muted whitespace-nowrap\">\n · {selectionCount} selecionado{selectionCount > 1 ? \"s\" : \"\"}\n </span>\n )}\n </div>\n\n {/* ── Right: Pagination ────────────────────────────────────── */}\n <Pagination>\n {!hideFirstLast && (\n <PaginationFirst\n onClick={() => onPageChange(1)}\n disabled={safePage === 1}\n />\n )}\n <PaginationPrevious\n onClick={() => onPageChange(Math.max(1, safePage - 1))}\n disabled={safePage === 1}\n />\n <PaginationContent>\n {pages.map((p, i) =>\n p === \"ellipsis\" ? (\n <PaginationItem key={`e-${i}`}>\n <PaginationEllipsis />\n </PaginationItem>\n ) : (\n <PaginationItem key={p}>\n <PaginationLink\n isActive={p === safePage}\n onClick={() => onPageChange(p)}\n aria-label={`Página ${p}`}\n >\n {p}\n </PaginationLink>\n </PaginationItem>\n ),\n )}\n </PaginationContent>\n <PaginationNext\n onClick={() => onPageChange(Math.min(lastPage, safePage + 1))}\n disabled={safePage === lastPage}\n />\n {!hideFirstLast && (\n <PaginationLast\n onClick={() => onPageChange(lastPage)}\n disabled={safePage === lastPage}\n />\n )}\n </Pagination>\n </footer>\n );\n}\n\n/* ── Skeleton ─────────────────────────────────────────────────────────────── */\n\nexport type FooterTableSkeletonProps = {\n /** Quantos botões de página simular no skeleton. Default: 5. */\n pageButtonCount?: number;\n className?: string;\n};\n\n/**\n * Estado loading do FooterTable — usado pelo DataTable enquanto a primeira\n * chamada de `fetchData` não retornou totalCount.\n *\n * Mantém a mesma silhueta do footer real (page-size select + range + pagination)\n * pra evitar layout shift quando o conteúdo chega.\n */\nexport function FooterTableSkeleton({\n pageButtonCount = 5,\n className,\n}: FooterTableSkeletonProps) {\n return (\n <footer\n aria-busy=\"true\"\n aria-label=\"Carregando paginação\"\n className={cn(\n \"flex flex-col sm:flex-row sm:items-center sm:justify-between\",\n \"gap-gp-2xl px-pad-xs pt-pad-xl\",\n className,\n )}\n >\n {/* Left: page-size select + range */}\n <div className=\"flex items-center gap-gp-2xl\">\n <div className=\"h-form-md w-[88px] rounded-radius-md bg-bg-muted animate-pulse\" />\n <div className=\"h-[14px] w-[140px] rounded-radius-sm bg-bg-muted animate-pulse\" />\n </div>\n {/* Right: prev + pages + next (mesma silhueta do <Pagination>) */}\n <div className=\"inline-flex items-center gap-gp-xs\">\n {Array.from({ length: pageButtonCount + 4 }, (_, i) => (\n <div\n key={i}\n className=\"h-form-md w-form-md rounded-radius-md bg-bg-muted animate-pulse\"\n />\n ))}\n </div>\n </footer>\n );\n}\n","import { tv } from \"@/utils/tv\";\n\n/**\n * Slots tv() pro <Kanban>.\n *\n * Réplica visual do TblKanban do sandbox `/design-and-table-v2`, agora consumindo\n * tokens DS de forma estrita. Header da coluna \"solto\" (mesma bg do col body),\n * cards com shadow-sm permanente flutuando sobre bg-muted da coluna.\n *\n * Valores fora da escala DS (296px width, line-clamp values, offsets posicionais\n * dos slots absolute) permanecem como arbitrary literal — calibração visual exata.\n */\n\n/* ── Board (container externo) ───────────────────────────────── */\n\nexport const root = tv({\n base: [\n \"flex flex-1 min-h-0 overflow-hidden\",\n // Sem moldura outer — kanban assume a área disponível\n ],\n});\n\nexport const board = tv({\n base: [\n \"flex flex-1 gap-gp-2xl p-0\",\n \"overflow-x-auto overflow-y-hidden scrollbar-thin\",\n ],\n});\n\n/* ── Column ──────────────────────────────────────────────────── */\n\nexport const column = tv({\n base: [\n \"flex flex-col w-[296px] shrink-0 max-h-full\",\n \"bg-bg-muted rounded-radius-xl\",\n \"overflow-hidden\",\n ],\n});\n\n/** Header da coluna — solto sobre o bg-muted, sem divider. */\nexport const columnHead = tv({\n base: [\n \"flex items-center gap-gp-md\",\n \"px-pad-xl pt-pad-xl pb-pad-sm\",\n \"bg-transparent\",\n ],\n});\n\nexport const columnDot = tv({\n base: \"size-[8px] rounded-radius-full shrink-0\",\n});\n\nexport const columnTitle = tv({\n base: [\n \"m-0 text-label-sm text-fg-default\",\n // Não expande (badge fica grudado à direita do título)\n \"shrink min-w-0\",\n \"whitespace-nowrap overflow-hidden text-ellipsis\",\n ],\n});\n\nexport const columnCount = tv({\n base: [\n \"inline-flex items-center justify-center shrink-0\",\n \"min-w-[20px] h-[20px] px-pad-sm\",\n \"bg-bg-muted-hover rounded-radius-full\",\n \"text-caption-sm text-fg-muted\",\n \"[font-variant-numeric:tabular-nums]\",\n ],\n});\n\n/** Wrapper que empurra os botões de ação pro canto direito. */\nexport const columnActionsSpacer = tv({\n base: \"ml-auto inline-flex items-center gap-gp-2xs\",\n});\n\n/* ── Column body (lista de cards) ────────────────────────────── */\n\nexport const columnBody = tv({\n base: [\n \"flex flex-1 flex-col gap-gp-md min-h-0\",\n \"px-pad-md pt-sp-xs pb-pad-md\",\n \"overflow-y-auto overflow-x-hidden scrollbar-thin\",\n ],\n});\n\n/**\n * Empty state — flex-1 ocupa o resto do col-body e centraliza vertical.\n * Sem bg/border (transparente sobre col bg). Ícone + texto sutis pra não\n * competir com cards de colunas vizinhas.\n */\nexport const columnEmpty = tv({\n base: [\n \"flex flex-1 flex-col items-center justify-center gap-gp-sm\",\n \"py-pad-3xl px-pad-xl\",\n \"text-center text-caption-md text-fg-subtle\",\n ],\n});\n\n/** Ícone do empty state — discreto, mesma cor do texto. */\nexport const columnEmptyIcon = tv({\n base: \"size-icon-md text-fg-subtle opacity-70\",\n});\n\n/**\n * Botão \"+ Adicionar\" no rodapé da coluna — dashed centered.\n *\n * Mantido como `<button>` raw porque o variant dashed-ghost não existe no\n * `<Button>` DS. Estilos migrados pra tokens; min-h alinhado com size sm.\n */\nexport const columnAdd = tv({\n base: [\n \"inline-flex items-center justify-center gap-gp-sm\",\n \"mx-pad-md mb-pad-md mt-sp-2xs\",\n \"px-pad-lg min-h-form-sm\",\n \"bg-transparent border border-dashed border-border-input rounded-radius-md\",\n \"text-caption-md font-medium text-fg-muted\",\n \"cursor-pointer\",\n \"transition-[background-color,color,border-color] duration-150\",\n \"hover:bg-bg-surface hover:text-fg-default hover:border-border-default\",\n \"focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-ring-brand\",\n ],\n});\n\n/* ── Card ────────────────────────────────────────────────────── */\n\nexport const card = tv({\n base: [\n \"group/kanban-card\",\n \"relative flex flex-col gap-gp-md\",\n \"p-pad-xl\",\n \"bg-bg-surface border border-border-subtle rounded-radius-lg\",\n \"shadow-sh-sm\",\n \"cursor-pointer text-left\",\n \"transition-[padding-left,background-color,border-color,box-shadow] duration-150 ease-out\",\n \"hover:border-border-default hover:shadow-sh-md\",\n // No light, hover mantém bg-surface (branco) — só border/shadow mudam.\n // No dark, escurece o card pra dar profundidade (em vez de \"ficar mais claro\"\n // que era o efeito padrão por causa da shadow sobre bg-surface dark).\n \"dark:hover:bg-bg-canvas\",\n \"focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-ring-brand\",\n ],\n variants: {\n /** Card selecionado (checkbox marcado) — bg brand-subtle + strip lateral. */\n selected: {\n true: [\n \"bg-bg-brand-subtle border-border-brand-subtle\",\n \"before:content-[''] before:absolute before:left-0 before:top-[8px] before:bottom-[8px]\",\n \"before:w-[3px] before:bg-bg-brand before:rounded-r-[2px]\",\n \"before:pointer-events-none\",\n ].join(\" \"),\n },\n /** Card \"aberto\" no detail panel — destaque com border-brand e ring shadow. */\n open: {\n true: \"!border-border-brand shadow-sh-ring\",\n },\n /**\n * Reserva 24px à esquerda pro checkbox aparecer sem sobrepor o avatar.\n * Aplicado APENAS quando o board tem `onToggleSelect` (showCheckbox=true) —\n * caso contrário, hover não desloca o conteúdo (visual mais estável).\n */\n reserveCheck: {\n true: \"hover:pl-[36px] focus-visible:pl-[36px]\",\n },\n },\n compoundVariants: [\n // Card selected + reserveCheck → força sempre o pl reservado (mantém strip lateral visível)\n { selected: true, reserveCheck: true, class: \"!pl-[36px]\" },\n ],\n});\n\n/**\n * Checkbox absolute top-left — alinhado vertical com o avatar do head.\n *\n * Visibility: aparece em hover do card OU foco por teclado (focus-visible).\n * `focus-visible` (em vez de `focus-within`) evita que o checkbox permaneça\n * visível ao desmarcar via clique — o foco fica retido no input mas\n * `focus-visible` só ativa em navegação por teclado.\n */\nexport const cardCheck = tv({\n base: [\n \"absolute top-[18px] left-[12px] z-[1]\",\n \"opacity-0 transition-opacity duration-150\",\n \"group-hover/kanban-card:opacity-100\",\n \"group-focus-visible/kanban-card:opacity-100\",\n ],\n variants: {\n selected: { true: \"!opacity-100\" },\n },\n});\n\n/**\n * Wrapper de posicionamento do menu \"⋯\" no card.\n *\n * Apenas absolute positioning + opacity transitions. O visual do botão\n * (size, focus ring, hover bg) vem do `<Button>` DS.\n */\nexport const cardMenuSlot = tv({\n base: [\n \"absolute top-[6px] right-[6px] z-[2]\",\n \"opacity-0\",\n \"transition-opacity duration-150\",\n \"group-hover/kanban-card:opacity-100\",\n \"group-focus-visible/kanban-card:opacity-100\",\n ],\n});\n\n/** Head do card — avatar + título/subtítulo. Reserva 28px à direita pro menu. */\nexport const cardHead = tv({\n base: \"flex items-center gap-gp-md pr-[28px]\",\n});\n\nexport const cardTitleWrap = tv({\n base: \"flex-1 min-w-0 flex flex-col gap-gp-2xs\",\n});\n\nexport const cardTitle = tv({\n base: [\n \"text-label-sm text-fg-default leading-[1.3]\",\n \"whitespace-nowrap overflow-hidden text-ellipsis\",\n ],\n});\n\nexport const cardSubtitle = tv({\n base: \"text-caption-sm text-fg-muted [font-variant-numeric:tabular-nums]\",\n});\n\n/** Descrição — line-clamp 2, fg-muted. */\nexport const cardDesc = tv({\n base: [\n \"m-0 text-caption-md leading-[1.45] text-fg-muted\",\n \"[display:-webkit-box] [-webkit-line-clamp:2] [-webkit-box-orient:vertical]\",\n \"overflow-hidden\",\n ],\n});\n\n/** Meta (chip + valor) — flex space-between. */\nexport const cardMeta = tv({\n base: \"flex items-center justify-between gap-gp-md\",\n});\n\nexport const cardValue = tv({\n base: \"text-caption-md font-semibold text-fg-default [font-variant-numeric:tabular-nums]\",\n});\n\n/** Footer (agent + data) — separador solid no top. */\nexport const cardFoot = tv({\n base: [\n \"flex items-center justify-between gap-gp-md\",\n \"pt-pad-md border-t border-border-subtle\",\n ],\n});\n\n/* ── DnD slots ─────────────────────────────────────────────── */\n\n/** Card sendo arrastado — opacity baixa + cursor grabbing. */\nexport const cardDragging = tv({\n base: \"opacity-40 cursor-grabbing\",\n});\n\n/**\n * Coluna candidata válida durante drag (over + canReceiveDrop !== false).\n * Outline brand + bg subtle pra indicar drop zone aceita.\n */\nexport const columnDropTarget = tv({\n base: \"outline outline-2 outline-offset-[-2px] outline-border-brand bg-bg-brand-subtle/30 transition-[outline,background-color] duration-150\",\n});\n\n/**\n * Coluna que não aceita drop (canReceiveDrop === false).\n * Atenuada SEMPRE durante drag (não só when over) — feedback visual que ela\n * está \"fora do jogo\". Cursor not-allowed quando o usuário insiste em over.\n */\nexport const columnDropInvalidDimmed = tv({\n base: \"opacity-50 transition-opacity duration-200\",\n});\n\nexport const columnDropInvalidOver = tv({\n base: \"cursor-not-allowed\",\n});\n\n/**\n * Drop placeholder — slot fino com ícone \"+\" renderizado na posição exata\n * onde o card vai aterrissar (antes/depois do card hovered, ou no fim da\n * coluna quando hover em área vazia). Visual sutil — uma \"linha\" indicando\n * inserção, não um card fantasma grande.\n */\nexport const dropPlaceholder = tv({\n base: [\n \"h-[36px] flex items-center justify-center shrink-0\",\n \"rounded-radius-md border border-dashed border-border-brand\",\n \"bg-bg-brand-subtle/40\",\n \"text-fg-brand\",\n \"transition-opacity duration-150\",\n \"[&>svg]:size-[14px]\",\n ],\n});\n","import { useCallback, useMemo, useState } from \"react\";\nimport {\n PointerSensor,\n KeyboardSensor,\n useSensor,\n useSensors,\n type DragEndEvent,\n type DragOverEvent,\n type DragStartEvent,\n} from \"@dnd-kit/core\";\nimport type { KanbanColumn } from \"../kanban.types\";\n\ntype UseKanbanDnDOptions = {\n enabled: boolean;\n columns: KanbanColumn[];\n /** Lookup `cardId → columnId` pra resolver drop em cima de card específico. */\n cardColumnLookup: Map<string, string>;\n onCardMove?: (cardId: string, from: string, to: string) => void | Promise<unknown>;\n};\n\ntype DragStartData = {\n cardId: string;\n fromColumnId: string;\n};\n\n/** Prefixos pra distinguir tipo de droppable no `over.id`. */\nconst COL_PREFIX = \"column:\";\nconst CARD_PREFIX = \"card:\";\n\nexport const droppableIdForColumn = (id: string) => `${COL_PREFIX}${id}`;\nexport const droppableIdForCard = (id: string) => `${CARD_PREFIX}${id}`;\n\n/**\n * Encapsula sensors + handlers do `@dnd-kit/core` pro Kanban.\n *\n * - PointerSensor com `distance: 5` evita ativar drag em cliques curtos\n * (preserva click-to-open do card).\n * - Tracks `activeCardId` + `fromColumnId` durante drag.\n * - Tracks `overColumnId` e `overCardId` em `onDragOver` — quando o cursor está\n * exatamente sobre outro card, `overCardId` aponta pra ele e `overColumnId`\n * resolve pra coluna desse card. Quando está na área vazia da coluna,\n * `overColumnId` aponta pra coluna e `overCardId` é null.\n * - Drop pode resolver pra `column:{id}` (fim da coluna) ou `card:{id}` (antes\n * do card hovered) — em ambos os casos, o `to` é a coluna resultante.\n *\n * Quando `enabled === false`, retorna estado inerte (handlers no-op).\n */\nexport function useKanbanDnD({\n enabled,\n columns,\n cardColumnLookup,\n onCardMove,\n}: UseKanbanDnDOptions) {\n const [dragState, setDragState] = useState<DragStartData | null>(null);\n const [overColumnId, setOverColumnId] = useState<string | null>(null);\n const [overCardId, setOverCardId] = useState<string | null>(null);\n\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),\n useSensor(KeyboardSensor),\n );\n\n const columnsById = useMemo(() => {\n const map = new Map<string, KanbanColumn>();\n for (const c of columns) map.set(c.id, c);\n return map;\n }, [columns]);\n\n /** Resolve `over.id` (namespaced) → columnId resultante + cardId opcional. */\n const resolveOver = useCallback(\n (overId: string | null): { columnId: string | null; cardId: string | null } => {\n if (!overId) return { columnId: null, cardId: null };\n if (overId.startsWith(COL_PREFIX)) {\n return { columnId: overId.slice(COL_PREFIX.length), cardId: null };\n }\n if (overId.startsWith(CARD_PREFIX)) {\n const cardId = overId.slice(CARD_PREFIX.length);\n return { columnId: cardColumnLookup.get(cardId) ?? null, cardId };\n }\n return { columnId: null, cardId: null };\n },\n [cardColumnLookup],\n );\n\n const handleDragStart = useCallback((event: DragStartEvent) => {\n if (!enabled) return;\n const data = event.active.data.current as DragStartData | undefined;\n if (!data) return;\n setDragState(data);\n }, [enabled]);\n\n const handleDragOver = useCallback((event: DragOverEvent) => {\n if (!enabled) return;\n const overId = event.over ? String(event.over.id) : null;\n const { columnId, cardId } = resolveOver(overId);\n setOverColumnId(columnId);\n setOverCardId(cardId);\n }, [enabled, resolveOver]);\n\n const handleDragEnd = useCallback((event: DragEndEvent) => {\n const active = dragState;\n setDragState(null);\n setOverColumnId(null);\n setOverCardId(null);\n if (!enabled || !active || !event.over) return;\n\n const { columnId: toColumnId } = resolveOver(String(event.over.id));\n if (!toColumnId || toColumnId === active.fromColumnId) return;\n\n const dest = columnsById.get(toColumnId);\n if (dest?.canReceiveDrop === false) return;\n\n onCardMove?.(active.cardId, active.fromColumnId, toColumnId);\n }, [enabled, dragState, columnsById, onCardMove, resolveOver]);\n\n const handleDragCancel = useCallback(() => {\n setDragState(null);\n setOverColumnId(null);\n setOverCardId(null);\n }, []);\n\n return {\n sensors,\n activeCardId: dragState?.cardId ?? null,\n fromColumnId: dragState?.fromColumnId ?? null,\n overColumnId,\n overCardId,\n handleDragStart,\n handleDragOver,\n handleDragEnd,\n handleDragCancel,\n };\n}\n","import { Fragment, useMemo, type KeyboardEvent, type MouseEvent, type ReactNode } from \"react\";\nimport { Inbox, MoreHorizontal, Plus } from \"lucide-react\";\nimport {\n DndContext,\n DragOverlay,\n closestCorners,\n useDraggable,\n useDroppable,\n} from \"@dnd-kit/core\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"../Button\";\nimport { Checkbox } from \"../../shadcn/checkbox\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"../../shadcn/dropdown-menu\";\nimport * as s from \"./kanban.styles\";\nimport {\n droppableIdForCard,\n droppableIdForColumn,\n useKanbanDnD,\n} from \"./hooks/use-kanban-dnd\";\nimport type {\n KanbanCardData,\n KanbanColumn,\n KanbanMenuItem,\n KanbanProps,\n KanbanRenderCardParams,\n} from \"./kanban.types\";\n\n/**\n * Kanban — board com colunas verticais (estágios) e cards distribuídos.\n *\n * **Dumb primitive**: recebe `columns` + `cards` e callbacks de interação.\n * Não gerencia state de seleção / detail panel / menus / cards — tudo controlado.\n *\n * **Features**:\n * - Layout default do card (avatar/title/subtitle/description/chip/value/footer)\n * OU custom via `renderCard` (consumer fornece o miolo, primitive controla\n * wrapper/focus/checkbox/menu positioning).\n * - Menus padronizados via `getCardMenuItems` / `getColumnMenuItems` (items →\n * `<DropdownMenu>` automático) OU callbacks manuais (`onCardMenu` / `onColumnMenu`).\n * - DnD entre colunas via `enableDnD` + `onCardMove`. Constraints por coluna\n * (`canReceiveDrop`, `canDragFrom`). Primitive **não faz revert** automático;\n * consumer commita atualizando `cards` props.\n *\n * Visual alinhado com TblKanban do sandbox `/design-and-table-v2`, consumindo\n * tokens DS estritamente.\n */\nexport function Kanban({\n columns,\n cards,\n selectedIds,\n onToggleSelect,\n openCardId,\n onOpenCard,\n onAddCard,\n onColumnMenu,\n getColumnMenuItems,\n onAddInFooter,\n hideFooterAdd = false,\n onCardMenu,\n getCardMenuItems,\n renderCard,\n enableDnD = false,\n onCardMove,\n emptyLabel = \"Nenhum item neste estágio\",\n addLabel = \"Adicionar\",\n className,\n}: KanbanProps) {\n // Lookup `cardId → columnId` pro hook resolver drop em cima de card específico.\n const cardColumnLookup = useMemo(() => {\n const map = new Map<string, string>();\n for (const c of cards) map.set(c.id, c.columnId);\n return map;\n }, [cards]);\n\n const {\n sensors,\n activeCardId,\n fromColumnId,\n overColumnId,\n overCardId,\n handleDragStart,\n handleDragOver,\n handleDragEnd,\n handleDragCancel,\n } = useKanbanDnD({ enabled: enableDnD, columns, cardColumnLookup, onCardMove });\n\n const activeCard = activeCardId ? cards.find((c) => c.id === activeCardId) ?? null : null;\n\n const boardContent = (\n <div className={s.board()}>\n {columns.map((col) => {\n const colCards = cards.filter((c) => c.columnId === col.id);\n const count = col.count ?? colCards.length;\n return (\n <KanbanColumnInner\n key={col.id}\n column={col}\n count={count}\n cards={colCards}\n selectedIds={selectedIds}\n onToggleSelect={onToggleSelect}\n openCardId={openCardId}\n onOpenCard={onOpenCard}\n onAddCard={onAddCard}\n onColumnMenu={onColumnMenu}\n getColumnMenuItems={getColumnMenuItems}\n onAddInFooter={onAddInFooter}\n hideFooterAdd={hideFooterAdd}\n onCardMenu={onCardMenu}\n getCardMenuItems={getCardMenuItems}\n renderCard={renderCard}\n emptyLabel={emptyLabel}\n addLabel={addLabel}\n enableDnD={enableDnD}\n activeCardId={activeCardId}\n fromColumnId={fromColumnId}\n overColumnId={overColumnId}\n overCardId={overCardId}\n />\n );\n })}\n </div>\n );\n\n return (\n <div className={cn(s.root(), className)} role=\"region\" aria-label=\"Quadro Kanban\">\n {enableDnD ? (\n <DndContext\n sensors={sensors}\n collisionDetection={closestCorners}\n onDragStart={handleDragStart}\n onDragOver={handleDragOver}\n onDragEnd={handleDragEnd}\n onDragCancel={handleDragCancel}\n >\n {boardContent}\n <DragOverlay dropAnimation={null}>\n {activeCard && (\n <div className={cn(s.card({ selected: false, open: false }), \"rotate-2 opacity-90 shadow-sh-lg\")}>\n <KanbanCardContent\n card={activeCard}\n selected={false}\n open={false}\n renderCard={renderCard}\n />\n </div>\n )}\n </DragOverlay>\n </DndContext>\n ) : (\n boardContent\n )}\n </div>\n );\n}\n\n/* ─────────────────────────────────────────────────────────────\n * KanbanColumnInner — uma coluna do board\n * ───────────────────────────────────────────────────────────── */\n\ntype KanbanColumnInnerProps = {\n column: KanbanColumn;\n count: number;\n cards: KanbanCardData[];\n enableDnD: boolean;\n activeCardId: string | null;\n fromColumnId: string | null;\n overColumnId: string | null;\n overCardId: string | null;\n} & Pick<\n KanbanProps,\n | \"selectedIds\"\n | \"onToggleSelect\"\n | \"openCardId\"\n | \"onOpenCard\"\n | \"onAddCard\"\n | \"onColumnMenu\"\n | \"getColumnMenuItems\"\n | \"onAddInFooter\"\n | \"hideFooterAdd\"\n | \"onCardMenu\"\n | \"getCardMenuItems\"\n | \"renderCard\"\n | \"emptyLabel\"\n | \"addLabel\"\n>;\n\nfunction KanbanColumnInner({\n column,\n count,\n cards,\n selectedIds,\n onToggleSelect,\n openCardId,\n onOpenCard,\n onAddCard,\n onColumnMenu,\n getColumnMenuItems,\n onAddInFooter,\n hideFooterAdd,\n onCardMenu,\n getCardMenuItems,\n renderCard,\n emptyLabel,\n addLabel,\n enableDnD,\n activeCardId,\n fromColumnId,\n overColumnId,\n overCardId,\n}: KanbanColumnInnerProps) {\n const canReceive = column.canReceiveDrop !== false;\n // Coluna body é droppable pra capturar drop em área vazia (fora de qualquer\n // card específico). Registrada mesmo quando inválida — captura `over` pra\n // cursor not-allowed; drop em si é bloqueado no hook via canReceiveDrop.\n const { setNodeRef } = useDroppable({\n id: droppableIdForColumn(column.id),\n disabled: !enableDnD,\n });\n\n const isDragInProgress = activeCardId !== null && fromColumnId !== column.id;\n const isOverColumn = overColumnId === column.id;\n\n // Feedback visual em 3 estados:\n // - Coluna inválida, drag em progresso: sempre dim (atenuada — está \"fora do jogo\")\n // - Coluna inválida + over: extra cursor not-allowed\n // - Coluna válida + over: highlight outline brand + placeholder localizado\n const showInvalidDim = enableDnD && isDragInProgress && !canReceive;\n const showInvalidOver = showInvalidDim && isOverColumn;\n const showAsTarget = enableDnD && isDragInProgress && isOverColumn && canReceive;\n\n // Posição do placeholder dentro da lista de cards:\n // - Se hover sobre card específico desta coluna → antes desse card\n // - Senão, se hover na área vazia da coluna válida → no fim\n const placeholderBeforeCardId =\n showAsTarget && overCardId && cards.some((c) => c.id === overCardId) ? overCardId : null;\n const showPlaceholderAtEnd = showAsTarget && !placeholderBeforeCardId;\n\n return (\n <section\n className={cn(\n s.column(),\n showInvalidDim && s.columnDropInvalidDimmed(),\n showInvalidOver && s.columnDropInvalidOver(),\n showAsTarget && s.columnDropTarget(),\n )}\n data-column-id={column.id}\n >\n {/* HEAD: dot + título + badge ←—— spacer ——→ + ⋯ */}\n <header className={s.columnHead()}>\n <span\n className={s.columnDot()}\n style={{ background: column.dotColor ?? \"var(--color-fg-muted)\" }}\n aria-hidden\n />\n <h3 className={s.columnTitle()}>{column.label}</h3>\n <span className={s.columnCount()}>{count}</span>\n\n <div className={s.columnActionsSpacer()}>\n {onAddCard && (\n <Button\n variant=\"ghost\"\n color=\"secondary\"\n size=\"icon-2xs\"\n aria-label={`Adicionar em ${column.label}`}\n title=\"Adicionar\"\n onClick={() => onAddCard(column.id)}\n >\n <Plus />\n </Button>\n )}\n {renderColumnMenu({ column, getColumnMenuItems, onColumnMenu })}\n </div>\n </header>\n\n {/* BODY: lista de cards (ou empty state) — droppable */}\n <div ref={setNodeRef} className={s.columnBody()}>\n {cards.length === 0 && !showAsTarget ? (\n <div className={s.columnEmpty()}>\n <Inbox className={s.columnEmptyIcon()} aria-hidden />\n <span>{emptyLabel}</span>\n </div>\n ) : (\n <>\n {cards.map((card) => (\n <Fragment key={card.id}>\n {/* Placeholder antes deste card se for o card hovered durante drag */}\n {placeholderBeforeCardId === card.id && <DropPlaceholder />}\n <KanbanCardOuter\n card={card}\n selected={selectedIds?.has(card.id) ?? false}\n open={openCardId === card.id}\n showCheckbox={Boolean(onToggleSelect)}\n onToggleSelect={onToggleSelect}\n onOpenCard={onOpenCard}\n onCardMenu={onCardMenu}\n getCardMenuItems={getCardMenuItems}\n renderCard={renderCard}\n enableDnD={enableDnD && column.canDragFrom !== false}\n isBeingDragged={activeCardId === card.id}\n />\n </Fragment>\n ))}\n {/* Placeholder no fim quando hover em área vazia da coluna válida */}\n {showPlaceholderAtEnd && <DropPlaceholder />}\n </>\n )}\n </div>\n\n {/* FOOTER: botão \"+ Adicionar\" dashed centered */}\n {!hideFooterAdd && onAddInFooter && (\n <button\n type=\"button\"\n className={s.columnAdd()}\n onClick={() => onAddInFooter(column.id)}\n >\n <Plus size={14} strokeWidth={2} /> {addLabel}\n </button>\n )}\n </section>\n );\n}\n\n/* ─────────────────────────────────────────────────────────────\n * Column menu trigger — auto via items OU callback manual\n * ───────────────────────────────────────────────────────────── */\n\nfunction renderColumnMenu({\n column,\n getColumnMenuItems,\n onColumnMenu,\n}: {\n column: KanbanColumn;\n getColumnMenuItems?: (column: KanbanColumn) => KanbanMenuItem[];\n onColumnMenu?: (columnId: string, anchor: HTMLElement) => void;\n}): ReactNode {\n if (getColumnMenuItems) {\n const items = getColumnMenuItems(column);\n if (items.length === 0) return null;\n return (\n <KanbanAutoMenu\n items={items}\n ariaLabel={`Menu de ${column.label}`}\n title=\"Mais ações\"\n />\n );\n }\n if (onColumnMenu) {\n return (\n <Button\n variant=\"ghost\"\n color=\"secondary\"\n size=\"icon-2xs\"\n aria-label={`Menu de ${column.label}`}\n title=\"Mais ações\"\n onClick={(e) => onColumnMenu(column.id, e.currentTarget)}\n >\n <MoreHorizontal />\n </Button>\n );\n }\n return null;\n}\n\n/* ─────────────────────────────────────────────────────────────\n * DropPlaceholder — indicador visual sutil de posição de inserção\n * ───────────────────────────────────────────────────────────── */\n\nfunction DropPlaceholder() {\n return (\n <div className={s.dropPlaceholder()} aria-hidden>\n <Plus />\n </div>\n );\n}\n\n/* ─────────────────────────────────────────────────────────────\n * KanbanCardOuter — wrapper draggable + droppable + estrutura visual\n * ───────────────────────────────────────────────────────────── */\n\ntype KanbanCardOuterProps = {\n card: KanbanCardData;\n selected: boolean;\n open: boolean;\n showCheckbox: boolean;\n enableDnD: boolean;\n isBeingDragged: boolean;\n onToggleSelect?: (cardId: string) => void;\n onOpenCard?: (cardId: string) => void;\n onCardMenu?: (cardId: string, anchor: HTMLElement) => void;\n getCardMenuItems?: (card: KanbanCardData) => KanbanMenuItem[];\n renderCard?: (params: KanbanRenderCardParams) => ReactNode;\n};\n\nfunction KanbanCardOuter({\n card,\n selected,\n open,\n showCheckbox,\n enableDnD,\n isBeingDragged,\n onToggleSelect,\n onOpenCard,\n onCardMenu,\n getCardMenuItems,\n renderCard,\n}: KanbanCardOuterProps) {\n const {\n setNodeRef: setDraggableRef,\n attributes,\n listeners,\n } = useDraggable({\n id: card.id,\n disabled: !enableDnD,\n data: { cardId: card.id, fromColumnId: card.columnId },\n });\n\n // Card também é droppable — necessário pra hook saber em qual card específico\n // o cursor está sobre durante drag (placeholder localizado antes deste card).\n const { setNodeRef: setDroppableRef } = useDroppable({\n id: droppableIdForCard(card.id),\n disabled: !enableDnD,\n });\n\n // Combina os 2 refs do dnd-kit num único callback ref aplicável ao DOM node\n const setNodeRef = (node: HTMLElement | null) => {\n setDraggableRef(node);\n setDroppableRef(node);\n };\n\n // NOTA: não aplicamos `transform` no card source — o `<DragOverlay>` no root\n // renderiza um clone flutuante seguindo o cursor. O source permanece no lugar\n // (com opacity baixa via `cardDragging`), evitando scroll horizontal indesejado\n // na coluna quando o card seria translatado pra fora do overflow-y-auto.\n\n const handleClick = () => onOpenCard?.(card.id);\n const handleKey = (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onOpenCard?.(card.id);\n }\n };\n const handleStop = (e: MouseEvent) => e.stopPropagation();\n\n // `useDraggable.attributes` já fornece role + tabIndex próprios — quando\n // DnD está ativo, usamos esses; quando inativo, fornecemos os nossos pra\n // manter o card focável e operável por teclado (Enter/Space abre detalhe).\n const a11yProps = enableDnD\n ? { ...attributes, ...listeners }\n : onOpenCard\n ? { role: \"button\" as const, tabIndex: 0 }\n : {};\n\n return (\n <article\n ref={enableDnD ? setNodeRef : undefined}\n className={cn(\n s.card({ selected, open, reserveCheck: showCheckbox }),\n isBeingDragged && s.cardDragging(),\n enableDnD && \"cursor-grab active:cursor-grabbing\",\n )}\n onClick={onOpenCard ? handleClick : undefined}\n onKeyDown={onOpenCard ? handleKey : undefined}\n data-card-id={card.id}\n {...a11yProps}\n >\n {showCheckbox && (\n <div className={s.cardCheck({ selected })} onClick={handleStop} onPointerDown={handleStop}>\n <Checkbox\n checked={selected}\n onCheckedChange={() => onToggleSelect?.(card.id)}\n aria-label=\"Selecionar card\"\n />\n </div>\n )}\n\n {renderCardMenu({ card, getCardMenuItems, onCardMenu })}\n\n <KanbanCardContent card={card} selected={selected} open={open} renderCard={renderCard} />\n </article>\n );\n}\n\n/* ─────────────────────────────────────────────────────────────\n * KanbanCardContent — miolo do card (default ou custom)\n * ───────────────────────────────────────────────────────────── */\n\nfunction KanbanCardContent({\n card,\n selected,\n open,\n renderCard,\n}: {\n card: KanbanCardData;\n selected: boolean;\n open: boolean;\n renderCard?: (params: KanbanRenderCardParams) => ReactNode;\n}) {\n if (renderCard) {\n return <Fragment>{renderCard({ card, selected, open })}</Fragment>;\n }\n\n return (\n <Fragment>\n {/* HEAD: avatar + título/subtítulo */}\n {(card.avatar || card.title || card.subtitle) && (\n <header className={s.cardHead()}>\n {card.avatar}\n <div className={s.cardTitleWrap()}>\n {card.title && <div className={s.cardTitle()}>{card.title}</div>}\n {card.subtitle && <div className={s.cardSubtitle()}>{card.subtitle}</div>}\n </div>\n </header>\n )}\n\n {card.description && <p className={s.cardDesc()}>{card.description}</p>}\n\n {(card.chip || card.value) && (\n <div className={s.cardMeta()}>\n {card.chip ?? <span />}\n {card.value && <span className={s.cardValue()}>{card.value}</span>}\n </div>\n )}\n\n {(card.footerLeft || card.footerRight) && (\n <footer className={s.cardFoot()}>\n {card.footerLeft ?? <span />}\n {card.footerRight ?? <span />}\n </footer>\n )}\n </Fragment>\n );\n}\n\n/* ─────────────────────────────────────────────────────────────\n * Card menu trigger — auto via items OU callback manual\n * ───────────────────────────────────────────────────────────── */\n\nfunction renderCardMenu({\n card,\n getCardMenuItems,\n onCardMenu,\n}: {\n card: KanbanCardData;\n getCardMenuItems?: (card: KanbanCardData) => KanbanMenuItem[];\n onCardMenu?: (cardId: string, anchor: HTMLElement) => void;\n}): ReactNode {\n const handleStop = (e: MouseEvent) => e.stopPropagation();\n\n if (getCardMenuItems) {\n const items = getCardMenuItems(card);\n if (items.length === 0) return null;\n return (\n <div className={s.cardMenuSlot()} onClick={handleStop} onPointerDown={handleStop}>\n <KanbanAutoMenu items={items} ariaLabel=\"Ações do card\" title=\"Ações\" />\n </div>\n );\n }\n if (onCardMenu) {\n return (\n <div className={s.cardMenuSlot()} onClick={handleStop} onPointerDown={handleStop}>\n <Button\n variant=\"ghost\"\n color=\"secondary\"\n size=\"icon-2xs\"\n aria-label=\"Ações do card\"\n title=\"Ações\"\n onClick={(e) => {\n e.stopPropagation();\n onCardMenu(card.id, e.currentTarget);\n }}\n >\n <MoreHorizontal />\n </Button>\n </div>\n );\n }\n return null;\n}\n\n/* ─────────────────────────────────────────────────────────────\n * KanbanAutoMenu — renderiza items padronizados via DropdownMenu DS\n * ───────────────────────────────────────────────────────────── */\n\nfunction KanbanAutoMenu({\n items,\n ariaLabel,\n title,\n}: {\n items: KanbanMenuItem[];\n ariaLabel: string;\n title: string;\n}) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n color=\"secondary\"\n size=\"icon-2xs\"\n aria-label={ariaLabel}\n title={title}\n >\n <MoreHorizontal />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" sideOffset={4}>\n {items.map((item, idx) => {\n if (item.separator) {\n return <DropdownMenuSeparator key={`sep-${idx}`} />;\n }\n return (\n <DropdownMenuItem\n key={item.label ?? idx}\n variant={item.destructive ? \"destructive\" : \"default\"}\n disabled={item.disabled}\n onSelect={() => item.onClick?.()}\n >\n {item.icon}\n {item.label}\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n","import { tv } from \"@/utils/tv\";\n\n/**\n * DataTable wrapper externo — agrupa toolbar + table + footer.\n * Visual: card com border + radius. O <Table> interno tem o próprio wrapper\n * com bg-bg-table; aqui o <div> raiz só posiciona toolbar e footer.\n */\nexport const dataTableStyles = tv({\n slots: {\n root: [\n // 16px (gp-2xl) entre toolbar e tabela\n \"flex flex-col w-full gap-gp-2xl\",\n ],\n toolbarWrap: [\n // Sem gap: chips ficam justapostos a toolbar header (sem separator)\n \"flex flex-col\",\n ],\n footerWrap: [\n \"flex-shrink-0\",\n ],\n overlay: [\n \"absolute inset-0 z-50 flex items-center justify-center\",\n \"bg-bg-canvas/80 backdrop-blur-sm\",\n ],\n emptyWrap: [\n \"flex flex-col items-center justify-center gap-gp-md\",\n \"min-h-[240px] p-pad-3xl\",\n \"text-fg-muted\",\n ],\n emptyTitle: [\n \"text-title-md text-fg-default\",\n ],\n emptyDescription: [\n \"text-paragraph-sm text-fg-muted text-center max-w-[360px]\",\n ],\n bulkBar: [\n \"fixed bottom-pad-3xl left-1/2 -translate-x-1/2 z-[var(--z-index-toast,600)]\",\n \"flex items-center gap-gp-lg\",\n \"py-pad-md px-pad-2xl rounded-radius-xl\",\n \"bg-bg-brand-subtle border border-border-brand text-fg-brand\",\n \"shadow-sh-lg\",\n ],\n },\n});\n","import { createContext, useContext } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type {\n TableDensity,\n ColumnPinned,\n} from \"../../Table\";\nimport type {\n DataTableColumnDef,\n PaginationModel,\n GridSelectionState,\n GridRowId,\n FilterModel,\n SortModel,\n} from \"../data-table.types\";\n\n/* ── Tipo do value do Context — readonly snapshot do estado ─────── */\n\nexport type DataTableContextValue<T = any> = {\n /** Dados originais sem processar (filter/sort/paginate ficam no processor). */\n rows: T[];\n /** Colunas efetivas (já filtradas por visibility e ordenadas por columnOrder). */\n effectiveColumns: DataTableColumnDef<T>[];\n /** Widths em px por field. */\n columnWidths: Record<string, number>;\n /** Sticky offsets por field. */\n stickyOffsets: Record<string, number>;\n /** Order atual dos fields (filtrada por visibilidade). */\n columnOrder: string[];\n /** Set de fields hidden. */\n hiddenColumns: Set<string>;\n /** Map de pinned por field. */\n pinnedColumns: Record<string, ColumnPinned>;\n\n /** Multi-sort: array de criterios (primeiro = prioridade maior). */\n sortModel: SortModel[];\n /** Pagination state. */\n paginationModel: PaginationModel;\n /** Selection state. */\n selection: {\n state: GridSelectionState;\n isRowSelected: (row: T) => boolean;\n selectedCount: number;\n };\n /** Density state. */\n density: TableDensity;\n /** Search state. */\n search: string;\n /** Filter model. */\n filterModel: FilterModel;\n\n /** getRowId utility. */\n getRowId: (row: T) => GridRowId;\n};\n\nconst DataTableContext = createContext<DataTableContextValue | null>(null);\n\nexport function DataTableProvider({\n value,\n children,\n}: {\n value: DataTableContextValue;\n children: ReactNode;\n}) {\n return (\n <DataTableContext.Provider value={value}>\n {children}\n </DataTableContext.Provider>\n );\n}\n\nexport function useDataTableContext<T = any>(): DataTableContextValue<T> {\n const ctx = useContext(DataTableContext);\n if (!ctx) {\n throw new Error(\"useDataTableContext must be used inside <DataTable>\");\n }\n return ctx as DataTableContextValue<T>;\n}\n","import type { ColumnTypeDefinition, ColumnTypeId } from \"./column-types.types\";\n\n/**\n * Registry Singleton de tipos de coluna do DataTable.\n *\n * Permite o consumer registrar tipos customizados sem mudar o nucleo.\n * Fallback automatico pra `text` quando tipo desconhecido eh requisitado.\n *\n * Uso:\n * columnTypeRegistry.register(myCustomType);\n * const def = columnTypeRegistry.get(\"currency\");\n */\nclass ColumnTypeRegistry {\n private types = new Map<string, ColumnTypeDefinition>();\n\n register(definition: ColumnTypeDefinition): void {\n if (this.types.has(definition.type)) {\n // Não throw — pra hot reload em dev e re-import incidental. Apenas warn.\n // Em produção, console.warn é silencioso por default mas detectável.\n console.warn(\n `[columnTypeRegistry] type \"${definition.type}\" já registrado — override silencioso. Verifique imports duplicados.`,\n );\n }\n this.types.set(definition.type, definition);\n }\n\n registerMany(definitions: ColumnTypeDefinition[]): void {\n for (const d of definitions) this.register(d);\n }\n\n get(typeId: ColumnTypeId | undefined): ColumnTypeDefinition {\n if (typeId && this.types.has(typeId)) {\n return this.types.get(typeId)!;\n }\n const fallback = this.types.get(\"text\");\n if (!fallback) {\n throw new Error(\n \"ColumnTypeRegistry: tipo 'text' nao registrado (default fallback ausente)\",\n );\n }\n return fallback;\n }\n\n has(typeId: string): boolean {\n return this.types.has(typeId);\n }\n\n list(): ColumnTypeDefinition[] {\n return Array.from(this.types.values());\n }\n}\n\nexport const columnTypeRegistry = new ColumnTypeRegistry();\n","import { cn } from \"@/lib/utils\";\n\n/**\n * Helpers compartilhados pelos triggers/inputs do modal Filtros (advanced).\n *\n * Sincronizados com `FIELD_BASE` + `INPUT_FIELD` do FilterPopover pra que\n * Campo/Operador/Valor tenham altura, padding, radius, bg, border e tipografia\n * IDÊNTICOS — sem diferença visual entre tipos (date, text, select, etc).\n *\n * Altura: form-md (36px). Radius: md. Padding: pad-xl. Text: 13px.\n *\n * Use:\n * - `FILTER_FIELD_CLASS` em `<button>` ou divs construídos from-scratch\n * (date/tags/multiSelect triggers que precisam estrutura própria).\n * - `FILTER_FIELD_SIZE` em primitives DS (`<Input>`, `<SelectTrigger>`) que\n * já têm bg/border próprios — só sobrescreve altura+radius pra match.\n */\n\n/** Trigger completo from-scratch — bg, border, foco, tudo. */\nexport const FILTER_FIELD_CLASS = cn(\n // Box-model\n \"flex min-h-form-md h-form-md w-full items-center justify-between gap-gp-md\",\n \"rounded-radius-md px-pad-xl\",\n // Tipografia\n \"text-[13px]\",\n // Visual\n \"bg-bg-input dark:bg-bg-muted\",\n \"border border-border-input text-fg-default\",\n // Estado\n \"outline-none transition-[border-color,box-shadow,background-color]\",\n \"focus-visible:border-border-brand focus-visible:shadow-sh-ring\",\n \"data-[state=open]:border-border-brand data-[state=open]:shadow-sh-ring\",\n);\n\n/** Só sizing override — usado em primitives shadcn que já têm visual próprio\n * mas vêm com altura default form-lg (40px). Garante match com FIELD_BASE. */\nexport const FILTER_FIELD_SIZE = cn(\n \"min-h-form-md h-form-md rounded-radius-md\",\n);\n","import { Type } from \"lucide-react\";\nimport { Input } from \"../../../../shadcn/input\";\nimport { FILTER_FIELD_SIZE } from \"../_filter-field\";\nimport type { ColumnTypeDefinition } from \"../column-types.types\";\n\nfunction normalize(s: unknown): string {\n if (s == null) return \"\";\n return String(s)\n .toLowerCase()\n .normalize(\"NFD\")\n .replace(/[̀-ͯ]/g, \"\");\n}\n\nexport const TextColumnType: ColumnTypeDefinition = {\n type: \"text\",\n operators: [\n { id: \"contains\", label: \"contém\" },\n { id: \"equals\", label: \"é\" },\n { id: \"neq\", label: \"não é\" },\n ],\n renderFilterInput: ({ value, onChange, placeholder }) => (\n <Input\n type=\"text\"\n size=\"sm\"\n className={FILTER_FIELD_SIZE}\n value={(value as string) ?? \"\"}\n onChange={(e) => onChange(e.target.value)}\n placeholder={placeholder ?? \"Valor...\"}\n />\n ),\n renderFastFilterInput: ({ value, onChange, options }) => (\n <Input\n type=\"text\"\n value={(value as string) ?? \"\"}\n onChange={(e) => onChange(e.target.value)}\n placeholder={options?.[0]?.label ?? \"Buscar...\"}\n autoFocus\n />\n ),\n matchesFilter: (cellValue, filterValue, operator) => {\n const cell = normalize(cellValue);\n const filter = normalize(filterValue);\n if (operator === \"contains\") return cell.includes(filter);\n if (operator === \"equals\") return cell === filter;\n if (operator === \"neq\") return cell !== filter;\n return null;\n },\n\n /* G.2 slots — text não precisa renderCell custom (raw value já basta). */\n formatValue: (v) => (v == null ? \"\" : String(v)),\n defaultAlign: \"left\",\n defaultSortable: true,\n defaultIcon: Type,\n};\n","import { Hash } from \"lucide-react\";\nimport { Input } from \"../../../../shadcn/input\";\nimport { FILTER_FIELD_SIZE } from \"../_filter-field\";\nimport type { ColumnTypeDefinition } from \"../column-types.types\";\n\nfunction toNum(v: unknown): number | null {\n if (v == null || v === \"\") return null;\n const n = Number(v);\n return Number.isFinite(n) ? n : null;\n}\n\nexport const NumberColumnType: ColumnTypeDefinition = {\n type: \"number\",\n operators: [\n { id: \"equals\", label: \"=\" },\n { id: \"gt\", label: \">\" },\n { id: \"lt\", label: \"<\" },\n { id: \"neq\", label: \"≠\" },\n ],\n renderFilterInput: ({ value, onChange, placeholder }) => (\n <Input\n type=\"number\"\n size=\"sm\"\n className={FILTER_FIELD_SIZE}\n value={(value as number) ?? \"\"}\n onChange={(e) => onChange(e.target.value === \"\" ? \"\" : Number(e.target.value))}\n placeholder={placeholder ?? \"0\"}\n />\n ),\n renderFastFilterInput: ({ value, onChange }) => (\n <Input\n type=\"number\"\n value={(value as number) ?? \"\"}\n onChange={(e) => onChange(e.target.value === \"\" ? \"\" : Number(e.target.value))}\n placeholder=\"0\"\n autoFocus\n />\n ),\n matchesFilter: (cellValue, filterValue, operator) => {\n const cell = toNum(cellValue);\n const filter = toNum(filterValue);\n if (cell === null || filter === null) return false;\n if (operator === \"equals\") return cell === filter;\n if (operator === \"neq\") return cell !== filter;\n if (operator === \"gt\") return cell > filter;\n if (operator === \"lt\") return cell < filter;\n return null;\n },\n\n /* G.2 — number alinhado à direita, formato locale-aware */\n renderCell: ({ value }) => {\n const n = toNum(value);\n if (n === null) return null;\n return <span className=\"tabular-nums\">{n.toLocaleString(\"pt-BR\")}</span>;\n },\n formatValue: (v) => {\n const n = toNum(v);\n return n === null ? \"\" : n.toLocaleString(\"pt-BR\");\n },\n defaultAlign: \"right\",\n defaultWidth: 110,\n defaultSortable: true,\n defaultIcon: Hash,\n};\n","import * as React from \"react\"\nimport { ChevronLeftIcon, ChevronRightIcon } from \"lucide-react\"\nimport { DayPicker, getDefaultClassNames, type DayButton } from \"react-day-picker\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n captionLayout = \"label\",\n components,\n ...props\n}: React.ComponentProps<typeof DayPicker>) {\n const defaultClassNames = getDefaultClassNames()\n\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n className={cn(\n \"group/calendar bg-transparent p-0 [--cell-size:2.5rem]\",\n className\n )}\n captionLayout={captionLayout}\n classNames={{\n root: cn(\"w-full\", defaultClassNames.root),\n months: cn(\"relative flex flex-col gap-gp-2xl sm:flex-row sm:gap-gp-4xl\", defaultClassNames.months),\n month: cn(\"flex w-full flex-col gap-gp-2xl\", defaultClassNames.month),\n nav: cn(\n \"absolute inset-x-0 top-0 flex w-full items-center justify-between\",\n defaultClassNames.nav\n ),\n button_previous: cn(\n \"inline-flex items-center justify-center size-[--cell-size] rounded-full text-fg-muted hover:bg-bg-muted transition-colors select-none aria-disabled:opacity-30\",\n defaultClassNames.button_previous\n ),\n button_next: cn(\n \"inline-flex items-center justify-center size-[--cell-size] rounded-full text-fg-muted hover:bg-bg-muted transition-colors select-none aria-disabled:opacity-30\",\n defaultClassNames.button_next\n ),\n month_caption: cn(\n \"flex h-[--cell-size] w-full items-center justify-center px-[--cell-size]\",\n defaultClassNames.month_caption\n ),\n caption_label: cn(\n \"text-label-sm font-semibold select-none\",\n captionLayout === \"dropdown\" ? \"hidden\" : \"\",\n defaultClassNames.caption_label\n ),\n dropdowns: cn(\n \"flex items-center gap-gp-md\",\n defaultClassNames.dropdowns\n ),\n dropdown: cn(\n \"cursor-pointer appearance-none bg-transparent text-label-sm font-semibold text-fg-default outline-none\",\n defaultClassNames.dropdown\n ),\n months_dropdown: cn(\"\", defaultClassNames.months_dropdown),\n years_dropdown: cn(\"\", defaultClassNames.years_dropdown),\n table: \"w-full border-collapse\",\n weekdays: cn(\"flex\", defaultClassNames.weekdays),\n weekday: cn(\n \"flex-1 min-w-8 max-w-12 text-[0.8rem] font-normal text-fg-muted select-none text-center\",\n defaultClassNames.weekday\n ),\n week: cn(\"mt-gp-md flex w-full\", defaultClassNames.week),\n day: cn(\n \"group/day relative aspect-square min-w-8 max-w-12 p-0 text-center select-none\",\n defaultClassNames.day\n ),\n range_start: cn(\"rounded-l-full\", defaultClassNames.range_start),\n range_end: cn(\"rounded-r-full\", defaultClassNames.range_end),\n range_middle: cn(\"\", defaultClassNames.range_middle),\n today: cn(\"\", defaultClassNames.today),\n outside: cn(\n \"text-fg-subtle opacity-40\",\n defaultClassNames.outside\n ),\n disabled: cn(\"text-fg-disabled opacity-50\", defaultClassNames.disabled),\n hidden: cn(\"invisible\", defaultClassNames.hidden),\n ...classNames,\n }}\n components={{\n Root: ({ className: rootCn, rootRef, ...rootProps }) => (\n <div data-slot=\"calendar\" ref={rootRef} className={cn(rootCn)} {...rootProps} />\n ),\n Chevron: ({ orientation }) => {\n if (orientation === \"left\") return <ChevronLeftIcon className=\"size-4\" />\n return <ChevronRightIcon className=\"size-4\" />\n },\n DayButton: CalendarDayButton,\n ...components,\n }}\n {...props}\n />\n )\n}\n\nfunction CalendarDayButton({\n className,\n day,\n modifiers,\n ...props\n}: React.ComponentProps<typeof DayButton>) {\n const ref = React.useRef<HTMLButtonElement>(null)\n React.useEffect(() => {\n if (modifiers.focused) ref.current?.focus()\n }, [modifiers.focused])\n\n const isRangeStart = modifiers.range_start;\n const isRangeEnd = modifiers.range_end;\n const isRangeMiddle = modifiers.range_middle;\n const isSingleSelected =\n modifiers.selected && !isRangeStart && !isRangeEnd && !isRangeMiddle;\n\n return (\n <button\n ref={ref}\n type=\"button\"\n data-selected-single={isSingleSelected}\n data-range-start={isRangeStart || undefined}\n data-range-end={isRangeEnd || undefined}\n data-range-middle={isRangeMiddle || undefined}\n className={cn(\n \"relative flex aspect-square w-full items-center justify-center text-paragraph-sm font-normal leading-none outline-none transition-colors\",\n\n // Default shape\n \"rounded-full\",\n\n // Hover\n \"hover:bg-bg-muted\",\n\n // Single selected\n \"data-[selected-single=true]:bg-bg-brand data-[selected-single=true]:text-fg-on-brand data-[selected-single=true]:hover:bg-bg-brand\",\n\n // Range start\n \"data-[range-start]:bg-bg-brand data-[range-start]:text-fg-on-brand data-[range-start]:rounded-full data-[range-start]:hover:bg-bg-brand\",\n\n // Range end\n \"data-[range-end]:bg-bg-brand data-[range-end]:text-fg-on-brand data-[range-end]:rounded-full data-[range-end]:hover:bg-bg-brand\",\n\n // Range middle\n \"data-[range-middle]:bg-bg-brand-subtle data-[range-middle]:text-fg-brand data-[range-middle]:rounded-none\",\n\n // Today\n modifiers.today && !isSingleSelected && !isRangeStart && !isRangeEnd && !isRangeMiddle &&\n \"bg-bg-brand text-fg-on-brand font-semibold hover:bg-bg-brand\",\n\n // Outside\n modifiers.outside && \"text-fg-subtle opacity-40 hover:bg-transparent\",\n\n // Disabled\n modifiers.disabled && \"opacity-30 pointer-events-none\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Calendar, CalendarDayButton }\n","import { Calendar as CalendarIcon } from \"lucide-react\";\nimport { Calendar } from \"../../../../shadcn/calendar\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../../../../shadcn/popover\";\nimport { FILTER_FIELD_CLASS } from \"../_filter-field\";\nimport type { ColumnTypeDefinition } from \"../column-types.types\";\n\n/* ── Helpers ─────────────────────────────────────────────────────── */\n\nfunction toDateMs(v: unknown): number | null {\n if (v == null || v === \"\") return null;\n if (typeof v === \"number\") return v;\n if (v instanceof Date) return v.getTime();\n const d = new Date(String(v));\n return Number.isNaN(d.getTime()) ? null : d.getTime();\n}\n\nfunction dayStart(ms: number): number {\n const d = new Date(ms);\n d.setHours(0, 0, 0, 0);\n return d.getTime();\n}\n\n/** Converte qualquer valor em Date pro Calendar (ou undefined). */\nfunction toDate(v: unknown): Date | undefined {\n const ms = toDateMs(v);\n return ms == null ? undefined : new Date(ms);\n}\n\n/** Serializa Date pra ISO string (sem hora — só \"YYYY-MM-DD\" estável). */\nfunction toIsoDate(d: Date | undefined | null): string | null {\n if (!d) return null;\n const y = d.getFullYear();\n const m = String(d.getMonth() + 1).padStart(2, \"0\");\n const day = String(d.getDate()).padStart(2, \"0\");\n return `${y}-${m}-${day}`;\n}\n\nconst ptBrShort = new Intl.DateTimeFormat(\"pt-BR\", {\n day: \"2-digit\",\n month: \"short\",\n});\n\nfunction formatShort(v: unknown): string {\n const d = toDate(v);\n if (!d) return \"\";\n return ptBrShort.format(d).replace(\".\", \"\");\n}\n\n/* ── Column type ─────────────────────────────────────────────────── */\n\nexport const DateColumnType: ColumnTypeDefinition = {\n type: \"date\",\n operators: [\n { id: \"equals\", label: \"é\" },\n { id: \"gt\", label: \"depois de\" },\n { id: \"lt\", label: \"antes de\" },\n { id: \"between\", label: \"entre\" },\n ],\n /** Modal Filtros (advanced): trigger compacto que abre Calendar em popover.\n * Trigger mostra valor formatado (\"15 fev\" ou \"15 fev → 28 fev\") ou placeholder. */\n renderFilterInput: ({ value, onChange, operator }) => {\n const isRange = operator === \"between\";\n const displayValue = (() => {\n if (isRange && Array.isArray(value)) {\n const from = formatShort(value[0]);\n const to = formatShort(value[1]);\n if (from && to) return `${from} → ${to}`;\n if (from) return `desde ${from}`;\n if (to) return `até ${to}`;\n return \"\";\n }\n return formatShort(value);\n })();\n return (\n <Popover>\n <PopoverTrigger asChild>\n <button type=\"button\" className={FILTER_FIELD_CLASS}>\n <span className={displayValue ? \"truncate\" : \"text-fg-muted opacity-70 truncate\"}>\n {displayValue || (isRange ? \"Selecione período\" : \"Selecione data\")}\n </span>\n <CalendarIcon className=\"size-icon-xs text-fg-muted shrink-0\" />\n </button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"p-pad-md w-auto\">\n {isRange ? (\n <Calendar\n mode=\"range\"\n selected={\n Array.isArray(value)\n ? { from: toDate(value[0]), to: toDate(value[1]) }\n : { from: undefined, to: undefined }\n }\n onSelect={(r) => {\n onChange([\n toIsoDate(r?.from ?? null),\n toIsoDate(r?.to ?? null),\n ]);\n }}\n />\n ) : (\n <Calendar\n mode=\"single\"\n selected={toDate(value)}\n onSelect={(d) => onChange(toIsoDate(d ?? null))}\n />\n )}\n </PopoverContent>\n </Popover>\n );\n },\n /** Chip popover (fast filter): mesmo Calendar. Se valor for tuple → range mode. */\n renderFastFilterInput: ({ value, onChange }) => {\n const isRange = Array.isArray(value);\n if (isRange) {\n const range = {\n from: toDate(value[0]),\n to: toDate(value[1]),\n };\n return (\n <div className=\"p-pad-md\">\n <Calendar\n mode=\"range\"\n selected={range}\n onSelect={(r) => {\n onChange([\n toIsoDate(r?.from ?? null),\n toIsoDate(r?.to ?? null),\n ]);\n }}\n />\n </div>\n );\n }\n return (\n <div className=\"p-pad-md\">\n <Calendar\n mode=\"single\"\n selected={toDate(value)}\n onSelect={(d) => onChange(toIsoDate(d ?? null))}\n />\n </div>\n );\n },\n /** Formato curto pro chip — \"15 jan\" ou \"15 jan → 28 jan\". */\n renderChipValue: (value) => {\n if (Array.isArray(value)) {\n const from = formatShort(value[0]);\n const to = formatShort(value[1]);\n if (from && to) return `${from} → ${to}`;\n if (from) return `desde ${from}`;\n if (to) return `até ${to}`;\n return \"\";\n }\n return formatShort(value);\n },\n /** Filtro runtime — between aceita tuple [start, end] (inclusive em ambos). */\n matchesFilter: (cellValue, filterValue, operator) => {\n const cell = toDateMs(cellValue);\n if (cell === null) return false;\n const cellDay = dayStart(cell);\n\n if (operator === \"between\") {\n if (!Array.isArray(filterValue)) return null;\n const startMs = toDateMs(filterValue[0]);\n const endMs = toDateMs(filterValue[1]);\n // Range parcial (só um lado preenchido) = comportamento gt ou lt\n if (startMs !== null && endMs !== null) {\n return cellDay >= dayStart(startMs) && cellDay <= dayStart(endMs);\n }\n if (startMs !== null) return cellDay >= dayStart(startMs);\n if (endMs !== null) return cellDay <= dayStart(endMs);\n return false;\n }\n\n const filter = toDateMs(filterValue);\n if (filter === null) return false;\n const filterDay = dayStart(filter);\n if (operator === \"equals\") return cellDay === filterDay;\n if (operator === \"gt\") return cellDay > filterDay;\n if (operator === \"lt\") return cellDay < filterDay;\n return null;\n },\n\n /* G.2 slots */\n renderCell: ({ value }) => (\n <span className=\"text-fg-muted tabular-nums\">{formatShort(value)}</span>\n ),\n formatValue: (v) => formatShort(v),\n defaultAlign: \"left\",\n defaultWidth: 130,\n defaultSortable: true,\n defaultIcon: CalendarIcon,\n};\n","import {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../../../shadcn/select\";\nimport { FILTER_FIELD_SIZE } from \"../_filter-field\";\nimport type { ColumnTypeDefinition } from \"../column-types.types\";\n\nexport const SelectColumnType: ColumnTypeDefinition = {\n type: \"select\",\n operators: [\n { id: \"equals\", label: \"é\" },\n { id: \"neq\", label: \"não é\" },\n ],\n renderFilterInput: ({ value, onChange, options }) => (\n <Select\n value={(value as string) ?? \"\"}\n onValueChange={(v) => onChange(v)}\n >\n <SelectTrigger className={FILTER_FIELD_SIZE}>\n <SelectValue placeholder=\"Selecionar...\" />\n </SelectTrigger>\n <SelectContent>\n {options?.map((opt) => (\n <SelectItem key={String(opt.value)} value={String(opt.value)}>\n {opt.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ),\n renderFastFilterInput: ({ value, onChange, options, onClose }) => (\n <Select\n value={(value as string) ?? \"\"}\n onValueChange={(v) => {\n onChange(v);\n onClose?.();\n }}\n open\n >\n <SelectTrigger className=\"sr-only\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {options?.map((opt) => (\n <SelectItem key={String(opt.value)} value={String(opt.value)}>\n {opt.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ),\n matchesFilter: (cellValue, filterValue, operator) => {\n const cell = cellValue == null ? \"\" : String(cellValue);\n const filter = filterValue == null ? \"\" : String(filterValue);\n if (operator === \"equals\") return cell === filter;\n if (operator === \"neq\") return cell !== filter;\n return null;\n },\n};\n","import type { ReactNode } from \"react\";\nimport { ChevronDown } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { Checkbox } from \"../../../../shadcn/checkbox\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../../../../shadcn/popover\";\nimport { FILTER_FIELD_CLASS } from \"../_filter-field\";\nimport type {\n ColumnTypeDefinition,\n FastFilterInputProps,\n FilterInputProps,\n} from \"../column-types.types\";\n\n/**\n * Render do dropdown multiselect — lista checkboxes com toggle.\n * Usado em ambos os contextos (modal advanced + fast filter popover).\n */\nfunction MultiSelectDropdown({\n value,\n onChange,\n options = [],\n renderOption,\n}: FastFilterInputProps) {\n const selected = Array.isArray(value) ? (value as Array<string | number>) : [];\n const toggle = (val: string | number) => {\n const set = new Set(selected.map(String));\n if (set.has(String(val))) set.delete(String(val));\n else set.add(String(val));\n onChange(Array.from(set));\n };\n\n return (\n <div className=\"flex flex-col gap-gp-3xs p-pad-2xs min-w-[200px]\">\n {options.length === 0 && (\n <p className=\"text-paragraph-xs text-fg-muted px-pad-md py-pad-sm\">\n Sem opções disponíveis\n </p>\n )}\n {options.map((opt) => {\n const isChecked = selected.map(String).includes(String(opt.value));\n return (\n <label\n key={String(opt.value)}\n className={cn(\n \"flex items-center gap-gp-md w-full\",\n \"px-pad-md py-pad-sm rounded-radius-md\",\n \"text-paragraph-sm text-fg-default text-left cursor-pointer\",\n \"hover:bg-bg-muted focus-within:bg-bg-muted\",\n \"transition-colors duration-100\",\n )}\n >\n <Checkbox\n checked={isChecked}\n onCheckedChange={() => toggle(opt.value)}\n aria-label={opt.label}\n className=\"shrink-0\"\n />\n <span className=\"flex-1 min-w-0 truncate\">\n {renderOption ? renderOption(opt) : (opt.label as ReactNode)}\n </span>\n </label>\n );\n })}\n </div>\n );\n}\n\n/** Trigger compacto + popover pra uso no modal advanced — economiza espaço\n * comparado a renderizar a lista de checkboxes inline. */\nfunction MultiSelectFieldDropdown(props: FilterInputProps) {\n const { value, options = [] } = props;\n const selected = Array.isArray(value) ? (value as Array<string | number>) : [];\n const labels = selected.map((v) => {\n const opt = options.find((o) => String(o.value) === String(v));\n return opt?.label ?? String(v);\n });\n const display =\n labels.length === 0\n ? \"\"\n : labels.length <= 2\n ? labels.join(\", \")\n : `${labels.length} selecionados`;\n return (\n <Popover>\n <PopoverTrigger asChild>\n <button type=\"button\" className={FILTER_FIELD_CLASS}>\n <span className={display ? \"truncate\" : \"text-fg-muted opacity-70 truncate\"}>\n {display || \"Selecione...\"}\n </span>\n <ChevronDown className=\"size-icon-xs text-fg-muted shrink-0\" />\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n className=\"p-0 w-[var(--radix-popover-trigger-width)] min-w-[200px]\"\n >\n <MultiSelectDropdown {...props} />\n </PopoverContent>\n </Popover>\n );\n}\n\nexport const MultiSelectColumnType: ColumnTypeDefinition = {\n type: \"multiSelect\",\n operators: [\n { id: \"isAnyOf\", label: \"é um de\" },\n { id: \"isNoneOf\", label: \"não é nenhum de\" },\n ],\n /** Modal advanced: trigger + popover (compacto). */\n renderFilterInput: (props) => <MultiSelectFieldDropdown {...props} />,\n /** Chip fast filter: já está dentro de um popover, renderiza inline. */\n renderFastFilterInput: (props) => <MultiSelectDropdown {...props} />,\n matchesFilter: (cellValue, filterValue, operator) => {\n const cell = cellValue == null ? \"\" : String(cellValue);\n const arr = Array.isArray(filterValue)\n ? filterValue.map(String)\n : filterValue == null\n ? []\n : [String(filterValue)];\n if (arr.length === 0) return true; // filtro vazio = passa tudo\n if (operator === \"isAnyOf\" || operator === \"equals\") {\n return arr.includes(cell);\n }\n if (operator === \"isNoneOf\" || operator === \"neq\") {\n return !arr.includes(cell);\n }\n return null;\n },\n renderChipValue: (value, options) => {\n const arr = Array.isArray(value)\n ? (value as Array<string | number>)\n : value == null\n ? []\n : [value as string | number];\n if (arr.length === 0) return null;\n const labelOf = (v: string | number) =>\n options?.find((o) => String(o.value) === String(v))?.label ?? String(v);\n if (arr.length === 1) return labelOf(arr[0]);\n if (arr.length === 2) return `${labelOf(arr[0])}, ${labelOf(arr[1])}`;\n return `${arr.length} selecionados`;\n },\n};\n","import { Check, X, ToggleLeft } from \"lucide-react\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../../../shadcn/select\";\nimport { FILTER_FIELD_SIZE } from \"../_filter-field\";\nimport type { ColumnTypeDefinition } from \"../column-types.types\";\n\nfunction toBool(v: unknown): boolean | null {\n if (v === true || v === \"true\" || v === 1 || v === \"1\") return true;\n if (v === false || v === \"false\" || v === 0 || v === \"0\") return false;\n return null;\n}\n\nexport const BooleanColumnType: ColumnTypeDefinition = {\n type: \"boolean\",\n operators: [{ id: \"equals\", label: \"é\" }],\n renderFilterInput: ({ value, onChange }) => (\n <Select\n value={(value as string) ?? \"\"}\n onValueChange={(v) => onChange(v === \"true\")}\n >\n <SelectTrigger className={FILTER_FIELD_SIZE}>\n <SelectValue placeholder=\"Selecionar...\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"true\">Sim</SelectItem>\n <SelectItem value=\"false\">Não</SelectItem>\n </SelectContent>\n </Select>\n ),\n renderFastFilterInput: ({ value, onChange, onClose }) => (\n <Select\n value={(value as string) ?? \"\"}\n onValueChange={(v) => {\n onChange(v === \"true\");\n onClose?.();\n }}\n open\n >\n <SelectTrigger className=\"sr-only\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"true\">Sim</SelectItem>\n <SelectItem value=\"false\">Não</SelectItem>\n </SelectContent>\n </Select>\n ),\n matchesFilter: (cellValue, filterValue, operator) => {\n const cell = toBool(cellValue);\n const filter = toBool(filterValue);\n if (cell === null || filter === null) return false;\n if (operator === \"equals\") return cell === filter;\n return null;\n },\n renderChipValue: (value) => (value ? \"Sim\" : \"Não\"),\n\n /* G.2 — render como ícone Check (verde) ou X (cinza). */\n renderCell: ({ value }) => {\n const b = toBool(value);\n if (b === null) return null;\n return b ? (\n <Check className=\"size-icon-sm text-fg-success\" aria-label=\"Sim\" />\n ) : (\n <X className=\"size-icon-sm text-fg-muted\" aria-label=\"Não\" />\n );\n },\n formatValue: (v) => {\n const b = toBool(v);\n if (b === null) return \"\";\n return b ? \"Sim\" : \"Não\";\n },\n defaultAlign: \"center\",\n defaultWidth: 80,\n defaultSortable: true,\n defaultIcon: ToggleLeft,\n};\n","import { DollarSign } from \"lucide-react\";\nimport { Input } from \"../../../../shadcn/input\";\nimport { FILTER_FIELD_SIZE } from \"../_filter-field\";\nimport type { ColumnTypeDefinition } from \"../column-types.types\";\n\n/** typeOptions esperadas (opcional): { currency?: \"BRL\" | \"USD\" | \"EUR\" | string, locale?: string } */\ntype CurrencyTypeOptions = {\n currency?: string;\n locale?: string;\n};\n\nfunction toCurrency(value: unknown, opts?: CurrencyTypeOptions): string {\n if (value == null || value === \"\" || Number.isNaN(Number(value))) return \"\";\n const num = Number(value);\n const locale = opts?.locale ?? \"pt-BR\";\n const currency = opts?.currency ?? \"BRL\";\n try {\n return new Intl.NumberFormat(locale, {\n style: \"currency\",\n currency,\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n }).format(num);\n } catch {\n return num.toFixed(2);\n }\n}\n\nfunction toNumber(v: unknown): number | null {\n if (v == null || v === \"\") return null;\n const n = Number(v);\n return Number.isNaN(n) ? null : n;\n}\n\nexport const CurrencyColumnType: ColumnTypeDefinition = {\n type: \"currency\",\n operators: [\n { id: \"equals\", label: \"é\" },\n { id: \"gt\", label: \"maior que\" },\n { id: \"lt\", label: \"menor que\" },\n { id: \"between\", label: \"entre\" },\n ],\n renderFilterInput: ({ value, onChange, operator }) => {\n if (operator === \"between\") {\n const arr = Array.isArray(value) ? value : [null, null];\n const minVal = toNumber(arr[0]);\n const maxVal = toNumber(arr[1]);\n return (\n <div className=\"flex items-center gap-gp-md\">\n <Input\n type=\"number\"\n size=\"sm\"\n className={FILTER_FIELD_SIZE}\n placeholder=\"min\"\n value={minVal == null ? \"\" : String(minVal)}\n onChange={(e) => {\n const v = e.target.value === \"\" ? null : Number(e.target.value);\n onChange([v, maxVal] as [number | null, number | null]);\n }}\n />\n <span className=\"text-fg-muted\">–</span>\n <Input\n type=\"number\"\n size=\"sm\"\n className={FILTER_FIELD_SIZE}\n placeholder=\"max\"\n value={maxVal == null ? \"\" : String(maxVal)}\n onChange={(e) => {\n const v = e.target.value === \"\" ? null : Number(e.target.value);\n onChange([minVal, v] as [number | null, number | null]);\n }}\n />\n </div>\n );\n }\n return (\n <Input\n type=\"number\"\n size=\"sm\"\n className={FILTER_FIELD_SIZE}\n value={value == null ? \"\" : String(value)}\n onChange={(e) => onChange(e.target.value === \"\" ? null : Number(e.target.value))}\n placeholder=\"0,00\"\n />\n );\n },\n renderFastFilterInput: ({ value, onChange }) => (\n <div className=\"p-pad-md\">\n <Input\n type=\"number\"\n value={value == null ? \"\" : String(value)}\n onChange={(e) => onChange(e.target.value === \"\" ? null : Number(e.target.value))}\n placeholder=\"0,00\"\n autoFocus\n />\n </div>\n ),\n matchesFilter: (cellValue, filterValue, operator) => {\n const cell = toNumber(cellValue);\n if (cell === null) return false;\n if (operator === \"between\") {\n if (!Array.isArray(filterValue)) return null;\n const min = toNumber(filterValue[0]);\n const max = toNumber(filterValue[1]);\n if (min !== null && max !== null) return cell >= min && cell <= max;\n if (min !== null) return cell >= min;\n if (max !== null) return cell <= max;\n return false;\n }\n const filter = toNumber(filterValue);\n if (filter === null) return false;\n if (operator === \"equals\") return cell === filter;\n if (operator === \"gt\") return cell > filter;\n if (operator === \"lt\") return cell < filter;\n return null;\n },\n renderChipValue: (value) => {\n if (Array.isArray(value)) {\n const from = toNumber(value[0]);\n const to = toNumber(value[1]);\n if (from != null && to != null) return `${toCurrency(from)} → ${toCurrency(to)}`;\n if (from != null) return `≥ ${toCurrency(from)}`;\n if (to != null) return `≤ ${toCurrency(to)}`;\n return \"\";\n }\n return toCurrency(value);\n },\n\n /* G.2 slots */\n renderCell: ({ value, column }) => {\n const opts = column?.typeOptions as CurrencyTypeOptions | undefined;\n return (\n <span className=\"font-semibold tabular-nums\">{toCurrency(value, opts)}</span>\n );\n },\n formatValue: (v) => toCurrency(v),\n defaultAlign: \"right\",\n defaultWidth: 130,\n defaultSortable: true,\n defaultIcon: DollarSign,\n};\n","import { Percent } from \"lucide-react\";\nimport { Input } from \"../../../../shadcn/input\";\nimport { FILTER_FIELD_SIZE } from \"../_filter-field\";\nimport type { ColumnTypeDefinition } from \"../column-types.types\";\n\n/** typeOptions esperadas (opcional): { decimals?: number, locale?: string } */\ntype PercentageTypeOptions = {\n decimals?: number;\n locale?: string;\n};\n\nfunction toPercent(value: unknown, opts?: PercentageTypeOptions): string {\n if (value == null || value === \"\" || Number.isNaN(Number(value))) return \"\";\n const num = Number(value);\n const decimals = opts?.decimals ?? 0;\n const locale = opts?.locale ?? \"pt-BR\";\n try {\n return new Intl.NumberFormat(locale, {\n style: \"percent\",\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n }).format(num / 100);\n } catch {\n return `${num.toFixed(decimals)}%`;\n }\n}\n\nfunction toNumber(v: unknown): number | null {\n if (v == null || v === \"\") return null;\n const n = Number(v);\n return Number.isNaN(n) ? null : n;\n}\n\nexport const PercentageColumnType: ColumnTypeDefinition = {\n type: \"percentage\",\n operators: [\n { id: \"equals\", label: \"é\" },\n { id: \"gt\", label: \"maior que\" },\n { id: \"lt\", label: \"menor que\" },\n ],\n renderFilterInput: ({ value, onChange }) => (\n <Input\n type=\"number\"\n size=\"sm\"\n className={FILTER_FIELD_SIZE}\n value={value == null ? \"\" : String(value)}\n onChange={(e) => onChange(e.target.value === \"\" ? null : Number(e.target.value))}\n placeholder=\"0\"\n max={100}\n min={0}\n />\n ),\n renderFastFilterInput: ({ value, onChange }) => (\n <div className=\"p-pad-md\">\n <Input\n type=\"number\"\n value={value == null ? \"\" : String(value)}\n onChange={(e) => onChange(e.target.value === \"\" ? null : Number(e.target.value))}\n placeholder=\"0\"\n max={100}\n min={0}\n autoFocus\n />\n </div>\n ),\n matchesFilter: (cellValue, filterValue, operator) => {\n const cell = toNumber(cellValue);\n const filter = toNumber(filterValue);\n if (cell === null || filter === null) return false;\n if (operator === \"equals\") return cell === filter;\n if (operator === \"gt\") return cell > filter;\n if (operator === \"lt\") return cell < filter;\n return null;\n },\n renderChipValue: (value) => toPercent(value),\n\n renderCell: ({ value, column }) => {\n const opts = column?.typeOptions as PercentageTypeOptions | undefined;\n return <span className=\"tabular-nums\">{toPercent(value, opts)}</span>;\n },\n formatValue: (v) => toPercent(v),\n defaultAlign: \"right\",\n defaultWidth: 110,\n defaultSortable: true,\n defaultIcon: Percent,\n};\n","import { AtSign } from \"lucide-react\";\nimport { Input } from \"../../../../shadcn/input\";\nimport { FILTER_FIELD_SIZE } from \"../_filter-field\";\nimport type { ColumnTypeDefinition } from \"../column-types.types\";\n\nexport const EmailColumnType: ColumnTypeDefinition = {\n type: \"email\",\n operators: [\n { id: \"contains\", label: \"contém\" },\n { id: \"equals\", label: \"é\" },\n { id: \"neq\", label: \"não é\" },\n ],\n renderFilterInput: ({ value, onChange }) => (\n <Input\n type=\"email\"\n size=\"sm\"\n className={FILTER_FIELD_SIZE}\n value={value == null ? \"\" : String(value)}\n onChange={(e) => onChange(e.target.value)}\n placeholder=\"usuario@exemplo.com\"\n />\n ),\n renderFastFilterInput: ({ value, onChange }) => (\n <div className=\"p-pad-md\">\n <Input\n type=\"email\"\n value={value == null ? \"\" : String(value)}\n onChange={(e) => onChange(e.target.value)}\n placeholder=\"usuario@exemplo.com\"\n autoFocus\n />\n </div>\n ),\n matchesFilter: (cellValue, filterValue, operator) => {\n const cell = cellValue == null ? \"\" : String(cellValue).toLowerCase();\n const filter = filterValue == null ? \"\" : String(filterValue).toLowerCase();\n if (operator === \"contains\") return cell.includes(filter);\n if (operator === \"equals\") return cell === filter;\n if (operator === \"neq\") return cell !== filter;\n return null;\n },\n\n renderCell: ({ value }) => {\n const email = value == null ? \"\" : String(value);\n if (!email) return null;\n return (\n <a\n href={`mailto:${email}`}\n className=\"text-fg-brand hover:underline truncate\"\n onClick={(e) => e.stopPropagation()}\n >\n {email}\n </a>\n );\n },\n formatValue: (v) => (v == null ? \"\" : String(v)),\n defaultAlign: \"left\",\n defaultWidth: 240,\n defaultEllipsis: true,\n defaultSortable: true,\n defaultIcon: AtSign,\n};\n","import { Phone } from \"lucide-react\";\nimport { Input } from \"../../../../shadcn/input\";\nimport { FILTER_FIELD_SIZE } from \"../_filter-field\";\nimport type { ColumnTypeDefinition } from \"../column-types.types\";\n\nexport const PhoneColumnType: ColumnTypeDefinition = {\n type: \"phone\",\n operators: [\n { id: \"contains\", label: \"contém\" },\n { id: \"equals\", label: \"é\" },\n ],\n renderFilterInput: ({ value, onChange }) => (\n <Input\n type=\"tel\"\n size=\"sm\"\n className={FILTER_FIELD_SIZE}\n value={value == null ? \"\" : String(value)}\n onChange={(e) => onChange(e.target.value)}\n placeholder=\"+55 ...\"\n />\n ),\n renderFastFilterInput: ({ value, onChange }) => (\n <div className=\"p-pad-md\">\n <Input\n type=\"tel\"\n value={value == null ? \"\" : String(value)}\n onChange={(e) => onChange(e.target.value)}\n placeholder=\"+55 ...\"\n autoFocus\n />\n </div>\n ),\n matchesFilter: (cellValue, filterValue, operator) => {\n const normalize = (s: unknown) =>\n s == null ? \"\" : String(s).replace(/\\D/g, \"\").toLowerCase();\n const cell = normalize(cellValue);\n const filter = normalize(filterValue);\n if (operator === \"contains\") return cell.includes(filter);\n if (operator === \"equals\") return cell === filter;\n return null;\n },\n\n renderCell: ({ value }) => {\n const phone = value == null ? \"\" : String(value);\n if (!phone) return null;\n const digits = phone.replace(/\\D/g, \"\");\n return (\n <a\n href={`tel:${digits}`}\n className=\"text-fg-brand hover:underline tabular-nums\"\n onClick={(e) => e.stopPropagation()}\n >\n {phone}\n </a>\n );\n },\n formatValue: (v) => (v == null ? \"\" : String(v)),\n defaultAlign: \"left\",\n defaultWidth: 170,\n defaultSortable: false,\n defaultIcon: Phone,\n};\n","import { ExternalLink, Link as LinkIcon } from \"lucide-react\";\nimport { Input } from \"../../../../shadcn/input\";\nimport { FILTER_FIELD_SIZE } from \"../_filter-field\";\nimport type { ColumnTypeDefinition } from \"../column-types.types\";\n\nexport const UrlColumnType: ColumnTypeDefinition = {\n type: \"url\",\n operators: [\n { id: \"contains\", label: \"contém\" },\n { id: \"equals\", label: \"é\" },\n ],\n renderFilterInput: ({ value, onChange }) => (\n <Input\n type=\"url\"\n size=\"sm\"\n className={FILTER_FIELD_SIZE}\n value={value == null ? \"\" : String(value)}\n onChange={(e) => onChange(e.target.value)}\n placeholder=\"https://...\"\n />\n ),\n renderFastFilterInput: ({ value, onChange }) => (\n <div className=\"p-pad-md\">\n <Input\n type=\"url\"\n value={value == null ? \"\" : String(value)}\n onChange={(e) => onChange(e.target.value)}\n placeholder=\"https://...\"\n autoFocus\n />\n </div>\n ),\n matchesFilter: (cellValue, filterValue, operator) => {\n const cell = cellValue == null ? \"\" : String(cellValue).toLowerCase();\n const filter = filterValue == null ? \"\" : String(filterValue).toLowerCase();\n if (operator === \"contains\") return cell.includes(filter);\n if (operator === \"equals\") return cell === filter;\n return null;\n },\n\n renderCell: ({ value }) => {\n const url = value == null ? \"\" : String(value);\n if (!url) return null;\n // Strip protocol pra display, mas mantém no href\n const display = url.replace(/^https?:\\/\\//, \"\");\n return (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-fg-brand hover:underline truncate inline-flex items-center gap-gp-2xs\"\n onClick={(e) => e.stopPropagation()}\n >\n <span className=\"truncate\">{display}</span>\n <ExternalLink className=\"size-icon-2xs shrink-0 opacity-60\" aria-hidden />\n </a>\n );\n },\n formatValue: (v) => (v == null ? \"\" : String(v)),\n defaultAlign: \"left\",\n defaultWidth: 200,\n defaultEllipsis: true,\n defaultSortable: false,\n defaultIcon: LinkIcon,\n};\n","import { User } from \"lucide-react\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../../../shadcn/select\";\nimport { Avatar } from \"../../../Avatar\";\nimport { FILTER_FIELD_SIZE } from \"../_filter-field\";\nimport type { ColumnTypeDefinition } from \"../column-types.types\";\n\n/** Estrutura esperada em `typeOptions.users` — dicionário id → user info. */\ntype UserInfo = {\n name: string;\n avatar?: string;\n initials?: string;\n color?: string;\n};\n\ntype UserTypeOptions = {\n users?: Record<string, UserInfo>;\n};\n\nfunction lookupUser(value: unknown, opts?: UserTypeOptions): UserInfo | null {\n if (value == null) return null;\n const key = String(value);\n return opts?.users?.[key] ?? null;\n}\n\nfunction initialsFromName(name: string): string {\n return name\n .split(/\\s+/)\n .filter(Boolean)\n .slice(0, 2)\n .map((s) => s[0]?.toUpperCase() ?? \"\")\n .join(\"\");\n}\n\n/** Gera cor consistente pelo hash do nome — quando user não tem `color` no\n * typeOptions, usa essa fallback estável (mesmo nome = mesma cor sempre).\n * Paleta de 8 cores semânticas. */\nconst FALLBACK_COLORS = [\n \"#0a3a2e\", // brand-deep\n \"#f59e0b\", // warning\n \"#8754ec\", // purple\n \"#ef4444\", // danger\n \"#06b6d4\", // cyan\n \"#22c55e\", // success\n \"#ec4899\", // pink\n \"#3b82f6\", // info\n];\n\nfunction hashName(name: string): number {\n let h = 0;\n for (let i = 0; i < name.length; i++) {\n h = (h * 31 + name.charCodeAt(i)) | 0;\n }\n return Math.abs(h);\n}\n\nfunction colorForName(name: string): string {\n return FALLBACK_COLORS[hashName(name) % FALLBACK_COLORS.length];\n}\n\n\nexport const UserColumnType: ColumnTypeDefinition = {\n type: \"user\",\n operators: [\n { id: \"equals\", label: \"é\" },\n { id: \"neq\", label: \"não é\" },\n { id: \"isAnyOf\", label: \"é um de\" },\n ],\n renderFilterInput: ({ value, onChange, options }) => (\n <Select\n value={value == null ? \"\" : String(value)}\n onValueChange={(v) => onChange(v)}\n >\n <SelectTrigger className={FILTER_FIELD_SIZE}>\n <SelectValue placeholder=\"Selecione usuário...\" />\n </SelectTrigger>\n <SelectContent>\n {(options ?? []).map((o) => (\n <SelectItem key={String(o.value)} value={String(o.value)}>\n {o.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ),\n renderFastFilterInput: ({ value, onChange, options }) => (\n <div className=\"p-pad-md\">\n <Select\n defaultOpen\n value={value == null ? \"\" : String(value)}\n onValueChange={(v) => onChange(v)}\n >\n <SelectTrigger>\n <SelectValue placeholder=\"Selecione usuário...\" />\n </SelectTrigger>\n <SelectContent>\n {(options ?? []).map((o) => (\n <SelectItem key={String(o.value)} value={String(o.value)}>\n {o.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ),\n matchesFilter: (cellValue, filterValue, operator) => {\n const cell = cellValue == null ? \"\" : String(cellValue);\n if (operator === \"equals\") return cell === String(filterValue ?? \"\");\n if (operator === \"neq\") return cell !== String(filterValue ?? \"\");\n if (operator === \"isAnyOf\") {\n if (!Array.isArray(filterValue)) return null;\n return filterValue.map(String).includes(cell);\n }\n return null;\n },\n renderChipValue: (value, options) => {\n if (value == null) return \"\";\n const opt = options?.find((o) => String(o.value) === String(value));\n return opt?.label ?? String(value);\n },\n\n renderCell: ({ value, column }) => {\n const opts = column?.typeOptions as UserTypeOptions | undefined;\n const user = lookupUser(value, opts);\n if (!user) {\n // Sem typeOptions.users registrado, fallback: usa o valor raw como nome\n const fallbackName = value == null ? \"\" : String(value);\n if (!fallbackName) return null;\n const initials = initialsFromName(fallbackName);\n const color = colorForName(fallbackName);\n return (\n <span\n className=\"inline-flex items-center gap-gp-md whitespace-nowrap\"\n title={fallbackName}\n >\n <Avatar size=\"sm\" colorHex={color}>{initials}</Avatar>\n <span className=\"truncate text-fg-default font-medium\">{fallbackName}</span>\n </span>\n );\n }\n const initials = user.initials ?? initialsFromName(user.name);\n const color = user.color ?? colorForName(user.name);\n return (\n <span\n className=\"inline-flex items-center gap-gp-md whitespace-nowrap\"\n title={user.name}\n >\n <Avatar size=\"sm\" colorHex={color}>{initials}</Avatar>\n <span className=\"truncate text-fg-default font-medium\">{user.name}</span>\n </span>\n );\n },\n formatValue: (v) => (v == null ? \"\" : String(v)),\n defaultAlign: \"left\",\n defaultWidth: 170,\n defaultSortable: true,\n defaultEllipsis: true,\n defaultIcon: User,\n};\n","import { Tag, CheckCircle2 } from \"lucide-react\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../../../shadcn/select\";\nimport { Chip } from \"../../../Chip/chip\";\nimport { FILTER_FIELD_SIZE } from \"../_filter-field\";\nimport type { ColumnTypeDefinition, ColumnOption } from \"../column-types.types\";\n\n/** Mapeia option.color → Chip color variant.\n * Aceita preset names (primary/neutral/danger/warning/success/info) OU\n * qualquer string custom (ex: \"blue\", \"purple\") que cai em `neutral` default. */\ntype ChipColor = \"primary\" | \"neutral\" | \"danger\" | \"warning\" | \"success\" | \"info\";\nconst VALID_COLORS: ReadonlyArray<ChipColor> = [\n \"primary\",\n \"neutral\",\n \"danger\",\n \"warning\",\n \"success\",\n \"info\",\n];\n\nfunction resolveChipColor(raw: string | undefined): ChipColor {\n if (!raw) return \"neutral\";\n if (VALID_COLORS.includes(raw as ChipColor)) return raw as ChipColor;\n // Mapeamentos comuns\n const aliases: Record<string, ChipColor> = {\n green: \"success\",\n red: \"danger\",\n yellow: \"warning\",\n blue: \"info\",\n gray: \"neutral\",\n grey: \"neutral\",\n };\n return aliases[raw.toLowerCase()] ?? \"neutral\";\n}\n\nfunction findOption(value: unknown, options?: ColumnOption[]): ColumnOption | null {\n if (value == null) return null;\n return options?.find((o) => String(o.value) === String(value)) ?? null;\n}\n\nexport const BadgeColumnType: ColumnTypeDefinition = {\n type: \"badge\",\n operators: [\n { id: \"equals\", label: \"é\" },\n { id: \"neq\", label: \"não é\" },\n { id: \"isAnyOf\", label: \"é um de\" },\n ],\n renderFilterInput: ({ value, onChange, options }) => (\n <Select\n value={value == null ? \"\" : String(value)}\n onValueChange={(v) => onChange(v)}\n >\n <SelectTrigger className={FILTER_FIELD_SIZE}>\n <SelectValue placeholder=\"Selecione...\" />\n </SelectTrigger>\n <SelectContent>\n {(options ?? []).map((o) => (\n <SelectItem key={String(o.value)} value={String(o.value)}>\n {o.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ),\n renderFastFilterInput: ({ value, onChange, options }) => (\n <div className=\"p-pad-md\">\n <Select\n defaultOpen\n value={value == null ? \"\" : String(value)}\n onValueChange={(v) => onChange(v)}\n >\n <SelectTrigger>\n <SelectValue placeholder=\"Selecione...\" />\n </SelectTrigger>\n <SelectContent>\n {(options ?? []).map((o) => (\n <SelectItem key={String(o.value)} value={String(o.value)}>\n {o.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ),\n matchesFilter: (cellValue, filterValue, operator) => {\n const cell = cellValue == null ? \"\" : String(cellValue);\n if (operator === \"equals\") return cell === String(filterValue ?? \"\");\n if (operator === \"neq\") return cell !== String(filterValue ?? \"\");\n if (operator === \"isAnyOf\") {\n if (!Array.isArray(filterValue)) return null;\n return filterValue.map(String).includes(cell);\n }\n return null;\n },\n renderChipValue: (value, options) => {\n if (value == null) return \"\";\n const opt = findOption(value, options);\n return opt?.label ?? String(value);\n },\n\n renderCell: ({ value, options }) => {\n const opt = findOption(value, options);\n if (!opt) {\n if (value == null) return null;\n return <Chip size=\"sm\">{String(value)}</Chip>;\n }\n return (\n <Chip size=\"sm\" color={resolveChipColor(opt.color)}>\n {opt.label}\n </Chip>\n );\n },\n formatValue: (v) => (v == null ? \"\" : String(v)),\n defaultAlign: \"left\",\n defaultWidth: 140,\n defaultSortable: true,\n defaultIcon: Tag,\n};\n\n/** Alias `status` = `badge`. Status é um conceito semântico (active/pending/etc)\n * mas o render é o mesmo de badge. Registramos ambos pra DX. */\nexport const StatusColumnType: ColumnTypeDefinition = {\n ...BadgeColumnType,\n type: \"status\",\n defaultIcon: CheckCircle2,\n};\n","import { Tags, ChevronDown } from \"lucide-react\";\nimport { Chip } from \"../../../Chip/chip\";\nimport { Checkbox } from \"../../../../shadcn/checkbox\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../../../../shadcn/popover\";\nimport { FILTER_FIELD_CLASS } from \"../_filter-field\";\nimport type { ColumnTypeDefinition, ColumnOption } from \"../column-types.types\";\n\n/** Resolve cor do chip — mesma logica do badge type. */\ntype ChipColor = \"primary\" | \"neutral\" | \"danger\" | \"warning\" | \"success\" | \"info\";\nconst VALID_COLORS: ReadonlyArray<ChipColor> = [\n \"primary\",\n \"neutral\",\n \"danger\",\n \"warning\",\n \"success\",\n \"info\",\n];\nfunction resolveChipColor(raw: string | undefined): ChipColor {\n if (!raw) return \"neutral\";\n if (VALID_COLORS.includes(raw as ChipColor)) return raw as ChipColor;\n const aliases: Record<string, ChipColor> = {\n green: \"success\",\n red: \"danger\",\n yellow: \"warning\",\n blue: \"info\",\n gray: \"neutral\",\n grey: \"neutral\",\n };\n return aliases[raw.toLowerCase()] ?? \"neutral\";\n}\n\nfunction toArray(v: unknown): string[] {\n if (v == null) return [];\n if (Array.isArray(v)) return v.map(String);\n return [String(v)];\n}\n\nfunction findOption(value: string, options?: ColumnOption[]): ColumnOption | null {\n return options?.find((o) => String(o.value) === value) ?? null;\n}\n\nexport const TagsColumnType: ColumnTypeDefinition = {\n type: \"tags\",\n operators: [\n { id: \"isAnyOf\", label: \"tem qualquer\" },\n { id: \"isNoneOf\", label: \"não tem\" },\n { id: \"contains\", label: \"contém\" },\n ],\n renderFilterInput: ({ value, onChange, options }) => {\n const selected = new Set(toArray(value));\n const toggle = (v: string) => {\n const next = new Set(selected);\n if (next.has(v)) next.delete(v);\n else next.add(v);\n onChange(Array.from(next));\n };\n const labels = Array.from(selected).map((v) => {\n const opt = findOption(v, options);\n return opt?.label ?? v;\n });\n const display =\n labels.length === 0\n ? \"\"\n : labels.length <= 2\n ? labels.join(\", \")\n : `${labels.length} selecionados`;\n return (\n <Popover>\n <PopoverTrigger asChild>\n <button type=\"button\" className={FILTER_FIELD_CLASS}>\n <span className={display ? \"truncate\" : \"text-fg-muted opacity-70 truncate\"}>\n {display || \"Selecione tags...\"}\n </span>\n <ChevronDown className=\"size-icon-xs text-fg-muted shrink-0\" />\n </button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"p-0 w-[var(--radix-popover-trigger-width)] min-w-[200px]\">\n <div className=\"flex flex-col gap-gp-2xs p-pad-md max-h-[240px] overflow-auto\">\n {(options ?? []).map((o) => (\n <label\n key={String(o.value)}\n className=\"flex items-center gap-gp-md p-pad-xs rounded-radius-sm hover:bg-bg-muted cursor-pointer\"\n >\n <Checkbox\n checked={selected.has(String(o.value))}\n onCheckedChange={() => toggle(String(o.value))}\n />\n <span className=\"text-paragraph-sm text-fg-default\">{o.label}</span>\n </label>\n ))}\n </div>\n </PopoverContent>\n </Popover>\n );\n },\n renderFastFilterInput: ({ value, onChange, options }) => {\n const selected = new Set(toArray(value));\n const toggle = (v: string) => {\n const next = new Set(selected);\n if (next.has(v)) next.delete(v);\n else next.add(v);\n onChange(Array.from(next));\n };\n return (\n <div className=\"flex flex-col gap-gp-2xs p-pad-md max-h-[240px] overflow-auto\">\n {(options ?? []).map((o) => (\n <label\n key={String(o.value)}\n className=\"flex items-center gap-gp-md p-pad-xs rounded-radius-sm hover:bg-bg-muted cursor-pointer\"\n >\n <Checkbox\n checked={selected.has(String(o.value))}\n onCheckedChange={() => toggle(String(o.value))}\n />\n <span className=\"text-paragraph-sm text-fg-default\">{o.label}</span>\n </label>\n ))}\n </div>\n );\n },\n matchesFilter: (cellValue, filterValue, operator) => {\n const cell = toArray(cellValue);\n const filter = toArray(filterValue);\n if (operator === \"isAnyOf\") return filter.some((f) => cell.includes(f));\n if (operator === \"isNoneOf\") return !filter.some((f) => cell.includes(f));\n if (operator === \"contains\") return filter.every((f) => cell.includes(f));\n return null;\n },\n renderChipValue: (value, options) => {\n const arr = toArray(value);\n if (arr.length === 0) return \"\";\n const labels = arr.map(\n (v) => findOption(v, options)?.label ?? v,\n );\n if (labels.length <= 2) return labels.join(\", \");\n return `${labels.length} selecionados`;\n },\n\n renderCell: ({ value, options }) => {\n const arr = toArray(value);\n if (arr.length === 0) return null;\n return (\n <span className=\"inline-flex items-center flex-wrap gap-gp-2xs\">\n {arr.map((v) => {\n const opt = findOption(v, options);\n return (\n <Chip key={v} size=\"sm\" color={resolveChipColor(opt?.color)}>\n {opt?.label ?? v}\n </Chip>\n );\n })}\n </span>\n );\n },\n formatValue: (v) => toArray(v).join(\", \"),\n defaultAlign: \"left\",\n defaultWidth: 200,\n defaultEllipsis: true,\n defaultSortable: false,\n defaultIcon: Tags,\n};\n","import { CalendarClock } from \"lucide-react\";\nimport { Calendar } from \"../../../../shadcn/calendar\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../../../../shadcn/popover\";\nimport { FILTER_FIELD_CLASS } from \"../_filter-field\";\nimport type { ColumnTypeDefinition } from \"../column-types.types\";\n\n/* Helpers idênticos ao date type (com hora adicional). */\n\nfunction toDateMs(v: unknown): number | null {\n if (v == null || v === \"\") return null;\n if (typeof v === \"number\") return v;\n if (v instanceof Date) return v.getTime();\n const d = new Date(String(v));\n return Number.isNaN(d.getTime()) ? null : d.getTime();\n}\n\nfunction dayStart(ms: number): number {\n const d = new Date(ms);\n d.setHours(0, 0, 0, 0);\n return d.getTime();\n}\n\nfunction toDate(v: unknown): Date | undefined {\n const ms = toDateMs(v);\n return ms == null ? undefined : new Date(ms);\n}\n\nfunction toIsoDate(d: Date | undefined | null): string | null {\n if (!d) return null;\n const y = d.getFullYear();\n const m = String(d.getMonth() + 1).padStart(2, \"0\");\n const day = String(d.getDate()).padStart(2, \"0\");\n return `${y}-${m}-${day}`;\n}\n\nconst ptBrShort = new Intl.DateTimeFormat(\"pt-BR\", {\n day: \"2-digit\",\n month: \"short\",\n});\n\nconst ptBrShortTime = new Intl.DateTimeFormat(\"pt-BR\", {\n day: \"2-digit\",\n month: \"short\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n});\n\nfunction formatShort(v: unknown): string {\n const d = toDate(v);\n if (!d) return \"\";\n return ptBrShort.format(d).replace(\".\", \"\");\n}\n\nfunction formatShortTime(v: unknown): string {\n const d = toDate(v);\n if (!d) return \"\";\n return ptBrShortTime.format(d).replace(\".\", \"\");\n}\n\nexport const DatetimeColumnType: ColumnTypeDefinition = {\n type: \"datetime\",\n operators: [\n { id: \"equals\", label: \"é\" },\n { id: \"gt\", label: \"depois de\" },\n { id: \"lt\", label: \"antes de\" },\n { id: \"between\", label: \"entre\" },\n ],\n renderFilterInput: ({ value, onChange, operator }) => {\n const isRange = operator === \"between\";\n const displayValue = (() => {\n if (isRange && Array.isArray(value)) {\n const from = formatShort(value[0]);\n const to = formatShort(value[1]);\n if (from && to) return `${from} → ${to}`;\n if (from) return `desde ${from}`;\n if (to) return `até ${to}`;\n return \"\";\n }\n return formatShort(value);\n })();\n return (\n <Popover>\n <PopoverTrigger asChild>\n <button type=\"button\" className={FILTER_FIELD_CLASS}>\n <span className={displayValue ? \"truncate\" : \"text-fg-muted opacity-70 truncate\"}>\n {displayValue || (isRange ? \"Selecione período\" : \"Selecione data\")}\n </span>\n <CalendarClock className=\"size-icon-xs text-fg-muted shrink-0\" />\n </button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"p-pad-md w-auto\">\n {isRange ? (\n <Calendar\n mode=\"range\"\n selected={\n Array.isArray(value)\n ? { from: toDate(value[0]), to: toDate(value[1]) }\n : { from: undefined, to: undefined }\n }\n onSelect={(r) => {\n onChange([\n toIsoDate(r?.from ?? null),\n toIsoDate(r?.to ?? null),\n ]);\n }}\n />\n ) : (\n <Calendar\n mode=\"single\"\n selected={toDate(value)}\n onSelect={(d) => onChange(toIsoDate(d ?? null))}\n />\n )}\n </PopoverContent>\n </Popover>\n );\n },\n renderFastFilterInput: ({ value, onChange }) => {\n const isRange = Array.isArray(value);\n if (isRange) {\n const range = { from: toDate(value[0]), to: toDate(value[1]) };\n return (\n <div className=\"p-pad-md\">\n <Calendar\n mode=\"range\"\n selected={range}\n onSelect={(r) => {\n onChange([toIsoDate(r?.from ?? null), toIsoDate(r?.to ?? null)]);\n }}\n />\n </div>\n );\n }\n return (\n <div className=\"p-pad-md\">\n <Calendar\n mode=\"single\"\n selected={toDate(value)}\n onSelect={(d) => onChange(toIsoDate(d ?? null))}\n />\n </div>\n );\n },\n renderChipValue: (value) => {\n if (Array.isArray(value)) {\n const from = formatShort(value[0]);\n const to = formatShort(value[1]);\n if (from && to) return `${from} → ${to}`;\n if (from) return `desde ${from}`;\n if (to) return `até ${to}`;\n return \"\";\n }\n return formatShort(value);\n },\n matchesFilter: (cellValue, filterValue, operator) => {\n const cell = toDateMs(cellValue);\n if (cell === null) return false;\n const cellDay = dayStart(cell);\n if (operator === \"between\") {\n if (!Array.isArray(filterValue)) return null;\n const startMs = toDateMs(filterValue[0]);\n const endMs = toDateMs(filterValue[1]);\n if (startMs !== null && endMs !== null) {\n return cellDay >= dayStart(startMs) && cellDay <= dayStart(endMs);\n }\n if (startMs !== null) return cellDay >= dayStart(startMs);\n if (endMs !== null) return cellDay <= dayStart(endMs);\n return false;\n }\n const filter = toDateMs(filterValue);\n if (filter === null) return false;\n const filterDay = dayStart(filter);\n if (operator === \"equals\") return cellDay === filterDay;\n if (operator === \"gt\") return cellDay > filterDay;\n if (operator === \"lt\") return cellDay < filterDay;\n return null;\n },\n\n renderCell: ({ value }) => (\n <span className=\"text-fg-muted tabular-nums\">{formatShortTime(value)}</span>\n ),\n formatValue: (v) => formatShortTime(v),\n defaultAlign: \"left\",\n defaultWidth: 160,\n defaultSortable: true,\n defaultIcon: CalendarClock,\n};\n","/**\n * Column Types Registry — sistema extensivel de tipos de coluna do DataTable.\n *\n * Cada tipo declara:\n * - operators suportados\n * - render no modal Filtros (advanced)\n * - render no chip popover (fast filter)\n * - logica de match runtime (rows.filter)\n * - render do chip value (opcional, default uso simples)\n *\n * Default tipos registrados: text, number, date, select, multiSelect, boolean.\n * Pra adicionar tipo customizado:\n * columnTypeRegistry.register({ type: \"currency\", operators: [...], renderFilterInput: ..., ... });\n */\n\nexport { columnTypeRegistry } from \"./column-type-registry\";\nexport type {\n ColumnTypeDefinition,\n ColumnTypeId,\n ColumnTypeOperator,\n ColumnOption,\n FilterInputProps,\n FastFilterInputProps,\n} from \"./column-types.types\";\n\n// Registra os tipos default automaticamente no import\nimport { columnTypeRegistry } from \"./column-type-registry\";\nimport { TextColumnType } from \"./definitions/text-column-type\";\nimport { NumberColumnType } from \"./definitions/number-column-type\";\nimport { DateColumnType } from \"./definitions/date-column-type\";\nimport { SelectColumnType } from \"./definitions/select-column-type\";\nimport { MultiSelectColumnType } from \"./definitions/multi-select-column-type\";\nimport { BooleanColumnType } from \"./definitions/boolean-column-type\";\n// Fase G.3 — tipos prebuilt\nimport { CurrencyColumnType } from \"./definitions/currency-column-type\";\nimport { PercentageColumnType } from \"./definitions/percentage-column-type\";\nimport { EmailColumnType } from \"./definitions/email-column-type\";\nimport { PhoneColumnType } from \"./definitions/phone-column-type\";\nimport { UrlColumnType } from \"./definitions/url-column-type\";\nimport { UserColumnType } from \"./definitions/user-column-type\";\nimport {\n BadgeColumnType,\n StatusColumnType,\n} from \"./definitions/badge-column-type\";\nimport { TagsColumnType } from \"./definitions/tags-column-type\";\nimport { DatetimeColumnType } from \"./definitions/datetime-column-type\";\n\ncolumnTypeRegistry.registerMany([\n TextColumnType,\n NumberColumnType,\n DateColumnType,\n SelectColumnType,\n MultiSelectColumnType,\n BooleanColumnType,\n CurrencyColumnType,\n PercentageColumnType,\n EmailColumnType,\n PhoneColumnType,\n UrlColumnType,\n UserColumnType,\n BadgeColumnType,\n StatusColumnType,\n TagsColumnType,\n DatetimeColumnType,\n]);\n\nexport {\n TextColumnType,\n NumberColumnType,\n DateColumnType,\n SelectColumnType,\n MultiSelectColumnType,\n BooleanColumnType,\n CurrencyColumnType,\n PercentageColumnType,\n EmailColumnType,\n PhoneColumnType,\n UrlColumnType,\n UserColumnType,\n BadgeColumnType,\n StatusColumnType,\n TagsColumnType,\n DatetimeColumnType,\n};\n","import { useCallback, useMemo, useState } from \"react\";\nimport { useColumnWidths } from \"../../Table\";\nimport type { ColumnPinned } from \"../../Table\";\nimport type { DataTableColumnDef } from \"../data-table.types\";\nimport { columnTypeRegistry } from \"../column-types\";\n\nexport type UseDataTableColumnsParams<T> = {\n columns: DataTableColumnDef<T>[];\n /** Estado inicial hidratado (de localStorage ou prop) — aplicado apenas no mount. */\n initialWidthOverrides?: Record<string, number>;\n initialPinnedOverrides?: Record<string, ColumnPinned>;\n initialHiddenColumns?: string[];\n initialColumnOrder?: string[];\n};\n\nexport type UseDataTableColumnsResult<T> = {\n /** Colunas após aplicar hiddenColumns e columnOrder. */\n effectiveColumns: DataTableColumnDef<T>[];\n /** Widths em px por field. */\n columnWidths: Record<string, number>;\n /** Sticky offsets por field. */\n stickyOffsets: Record<string, number>;\n /** Hidden columns state. */\n hiddenColumns: Set<string>;\n /** Pinned columns state. */\n pinnedColumns: Record<string, ColumnPinned>;\n /** Column order state. */\n columnOrder: string[];\n\n /** Handlers. */\n handleResize: (field: string, widthPx: number) => void;\n handlePin: (field: string, side: ColumnPinned) => void;\n handleHide: (field: string) => void;\n handleShow: (field: string) => void;\n handleReorder: (newOrder: string[]) => void;\n /** Aplica snapshot completo de columns state (usado por applyView). */\n applyColumnState: (state: {\n columnWidths?: Record<string, number>;\n pinnedColumns?: Record<string, ColumnPinned>;\n hiddenColumns?: string[];\n columnOrder?: string[];\n }) => void;\n};\n\n/**\n * Gerencia estado de colunas (widths, pin, hide, order) e calcula offsets sticky.\n * Tudo uncontrolled na v1 — controle via props vem em F7 (persistência).\n */\nexport function useDataTableColumns<T>({\n columns,\n initialWidthOverrides,\n initialPinnedOverrides,\n initialHiddenColumns,\n initialColumnOrder,\n}: UseDataTableColumnsParams<T>): UseDataTableColumnsResult<T> {\n // Width override por field (uncontrolled). Default vem do columnDef.\n const [widthOverrides, setWidthOverrides] = useState<Record<string, number>>(\n () => initialWidthOverrides ?? {},\n );\n // Pinned override (default vem do columnDef.pinned).\n const [pinnedOverrides, setPinnedOverrides] = useState<Record<string, ColumnPinned>>(\n () => initialPinnedOverrides ?? {},\n );\n // Hidden state (uncontrolled).\n const [hiddenColumns, setHiddenColumns] = useState<Set<string>>(\n () => new Set(initialHiddenColumns ?? []),\n );\n // Order state (uncontrolled). Default: order do array de columns.\n // Hidrata via initialColumnOrder mas descarta entradas que nao existem mais\n // nas columns atuais (schema validation — campo pode ter sido removido).\n const [columnOrder, setColumnOrder] = useState<string[]>(() => {\n const fieldSet = new Set(columns.map((c) => String(c.field)));\n if (initialColumnOrder) {\n const valid = initialColumnOrder.filter((f) => fieldSet.has(f));\n // Anexa campos que existem agora mas nao estavam no persist (colunas novas).\n const missing = columns\n .map((c) => String(c.field))\n .filter((f) => !valid.includes(f));\n return [...valid, ...missing];\n }\n return columns.map((c) => String(c.field));\n });\n\n // Efetivo: filtra hidden, aplica order, mescla overrides + defaults do registry\n // por tipo (Fase G.2: width/sortable/align/ellipsis vêm do tipo quando não passados).\n const effectiveColumns = useMemo<DataTableColumnDef<T>[]>(() => {\n const byField = new Map(columns.map((c) => [String(c.field), c]));\n const ordered: DataTableColumnDef<T>[] = [];\n for (const field of columnOrder) {\n const col = byField.get(field);\n if (!col || hiddenColumns.has(field)) continue;\n const typeDef = col.type ? columnTypeRegistry.get(col.type) : undefined;\n ordered.push({\n ...col,\n width: widthOverrides[field] ?? col.width ?? typeDef?.defaultWidth,\n sortable: col.sortable ?? typeDef?.defaultSortable,\n pinned: field in pinnedOverrides ? pinnedOverrides[field] : col.pinned,\n });\n }\n return ordered;\n }, [columns, columnOrder, hiddenColumns, widthOverrides, pinnedOverrides]);\n\n // Calcula offsets sticky via hook do Table primitivo\n const widthsInput = useMemo(\n () =>\n effectiveColumns.map((c) => ({\n field: String(c.field),\n width: c.width,\n defaultWidth: c.width,\n pinned: c.pinned,\n })),\n [effectiveColumns],\n );\n const { widths, offsets } = useColumnWidths(widthsInput);\n\n const handleResize = useCallback((field: string, widthPx: number) => {\n setWidthOverrides((prev) => ({ ...prev, [field]: widthPx }));\n }, []);\n\n const handlePin = useCallback((field: string, side: ColumnPinned) => {\n setPinnedOverrides((prev) => ({ ...prev, [field]: side }));\n }, []);\n\n const handleHide = useCallback((field: string) => {\n setHiddenColumns((prev) => {\n const next = new Set(prev);\n next.add(field);\n return next;\n });\n }, []);\n\n const handleShow = useCallback((field: string) => {\n setHiddenColumns((prev) => {\n const next = new Set(prev);\n next.delete(field);\n return next;\n });\n }, []);\n\n const handleReorder = useCallback((newOrder: string[]) => {\n setColumnOrder(newOrder);\n }, []);\n\n const applyColumnState = useCallback((state: {\n columnWidths?: Record<string, number>;\n pinnedColumns?: Record<string, ColumnPinned>;\n hiddenColumns?: string[];\n columnOrder?: string[];\n }) => {\n if (state.columnWidths) setWidthOverrides(state.columnWidths);\n if (state.pinnedColumns) setPinnedOverrides(state.pinnedColumns);\n if (state.hiddenColumns) setHiddenColumns(new Set(state.hiddenColumns));\n if (state.columnOrder) {\n // Filtra campos que nao existem mais (schema mudou)\n const fieldSet = new Set(columns.map((c) => String(c.field)));\n const valid = state.columnOrder.filter((f) => fieldSet.has(f));\n const missing = columns\n .map((c) => String(c.field))\n .filter((f) => !valid.includes(f));\n setColumnOrder([...valid, ...missing]);\n }\n }, [columns]);\n\n // pinnedColumns combinado (overrides + defaults)\n const pinnedColumns = useMemo<Record<string, ColumnPinned>>(() => {\n const result: Record<string, ColumnPinned> = {};\n for (const c of columns) {\n const field = String(c.field);\n result[field] = field in pinnedOverrides ? pinnedOverrides[field] : c.pinned;\n }\n return result;\n }, [columns, pinnedOverrides]);\n\n return {\n effectiveColumns,\n columnWidths: widths,\n stickyOffsets: offsets,\n hiddenColumns,\n pinnedColumns,\n columnOrder,\n handleResize,\n handlePin,\n handleHide,\n handleShow,\n handleReorder,\n applyColumnState,\n };\n}\n","import { useCallback, useState } from \"react\";\nimport type { SortModel } from \"../data-table.types\";\n\n/** Normaliza valor controlled/initial pra array (aceita single, array ou null). */\nfunction toArray(v: SortModel | SortModel[] | null | undefined): SortModel[] {\n if (v == null) return [];\n if (Array.isArray(v)) return v;\n return [v];\n}\n\nexport type UseDataTableSortParams = {\n /**\n * Controlled sort. Aceita single (1 criterio) ou array (multi-sort).\n * Array vazio ou null = sem sort.\n */\n sortModel?: SortModel | SortModel[] | null;\n /** Callback quando muda. Sempre recebe array. */\n onSortModelChange?: (model: SortModel[]) => void;\n /** Hidratado de localStorage. Single ou array. */\n initialSortModel?: SortModel | SortModel[] | null;\n};\n\nexport type UseDataTableSortResult = {\n /** Lista de criterios — primeiro = prioridade maior. */\n sortModels: SortModel[];\n /** Backward-compat: primeiro criterio (ou null). */\n sortModel: SortModel | null;\n /** Click no header — ciclo asc → desc → null. Substitui multi por single. */\n handleSort: (field: string) => void;\n /** Setter direto (substitui lista inteira). */\n setSortModels: (models: SortModel[]) => void;\n /**\n * @deprecated — use setSortModels com array.\n * Compat: aceita single objeto/null e wrappea pra array.\n */\n setSortModel: (model: SortModel | null) => void;\n};\n\n/**\n * Sort state — multi-sort com array de criterios.\n *\n * Click no header zera multi e define 1 criterio (ciclo asc/desc/null).\n * Multi-sort eh editado via popover (SortPopover usa setSortModels com array).\n *\n * Controlled quando `sortModel` prop presente (aceita single ou array).\n */\nexport function useDataTableSort({\n sortModel: controlledSort,\n onSortModelChange,\n initialSortModel,\n}: UseDataTableSortParams = {}): UseDataTableSortResult {\n const [uncontrolledSort, setUncontrolledSort] = useState<SortModel[]>(\n () => toArray(initialSortModel),\n );\n const isControlled = controlledSort !== undefined;\n const sortModels = isControlled ? toArray(controlledSort) : uncontrolledSort;\n\n const setSortModels = useCallback(\n (models: SortModel[]) => {\n if (!isControlled) setUncontrolledSort(models);\n onSortModelChange?.(models);\n },\n [isControlled, onSortModelChange],\n );\n\n const setSortModel = useCallback(\n (model: SortModel | null) => {\n setSortModels(model ? [model] : []);\n },\n [setSortModels],\n );\n\n const handleSort = useCallback(\n (field: string) => {\n // Click no header SEMPRE zera multi e define 1 criterio com ciclo.\n // Pra adicionar multi, usar SortPopover.\n const current = sortModels.find((s) => s.field === field);\n if (!current) {\n setSortModels([{ field, direction: \"asc\" }]);\n } else if (current.direction === \"asc\") {\n setSortModels([{ field, direction: \"desc\" }]);\n } else {\n setSortModels([]);\n }\n },\n [sortModels, setSortModels],\n );\n\n return {\n sortModels,\n sortModel: sortModels[0] ?? null,\n handleSort,\n setSortModels,\n setSortModel,\n };\n}\n","import { useCallback, useEffect, useState } from \"react\";\nimport type { PaginationModel } from \"../data-table.types\";\n\nexport type UseDataTablePaginationParams = {\n paginationModel?: PaginationModel;\n onPaginationModelChange?: (model: PaginationModel) => void;\n initialPageSize?: number;\n /** Reset page→1 quando esses valores mudarem (ex: filtro, search). */\n resetTriggers?: unknown[];\n};\n\nexport type UseDataTablePaginationResult = {\n paginationModel: PaginationModel;\n setPage: (page: number) => void;\n setPageSize: (pageSize: number) => void;\n setPaginationModel: (model: PaginationModel) => void;\n};\n\nconst DEFAULT_PAGE_SIZE = 25;\n\n/**\n * Pagination state. Auto-reseta para page 1 quando triggers mudam (filter/search).\n */\nexport function useDataTablePagination({\n paginationModel: controlledModel,\n onPaginationModelChange,\n initialPageSize = DEFAULT_PAGE_SIZE,\n resetTriggers = [],\n}: UseDataTablePaginationParams = {}): UseDataTablePaginationResult {\n const [uncontrolled, setUncontrolled] = useState<PaginationModel>({\n page: 1,\n pageSize: initialPageSize,\n });\n const isControlled = controlledModel !== undefined;\n const paginationModel = isControlled ? controlledModel : uncontrolled;\n\n const setPaginationModel = useCallback(\n (model: PaginationModel) => {\n if (!isControlled) setUncontrolled(model);\n onPaginationModelChange?.(model);\n },\n [isControlled, onPaginationModelChange],\n );\n\n const setPage = useCallback(\n (page: number) => {\n // Functional update pra evitar stale closure quando setPage é chamado\n // logo após setPageSize no mesmo render tick (ex: FooterTable.onValueChange\n // chama setPageSize(N) seguido de setPage(1)).\n if (!isControlled) {\n setUncontrolled((prev) => ({ ...prev, page }));\n }\n onPaginationModelChange?.({ ...paginationModel, page });\n },\n [paginationModel, isControlled, onPaginationModelChange],\n );\n\n const setPageSize = useCallback(\n (pageSize: number) => {\n if (!isControlled) {\n setUncontrolled((prev) => ({ ...prev, pageSize, page: 1 }));\n }\n onPaginationModelChange?.({ page: 1, pageSize });\n },\n [isControlled, onPaginationModelChange],\n );\n\n // Reset page→1 quando triggers mudam (ex: filtros aplicados, search digitado)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(() => {\n if (paginationModel.page !== 1) {\n setPaginationModel({ ...paginationModel, page: 1 });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, resetTriggers);\n\n return { paginationModel, setPage, setPageSize, setPaginationModel };\n}\n","import { useCallback, useMemo, useState } from \"react\";\nimport type { GridRowId, GridSelectionState } from \"../data-table.types\";\n\nexport type UseDataTableSelectionParams<T> = {\n rows: T[];\n getRowId: (row: T) => GridRowId;\n /** Controlled selection. */\n selectionModel?: GridSelectionState;\n onSelectionModelChange?: (model: GridSelectionState) => void;\n};\n\nexport type UseDataTableSelectionResult<T> = {\n /** Estado bruto. */\n state: GridSelectionState;\n /** True se a row está selecionada. */\n isRowSelected: (row: T) => boolean;\n /** Toggle uma row. */\n toggleRow: (row: T) => void;\n /** Seleciona/deseleciona todas as rows da página atual. */\n togglePage: (rowsOnPage: T[]) => void;\n /** Vira \"exclude all\": seleciona TUDO (incluindo dados não carregados). */\n selectAll: () => void;\n /** Limpa. */\n clear: () => void;\n /** Quantidade selecionada (rows visíveis). */\n selectedCount: number;\n /** IDs como array (utility). */\n selectedIds: GridRowId[];\n /** True quando todas as rows visíveis estão selecionadas. */\n isPageSelected: (rowsOnPage: T[]) => boolean;\n /** True quando ALGUMA (mas não todas) estão selecionadas. Pra indeterminate. */\n isPageIndeterminate: (rowsOnPage: T[]) => boolean;\n};\n\nconst EMPTY_STATE: GridSelectionState = { type: \"include\", ids: new Set() };\n\n/**\n * Selection com modelo include/exclude. Permite \"select all global\" sem materializar IDs.\n */\nexport function useDataTableSelection<T>({\n rows,\n getRowId,\n selectionModel: controlledState,\n onSelectionModelChange,\n}: UseDataTableSelectionParams<T>): UseDataTableSelectionResult<T> {\n const [uncontrolled, setUncontrolled] = useState<GridSelectionState>(EMPTY_STATE);\n const isControlled = controlledState !== undefined;\n const state = isControlled ? controlledState : uncontrolled;\n\n const setState = useCallback(\n (next: GridSelectionState) => {\n if (!isControlled) setUncontrolled(next);\n onSelectionModelChange?.(next);\n },\n [isControlled, onSelectionModelChange],\n );\n\n const isRowSelected = useCallback(\n (row: T) => {\n const id = getRowId(row);\n const hasInIds = state.ids.has(id);\n return state.type === \"include\" ? hasInIds : !hasInIds;\n },\n [state, getRowId],\n );\n\n const toggleRow = useCallback(\n (row: T) => {\n const id = getRowId(row);\n const nextIds = new Set(state.ids);\n if (nextIds.has(id)) nextIds.delete(id);\n else nextIds.add(id);\n setState({ type: state.type, ids: nextIds });\n },\n [state, getRowId, setState],\n );\n\n const togglePage = useCallback(\n (rowsOnPage: T[]) => {\n const allSelected = rowsOnPage.every(isRowSelected);\n const nextIds = new Set(state.ids);\n if (allSelected) {\n for (const r of rowsOnPage) {\n const id = getRowId(r);\n if (state.type === \"include\") nextIds.delete(id);\n else nextIds.add(id);\n }\n } else {\n for (const r of rowsOnPage) {\n const id = getRowId(r);\n if (state.type === \"include\") nextIds.add(id);\n else nextIds.delete(id);\n }\n }\n setState({ type: state.type, ids: nextIds });\n },\n [state, isRowSelected, getRowId, setState],\n );\n\n const selectAll = useCallback(() => {\n setState({ type: \"exclude\", ids: new Set() });\n }, [setState]);\n\n const clear = useCallback(() => {\n setState({ type: \"include\", ids: new Set() });\n }, [setState]);\n\n const selectedCount = useMemo(() => {\n if (state.type === \"include\") return state.ids.size;\n return rows.length - state.ids.size;\n }, [state, rows.length]);\n\n const selectedIds = useMemo<GridRowId[]>(() => {\n if (state.type === \"include\") return Array.from(state.ids);\n // exclude: visíveis menos os excluídos\n return rows\n .map(getRowId)\n .filter((id) => !state.ids.has(id));\n }, [state, rows, getRowId]);\n\n const isPageSelected = useCallback(\n (rowsOnPage: T[]) => rowsOnPage.length > 0 && rowsOnPage.every(isRowSelected),\n [isRowSelected],\n );\n\n const isPageIndeterminate = useCallback(\n (rowsOnPage: T[]) => {\n const sel = rowsOnPage.filter(isRowSelected).length;\n return sel > 0 && sel < rowsOnPage.length;\n },\n [isRowSelected],\n );\n\n return {\n state,\n isRowSelected,\n toggleRow,\n togglePage,\n selectAll,\n clear,\n selectedCount,\n selectedIds,\n isPageSelected,\n isPageIndeterminate,\n };\n}\n","import { useCallback, useState } from \"react\";\nimport type { TableDensity } from \"../../Table\";\n\nexport type UseDataTableDensityParams = {\n density?: TableDensity;\n onDensityChange?: (density: TableDensity) => void;\n defaultDensity?: TableDensity;\n /** Hidratado de localStorage. Aplicado apenas no mount. */\n initialDensity?: TableDensity;\n};\n\nexport type UseDataTableDensityResult = {\n density: TableDensity;\n setDensity: (density: TableDensity) => void;\n};\n\nexport function useDataTableDensity({\n density: controlled,\n onDensityChange,\n defaultDensity = \"standard\",\n initialDensity,\n}: UseDataTableDensityParams = {}): UseDataTableDensityResult {\n const [uncontrolled, setUncontrolled] = useState<TableDensity>(\n () => initialDensity ?? defaultDensity,\n );\n const isControlled = controlled !== undefined;\n const density = isControlled ? controlled : uncontrolled;\n\n const setDensity = useCallback(\n (next: TableDensity) => {\n if (!isControlled) setUncontrolled(next);\n onDensityChange?.(next);\n },\n [isControlled, onDensityChange],\n );\n\n return { density, setDensity };\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport type UseDataTableSearchParams = {\n /** Controlled search. */\n search?: string;\n onSearchChange?: (value: string) => void;\n /** Tempo de debounce em ms. Default 500. */\n debounceMs?: number;\n};\n\nexport type UseDataTableSearchResult = {\n /** Valor em tempo real (sem debounce) — pra binding do input. */\n inputValue: string;\n /** Valor debounced — usado pelo processor/query. */\n debouncedValue: string;\n /** Update — atualiza input + agenda update do debounced. */\n setInputValue: (value: string) => void;\n /** Force apply imediato (pra Enter, blur). */\n flush: () => void;\n};\n\nconst DEFAULT_DEBOUNCE = 500;\n\n/**\n * Search com debounce — separa o input (rápido) do valor \"comprometido\" (lento).\n * Em client mode: debouncedValue alimenta o processor. Server mode (futuro):\n * mesma assinatura, mas aciona refetch.\n */\nexport function useDataTableSearch({\n search: controlledSearch,\n onSearchChange,\n debounceMs = DEFAULT_DEBOUNCE,\n}: UseDataTableSearchParams = {}): UseDataTableSearchResult {\n const [uncontrolled, setUncontrolled] = useState<string>(\"\");\n const isControlled = controlledSearch !== undefined;\n const inputValue = isControlled ? controlledSearch : uncontrolled;\n\n const [debouncedValue, setDebouncedValue] = useState<string>(inputValue);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Quando inputValue muda, agenda update do debounced\n useEffect(() => {\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n timeoutRef.current = setTimeout(() => {\n setDebouncedValue(inputValue);\n }, debounceMs);\n return () => {\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n };\n }, [inputValue, debounceMs]);\n\n const setInputValue = useCallback(\n (value: string) => {\n if (!isControlled) setUncontrolled(value);\n onSearchChange?.(value);\n },\n [isControlled, onSearchChange],\n );\n\n const flush = useCallback(() => {\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n setDebouncedValue(inputValue);\n }, [inputValue]);\n\n return { inputValue, debouncedValue, setInputValue, flush };\n}\n","import { useCallback, useState } from \"react\";\nimport type { FilterModel } from \"../data-table.types\";\n\nexport type UseDataTableFiltersParams = {\n filterModel?: FilterModel;\n onFilterModelChange?: (model: FilterModel) => void;\n initialFilterModel?: FilterModel;\n};\n\nexport type UseDataTableFiltersResult = {\n filterModel: FilterModel;\n setFilterModel: (model: FilterModel) => void;\n clearFilters: () => void;\n};\n\nconst EMPTY_MODEL: FilterModel = { items: [], logicOperator: \"AND\" };\n\nexport function useDataTableFilters({\n filterModel: controlled,\n onFilterModelChange,\n initialFilterModel,\n}: UseDataTableFiltersParams = {}): UseDataTableFiltersResult {\n const [uncontrolled, setUncontrolled] = useState<FilterModel>(\n initialFilterModel ?? EMPTY_MODEL,\n );\n const isControlled = controlled !== undefined;\n const filterModel = isControlled ? controlled : uncontrolled;\n\n const setFilterModel = useCallback(\n (model: FilterModel) => {\n if (!isControlled) setUncontrolled(model);\n onFilterModelChange?.(model);\n },\n [isControlled, onFilterModelChange],\n );\n\n const clearFilters = useCallback(() => {\n setFilterModel(EMPTY_MODEL);\n }, [setFilterModel]);\n\n return { filterModel, setFilterModel, clearFilters };\n}\n","import type { DataTableColumnDef } from \"../data-table.types\";\n\n/**\n * Helpers compartilhados de resolução de valor de cell.\n *\n * Antes da consolidação, 3 lugares duplicavam lógica:\n * - data-table.tsx → `resolveCellValue` (cell render)\n * - hooks/use-data-table-processor.ts → `getFieldValue` + `applyValueGetter` + `applyFormatter` (filter/sort/search)\n * - utils/group-rows.ts → `resolveGroupValue` (agrupamento)\n *\n * Agora todos consomem daqui — single source of truth pra dot-path lookup,\n * valueGetter, e valueFormatter.\n */\n\n/** Acessa valor em row via dot-path (`user.name`) ou key simples. */\nexport function getFieldValue<T>(row: T, field: string): unknown {\n if (!field.includes(\".\")) {\n return (row as Record<string, unknown>)[field];\n }\n return field\n .split(\".\")\n .reduce<unknown>(\n (acc, key) => (acc as Record<string, unknown> | null | undefined)?.[key],\n row,\n );\n}\n\n/** Resolve valor da cell: prioriza `column.valueGetter`, senão dot-path do field. */\nexport function applyValueGetter<T>(row: T, column: DataTableColumnDef<T>): unknown {\n if (column.valueGetter) return column.valueGetter(row);\n return getFieldValue(row, String(column.field));\n}\n\n/** Resolve string formatada: pega valor + aplica `column.valueFormatter` se houver. */\nexport function applyFormatter<T>(row: T, column: DataTableColumnDef<T>): string {\n const value = applyValueGetter(row, column);\n if (column.valueFormatter) return column.valueFormatter(value);\n return value == null ? \"\" : String(value);\n}\n","import { useMemo } from \"react\";\nimport type {\n DataTableColumnDef,\n FilterItem,\n FilterModel,\n PaginationModel,\n SortModel,\n} from \"../data-table.types\";\nimport { columnTypeRegistry } from \"../column-types\";\nimport {\n getFieldValue,\n applyValueGetter,\n applyFormatter,\n} from \"../utils/resolve-value\";\n\nexport type UseDataTableProcessorParams<T> = {\n rows: T[];\n columns: DataTableColumnDef<T>[];\n filterModel: FilterModel;\n search: string;\n searchField?: string; // 'all' (default) ou field específico\n /** Multi-sort: array de criterios (primeiro = prioridade maior). */\n sortModel: SortModel[];\n paginationModel: PaginationModel;\n /** Quando false, skip do slice de paginação — `rowsToRender` retorna todas as\n * rows filtradas/buscadas/ordenadas. Use quando paginationConfig.enabled=false\n * ou quando virtualize=true (virtualizer cuida do \"render só visível\"). Default true. */\n paginate?: boolean;\n};\n\nexport type UseDataTableProcessorResult<T> = {\n /** Rows visíveis depois de filter+search+sort+paginate. */\n rowsToRender: T[];\n /** Rows depois de filter+search+sort (sem paginate) — pra \"togglePage\" considerar página atual completa. */\n rowsAllPagesProcessed: T[];\n /** Total após filter+search (sem paginate) — pra footer mostrar \"1-10 de N\". */\n totalAfterFilter: number;\n};\n\n// Helpers de resolução consolidados em utils/resolve-value.ts.\n\n/* ── Filter ──────────────────────────────────────────────────────── */\n\n/**\n * Match generico — delega pro ColumnTypeRegistry quando coluna tem filterType,\n * senao usa fallback string-based.\n */\nfunction matchesFilter<T>(value: any, item: FilterItem, col: DataTableColumnDef<T> | undefined): boolean {\n const { operator } = item;\n const target = item.value;\n\n // Operadores neutros (sem valor)\n if (operator === \"isEmpty\") return value == null || value === \"\";\n if (operator === \"isNotEmpty\") return value != null && value !== \"\";\n\n // Delega pro registry quando coluna tem tipo\n if (col?.filterType) {\n const def = columnTypeRegistry.get(col.filterType);\n const result = def.matchesFilter(value, target as any, operator);\n if (result !== null) return result;\n }\n\n // Fallback string-based\n const str = value == null ? \"\" : String(value).toLowerCase();\n const targetStr = target == null ? \"\" : String(target).toLowerCase();\n switch (operator) {\n case \"contains\": return str.includes(targetStr);\n case \"equals\": return str === targetStr;\n case \"neq\": return str !== targetStr;\n case \"startsWith\": return str.startsWith(targetStr);\n case \"endsWith\": return str.endsWith(targetStr);\n case \"isAnyOf\": return Array.isArray(target) && (target as any[]).some((t) => String(t).toLowerCase() === str);\n case \"isNoneOf\": return !Array.isArray(target) || !(target as any[]).some((t) => String(t).toLowerCase() === str);\n case \"gt\": return Number(value) > Number(target);\n case \"lt\": return Number(value) < Number(target);\n case \"gte\": return Number(value) >= Number(target);\n case \"lte\": return Number(value) <= Number(target);\n default: return true;\n }\n}\n\n/**\n * Agrupa filtros por (field + operator) — items do mesmo grupo combinam por OR\n * (ex: status=A + status=B vira \"status ∈ {A,B}\"). Grupos diferentes combinam\n * por AND (ex: status ∈ {...} AND city = X).\n *\n * Pra operadores agregados (isAnyOf, isNoneOf) com array, o grupo eh trivial.\n * Pra operadores escalares (equals, contains), reagrupa items repetidos.\n */\n/** Item está \"ativo\" (deve filtrar) quando tem valor real OU operator nao\n * precisa de valor (isEmpty/isNotEmpty). Filtros com value vazio/null/array\n * vazio são ignorados — usuario abriu modal e adicionou linha mas ainda nao\n * preencheu, não deve impactar a tabela. */\nfunction isFilterItemActive(item: FilterItem): boolean {\n if (item.operator === \"isEmpty\" || item.operator === \"isNotEmpty\") return true;\n const v = item.value;\n if (v == null) return false;\n if (typeof v === \"string\") return v.length > 0;\n if (Array.isArray(v)) {\n return v.some((x) => x != null && (typeof x === \"string\" ? x.length > 0 : true));\n }\n return true;\n}\n\nfunction applyFilters<T>(rows: T[], filterModel: FilterModel, columns: DataTableColumnDef<T>[]): T[] {\n // Pula items \"em construção\" (sem valor preenchido) — eles entram no estado\n // quando user clica \"+ Adicionar\" no modal mas não devem afetar resultado.\n const activeItems = filterModel.items.filter(isFilterItemActive);\n if (activeItems.length === 0) return rows;\n const colsByField = new Map(columns.map((c) => [String(c.field), c]));\n\n // Agrupa itens por (field|operator)\n const groups = new Map<string, FilterItem[]>();\n for (const item of activeItems) {\n const key = `${item.field}|${item.operator}`;\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(item);\n }\n\n return rows.filter((row) => {\n // AND entre grupos\n for (const items of groups.values()) {\n const col = colsByField.get(items[0].field);\n const value = col ? applyValueGetter(row, col) : getFieldValue(row, items[0].field);\n // OR dentro do grupo: row passa se QUALQUER item do grupo bate\n const passes = items.some((it) => matchesFilter(value, it, col));\n if (!passes) return false;\n }\n return true;\n });\n}\n\n/* ── Search ──────────────────────────────────────────────────────── */\n\nfunction applySearch<T>(rows: T[], search: string, columns: DataTableColumnDef<T>[], searchField: string): T[] {\n if (!search.trim()) return rows;\n const needle = search.trim().toLowerCase();\n const searchableCols =\n searchField === \"all\" || !searchField\n ? columns.filter((c) => c.type !== \"actions\")\n : columns.filter((c) => String(c.field) === searchField);\n\n return rows.filter((row) =>\n searchableCols.some((col) => applyFormatter(row, col).toLowerCase().includes(needle)),\n );\n}\n\n/* ── Sort ────────────────────────────────────────────────────────── */\n\n/** Compara 2 rows num criterio especifico. */\nfunction compareByField<T>(\n a: T,\n b: T,\n field: string,\n direction: \"asc\" | \"desc\",\n columns: DataTableColumnDef<T>[],\n): number {\n const col = columns.find((c) => String(c.field) === field);\n if (!col) return 0;\n const sign = direction === \"asc\" ? 1 : -1;\n const va = applyValueGetter(a, col);\n const vb = applyValueGetter(b, col);\n if (va == null && vb == null) return 0;\n if (va == null) return 1 * sign;\n if (vb == null) return -1 * sign;\n if (typeof va === \"number\" && typeof vb === \"number\") return (va - vb) * sign;\n return String(va).localeCompare(String(vb)) * sign;\n}\n\n/** Multi-sort: aplica criterios em cascata — quebra de empate via proximo criterio. */\nfunction applySort<T>(rows: T[], sortModel: SortModel[], columns: DataTableColumnDef<T>[]): T[] {\n if (!sortModel || sortModel.length === 0) return rows;\n return [...rows].sort((a, b) => {\n for (const s of sortModel) {\n const cmp = compareByField(a, b, s.field, s.direction, columns);\n if (cmp !== 0) return cmp;\n }\n return 0;\n });\n}\n\n/* ── Pipeline cascateado ─────────────────────────────────────────── */\n\nexport function useDataTableProcessor<T>({\n rows,\n columns,\n filterModel,\n search,\n searchField = \"all\",\n sortModel,\n paginationModel,\n paginate = true,\n}: UseDataTableProcessorParams<T>): UseDataTableProcessorResult<T> {\n // 1. Filter\n const filtered = useMemo(\n () => applyFilters(rows, filterModel, columns),\n [rows, filterModel, columns],\n );\n\n // 2. Search\n const searched = useMemo(\n () => applySearch(filtered, search, columns, searchField),\n [filtered, search, columns, searchField],\n );\n\n // 3. Sort\n const sorted = useMemo(\n () => applySort(searched, sortModel, columns),\n [searched, sortModel, columns],\n );\n\n // 4. Paginate (skip quando paginate=false → retorna todas as rows filtradas)\n const paginated = useMemo(() => {\n if (!paginate) return sorted;\n const { page, pageSize } = paginationModel;\n const start = (page - 1) * pageSize;\n return sorted.slice(start, start + pageSize);\n }, [sorted, paginationModel, paginate]);\n\n return {\n rowsToRender: paginated,\n rowsAllPagesProcessed: sorted,\n totalAfterFilter: sorted.length,\n };\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport type {\n GridFetchParams,\n GridFetchResult,\n PaginationModel,\n SortModel,\n FilterModel,\n} from \"../data-table.types\";\n\nexport type UseDataTableQueryParams<T> = {\n fetchData: (params: GridFetchParams) => Promise<GridFetchResult<T>>;\n filterModel: FilterModel;\n search: string;\n searchField?: string;\n sortModel: SortModel[];\n paginationModel: PaginationModel;\n /** Loading externo (forçado pelo consumer via prop). */\n externalLoading?: boolean;\n};\n\nexport type UseDataTableQueryResult<T> = {\n /** Linhas retornadas pelo servidor pra página atual. */\n rowsToRender: T[];\n /** Total global do servidor (pra footer \"1-10 de N\"). */\n totalAfterFilter: number;\n /** True enquanto a request está em andamento. */\n isLoading: boolean;\n /** Última error string (ou null). */\n error: string | null;\n /** Dispara refetch imediato (usado por DataTableRef.refresh). */\n refresh: () => void;\n};\n\n/**\n * Server mode fetcher. Chama `fetchData(params)` quando filter/sort/pagination/search mudam.\n *\n * - Em-vôo: `isLoading=true`. Resultado anterior continua visível.\n * - Race condition guard: requests fora de ordem são descartadas via `requestIdRef`.\n * - Refresh imperativo: bump em `refreshKey` força refetch sem mudar params.\n */\nexport function useDataTableQuery<T>({\n fetchData,\n filterModel,\n search,\n searchField,\n sortModel,\n paginationModel,\n externalLoading,\n}: UseDataTableQueryParams<T>): UseDataTableQueryResult<T> {\n const [data, setData] = useState<T[]>([]);\n const [total, setTotal] = useState(0);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [refreshKey, setRefreshKey] = useState(0);\n\n // Guard contra race condition — só aplica o resultado se for da request mais recente\n const requestIdRef = useRef(0);\n\n const refresh = useCallback(() => {\n setRefreshKey((k) => k + 1);\n }, []);\n\n useEffect(() => {\n const currentId = ++requestIdRef.current;\n setIsLoading(true);\n setError(null);\n\n fetchData({\n pagination: paginationModel,\n sort: sortModel,\n filters: filterModel,\n search,\n searchField,\n })\n .then((result) => {\n // Ignora se outra request mais recente foi disparada\n if (currentId !== requestIdRef.current) return;\n setData(result.data);\n setTotal(result.total);\n setIsLoading(false);\n })\n .catch((err: unknown) => {\n if (currentId !== requestIdRef.current) return;\n setError(err instanceof Error ? err.message : String(err));\n setIsLoading(false);\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [fetchData, filterModel, search, searchField, sortModel, paginationModel, refreshKey]);\n\n return {\n rowsToRender: data,\n totalAfterFilter: total,\n isLoading: isLoading || !!externalLoading,\n error,\n refresh,\n };\n}\n","import { useCallback } from \"react\";\nimport type { DataTableColumnDef, GridRowId } from \"../data-table.types\";\n\nexport type ExportScope = \"all\" | \"filtered\" | \"selected\";\n\nexport type UseDataTableExportParams<T> = {\n columns: DataTableColumnDef<T>[];\n /** Rows visiveis na pagina atual (server) ou apos filter+sort+paginate (client). */\n rowsCurrentPage: T[];\n /** Rows apos filter+search+sort, sem paginate. Client mode tem; server tem apenas pagina atual. */\n rowsAfterFilter: T[];\n /** Rows brutas (todas, sem filter). Server mode = vazio. */\n rowsAll: T[];\n /** IDs selecionados (resolvidos do selection state). */\n selectedIds: GridRowId[];\n /** Funcao pra extrair id de uma row. */\n getRowId: (row: T) => GridRowId;\n /** Nome do arquivo (sem extensao). Default \"export\". */\n filename?: string;\n};\n\nexport type UseDataTableExportResult = {\n exportCsv: (scope: ExportScope) => void;\n};\n\n/**\n * Gera CSV no client a partir das rows do escopo escolhido.\n * Aplica `valueFormatter` da coluna quando presente, senao usa o valor cru convertido pra string.\n * Trigger de download via Blob URL + <a download>.\n */\nexport function useDataTableExport<T>({\n columns,\n rowsCurrentPage,\n rowsAfterFilter,\n rowsAll,\n selectedIds,\n getRowId,\n filename = \"export\",\n}: UseDataTableExportParams<T>): UseDataTableExportResult {\n const exportCsv = useCallback(\n (scope: ExportScope) => {\n // Seleciona rows do escopo\n let rows: T[];\n if (scope === \"all\") {\n // Client tem rowsAll; server so temos a pagina atual\n rows = rowsAll.length > 0 ? rowsAll : rowsCurrentPage;\n } else if (scope === \"filtered\") {\n rows = rowsAfterFilter;\n } else {\n // selected: filtra rowsAfterFilter por IDs selecionados\n const idSet = new Set(selectedIds);\n rows = rowsAfterFilter.filter((r) => idSet.has(getRowId(r)));\n }\n\n // Colunas exportaveis (exclui type=actions)\n const exportCols = columns.filter((c) => c.type !== \"actions\");\n\n const csv = generateCsv(rows, exportCols);\n downloadCsv(csv, `${filename}-${scope}.csv`);\n },\n [columns, rowsCurrentPage, rowsAfterFilter, rowsAll, selectedIds, getRowId, filename],\n );\n\n return { exportCsv };\n}\n\n/* -- CSV utils ----------------------------------------------------------- */\n\nfunction escapeCsvCell(value: string): string {\n // Wrap em aspas se conter virgula, aspas ou nova linha\n if (/[\",\\n\\r]/.test(value)) {\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n }\n return value;\n}\n\nfunction getCellValue<T>(row: T, col: DataTableColumnDef<T>): string {\n let value: unknown;\n if (col.valueGetter) {\n value = col.valueGetter(row);\n } else {\n const field = String(col.field);\n value = field.includes(\".\")\n ? field.split(\".\").reduce<unknown>((acc, k) => (acc as Record<string, unknown> | null)?.[k], row)\n : (row as Record<string, unknown>)[field];\n }\n if (col.valueFormatter) return col.valueFormatter(value);\n if (value == null) return \"\";\n return String(value);\n}\n\nfunction generateCsv<T>(rows: T[], columns: DataTableColumnDef<T>[]): string {\n const header = columns.map((c) => escapeCsvCell(c.headerName)).join(\",\");\n const lines = rows.map((row) =>\n columns.map((col) => escapeCsvCell(getCellValue(row, col))).join(\",\"),\n );\n return [header, ...lines].join(\"\\n\");\n}\n\nfunction downloadCsv(csv: string, filename: string): void {\n // BOM pra Excel reconhecer UTF-8\n const blob = new Blob([\"\" + csv], { type: \"text/csv;charset=utf-8\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = filename;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n}\n","import type {\n DataTableViewMode,\n GridRowId,\n SortModel,\n} from \"../data-table.types\";\nimport type { ColumnPinned, TableDensity } from \"../../Table\";\n\nconst STORAGE_PREFIX = \"igreen-datatable:\";\nconst SCHEMA_VERSION = 3; // v3: adicionado viewMode/groupBy/expandedRowIds (Default workspace completo)\n\n/** Subset persistido — exclui filters, search, page (volátil entre sessões). */\nexport type PersistedDataTableState = {\n version: number;\n density?: TableDensity;\n /** Multi-sort: array. Migrado de single object pra array em v2. */\n sortModel?: SortModel[] | null;\n pageSize?: number;\n columnWidths?: Record<string, number>;\n pinnedColumns?: Record<string, ColumnPinned>;\n hiddenColumns?: string[];\n columnOrder?: string[];\n /** Modo de visualização (table OR kanban). Persistido em v3. */\n viewMode?: DataTableViewMode;\n /** Field de agrupamento (Fase F.4). Persistido em v3. */\n groupBy?: string;\n /** Rows expandidas (Fase F.4b). Persistido em v3. */\n expandedRowIds?: GridRowId[];\n /** Ultima view ativa (preset id, saved view id, ou null pra Default). */\n lastActiveViewId?: string | null;\n};\n\nexport type LoadedPersistedState = Omit<PersistedDataTableState, \"version\">;\n\nfunction storageKey(persistId: string): string {\n return `${STORAGE_PREFIX}${persistId}`;\n}\n\n/** Le do localStorage. Retorna null se vazio, schema antigo, ou parse falhou. */\nexport function loadPersistedState(\n persistId: string | undefined,\n): LoadedPersistedState | null {\n if (!persistId || typeof window === \"undefined\") return null;\n try {\n const raw = window.localStorage.getItem(storageKey(persistId));\n if (!raw) return null;\n const parsed = JSON.parse(raw) as PersistedDataTableState;\n if (parsed.version !== SCHEMA_VERSION) return null;\n const { version: _v, ...state } = parsed;\n return state;\n } catch {\n return null;\n }\n}\n\n/** Salva no localStorage. Inclui version pro schema. */\nexport function savePersistedState(\n persistId: string | undefined,\n state: LoadedPersistedState,\n): void {\n if (!persistId || typeof window === \"undefined\") return;\n try {\n const payload: PersistedDataTableState = { version: SCHEMA_VERSION, ...state };\n window.localStorage.setItem(storageKey(persistId), JSON.stringify(payload));\n } catch {\n // localStorage cheio / disabled / quota — silencioso, persist é best-effort.\n }\n}\n\n/** Remove entry do localStorage (usado pelo reset). */\nexport function clearPersistedState(persistId: string | undefined): void {\n if (!persistId || typeof window === \"undefined\") return;\n try {\n window.localStorage.removeItem(storageKey(persistId));\n } catch {\n // ignore\n }\n}\n","import { useEffect, useRef } from \"react\";\nimport { savePersistedState, type LoadedPersistedState } from \"./state-persistence-utils\";\n\nexport type UseDataTableStatePersistenceParams = {\n persistId: string | undefined;\n /** Snapshot completo a ser salvo. O hook detecta mudanças via deep-compare leve. */\n state: LoadedPersistedState;\n /** Delay antes de salvar (debounce). Default 400ms. */\n debounceMs?: number;\n};\n\n/**\n * Persiste estado da tabela no localStorage com debounce.\n * Hidratacao acontece no controller (loadPersistedState passado como initial state pros hooks).\n * Este hook so cuida do save.\n */\nexport function useDataTableStatePersistence({\n persistId,\n state,\n debounceMs = 400,\n}: UseDataTableStatePersistenceParams): void {\n const isMountedRef = useRef(false);\n\n useEffect(() => {\n // Evita salvar no primeiro render (re-salvar o que acabou de hidratar)\n if (!isMountedRef.current) {\n isMountedRef.current = true;\n return;\n }\n if (!persistId) return;\n\n const timer = setTimeout(() => {\n savePersistedState(persistId, state);\n }, debounceMs);\n\n return () => clearTimeout(timer);\n }, [persistId, state, debounceMs]);\n}\n","import type { SavedView, SavedViewsService } from \"./saved-views.types\";\n\nconst STORAGE_PREFIX = \"igreen-datatable-views:\";\n\nfunction storageKey(persistId: string): string {\n return `${STORAGE_PREFIX}${persistId}`;\n}\n\nfunction readAll(persistId: string): SavedView[] {\n if (typeof window === \"undefined\") return [];\n try {\n const raw = window.localStorage.getItem(storageKey(persistId));\n if (!raw) return [];\n const parsed = JSON.parse(raw);\n return Array.isArray(parsed) ? parsed : [];\n } catch {\n return [];\n }\n}\n\nfunction writeAll(persistId: string, views: SavedView[]): void {\n if (typeof window === \"undefined\") return;\n try {\n window.localStorage.setItem(storageKey(persistId), JSON.stringify(views));\n } catch {\n // localStorage cheio / disabled — silencioso\n }\n}\n\n/**\n * Service mock — persiste em localStorage via key separada de state-persistence.\n * Para producao: substituir por adapter que chama API. Mesma interface, comportamento assincrono.\n */\nexport const savedViewsMockService: SavedViewsService = {\n list: async (persistId) => {\n return readAll(persistId);\n },\n save: async (persistId, view) => {\n const all = readAll(persistId);\n const idx = all.findIndex((v) => v.id === view.id);\n if (idx >= 0) {\n all[idx] = view;\n } else {\n all.push(view);\n }\n writeAll(persistId, all);\n return view;\n },\n delete: async (persistId, id) => {\n const all = readAll(persistId);\n writeAll(persistId, all.filter((v) => v.id !== id));\n },\n};\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { SavedView, SavedViewsService } from \"../services/saved-views.types\";\nimport { savedViewsMockService } from \"../services/saved-views-mock-service\";\n\nexport type UseDataTableSavedViewsParams = {\n persistId: string | undefined;\n service?: SavedViewsService;\n};\n\nexport type SaveViewOptions = {\n /** Default false (privada). Quando true, view eh marcada como publica. */\n isPublic?: boolean;\n};\n\nexport type UseDataTableSavedViewsResult = {\n views: SavedView[];\n isLoading: boolean;\n currentViewId: string | null;\n /** Salva o snapshot atual com o nome dado. Gera id novo. */\n saveView: (\n name: string,\n snapshot: SavedView[\"state\"],\n opts?: SaveViewOptions,\n ) => Promise<SavedView | null>;\n /** Remove view do servico. */\n deleteView: (id: string) => Promise<void>;\n /** Marca uma view como atualmente aplicada (logica de aplicacao fica fora do hook). */\n setCurrentViewId: (id: string | null) => void;\n};\n\nfunction generateId(): string {\n return `view-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\n/**\n * Gerencia views salvas via service (default: localStorage mock).\n * O hook lista no mount, expoe save/delete, e mantem qual view esta \"ativa\" (apenas marker).\n * Aplicacao do estado de uma view eh feita pelo controller (chama setters dos hooks SRP).\n */\nexport function useDataTableSavedViews({\n persistId,\n service = savedViewsMockService,\n}: UseDataTableSavedViewsParams): UseDataTableSavedViewsResult {\n const [views, setViews] = useState<SavedView[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [currentViewId, setCurrentViewId] = useState<string | null>(null);\n const warnedRef = useRef(false);\n\n // Warning em prod quando service nao foi customizado (spec §risks)\n useEffect(() => {\n if (warnedRef.current || !persistId) return;\n const isProd = import.meta.env?.MODE === \"production\";\n const isMock = service === savedViewsMockService;\n if (isProd && isMock) {\n // eslint-disable-next-line no-console\n console.warn(\n \"[DataTable] Saved Views mock service em production. Substitua via prop `savedViewsService` por adapter de backend persistente.\",\n );\n warnedRef.current = true;\n }\n }, [persistId, service]);\n\n // Carrega lista no mount (quando persistId esta presente)\n useEffect(() => {\n if (!persistId) return;\n let cancelled = false;\n setIsLoading(true);\n service.list(persistId)\n .then((list) => {\n if (cancelled) return;\n setViews(list);\n setIsLoading(false);\n })\n .catch(() => {\n if (cancelled) return;\n setIsLoading(false);\n });\n return () => { cancelled = true; };\n }, [persistId, service]);\n\n const saveView = useCallback(\n async (\n name: string,\n snapshot: SavedView[\"state\"],\n opts?: SaveViewOptions,\n ): Promise<SavedView | null> => {\n if (!persistId) return null;\n const view: SavedView = {\n id: generateId(),\n name: name.trim(),\n isPublic: opts?.isPublic ?? false,\n state: snapshot,\n createdAt: new Date().toISOString(),\n };\n const saved = await service.save(persistId, view);\n setViews((prev) => [...prev, saved]);\n setCurrentViewId(saved.id);\n return saved;\n },\n [persistId, service],\n );\n\n const deleteView = useCallback(\n async (id: string): Promise<void> => {\n if (!persistId) return;\n await service.delete(persistId, id);\n setViews((prev) => prev.filter((v) => v.id !== id));\n setCurrentViewId((curr) => (curr === id ? null : curr));\n },\n [persistId, service],\n );\n\n return { views, isLoading, currentViewId, saveView, deleteView, setCurrentViewId };\n}\n","import { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from \"react\";\nimport type { Ref } from \"react\";\nimport type {\n DataTableProps,\n DataTablePresetView,\n DataTableRef,\n DataTableState,\n DataTableViewMode,\n GridFetchParams,\n GridFetchResult,\n GridRowId,\n} from \"../data-table.types\";\nimport type { DataTableContextValue } from \"../context/data-table-context\";\nimport { useDataTableColumns } from \"./use-data-table-columns\";\nimport { useDataTableSort } from \"./use-data-table-sort\";\nimport { useDataTablePagination } from \"./use-data-table-pagination\";\nimport { useDataTableSelection } from \"./use-data-table-selection\";\nimport { useDataTableDensity } from \"./use-data-table-density\";\nimport { useDataTableSearch } from \"./use-data-table-search\";\nimport { useDataTableFilters } from \"./use-data-table-filters\";\nimport { useDataTableProcessor } from \"./use-data-table-processor\";\nimport { useDataTableQuery } from \"./use-data-table-query\";\nimport { useDataTableExport } from \"./use-data-table-export\";\nimport { useDataTableStatePersistence } from \"./use-data-table-state-persistence\";\nimport { loadPersistedState, clearPersistedState } from \"./state-persistence-utils\";\nimport { useDataTableSavedViews } from \"./use-data-table-saved-views\";\nimport type { SavedView, SavedViewsService } from \"../services/saved-views.types\";\n// Side-effect: registra os tipos default no ColumnTypeRegistry\nimport \"../column-types\";\n\n/** No-op fetch usado quando estamos em client mode — referência estável evita re-renders. */\nconst NOOP_FETCH = async (_params: GridFetchParams): Promise<GridFetchResult<never>> => ({ data: [], total: 0 });\n\nconst DEFAULT_GET_ROW_ID = (row: any): GridRowId => row.id;\n\nexport function useDataTableController<T>(\n props: DataTableProps<T>,\n ref: Ref<DataTableRef>,\n) {\n const getRowId = props.getRowId ?? (DEFAULT_GET_ROW_ID as (row: T) => GridRowId);\n\n /* ── Hidrata estado persistido (localStorage) ─────────────────── */\n\n // Lazy: roda uma vez via useMemo. persistId estavel entre renders.\n const persistedInitial = useMemo(\n () => loadPersistedState(props.persistId),\n [props.persistId],\n );\n\n /* ── Hooks SRP ────────────────────────────────────────────────── */\n\n const cols = useDataTableColumns({\n columns: props.columns,\n initialWidthOverrides: persistedInitial?.columnWidths,\n initialPinnedOverrides: persistedInitial?.pinnedColumns,\n initialHiddenColumns: persistedInitial?.hiddenColumns,\n initialColumnOrder: persistedInitial?.columnOrder,\n });\n\n const sort = useDataTableSort({\n sortModel: props.sortModel,\n onSortModelChange: props.onSortModelChange,\n initialSortModel: persistedInitial?.sortModel,\n });\n\n const filters = useDataTableFilters({\n filterModel: props.filterModel,\n onFilterModelChange: props.onFilterModelChange,\n });\n\n const search = useDataTableSearch({\n search: props.search,\n onSearchChange: props.onSearchChange,\n });\n\n // Pagination com auto-reset quando filtros/search mudam\n const pagination = useDataTablePagination({\n paginationModel: props.paginationModel,\n onPaginationModelChange: props.onPaginationModelChange,\n initialPageSize:\n persistedInitial?.pageSize ?? props.paginationConfig?.initialPageSize,\n resetTriggers: [filters.filterModel.items.length, search.debouncedValue],\n });\n\n const density = useDataTableDensity({\n density: props.density,\n onDensityChange: props.onDensityChange,\n initialDensity: persistedInitial?.density,\n });\n\n /* ── viewMode + groupBy + expandedRowIds — controlled/uncontrolled hybrid\n *\n * Centralizados aqui (em vez de em `data-table.tsx`) pra que `applyView`\n * possa restaurá-los junto com filter/sort/density/layout. Padrão:\n * - Se prop controlled passada → usa prop (read-only); setter dispara callback\n * - Senão → usa state interno + chama callback se fornecido\n *\n * Saved views podem alternar esses 3 fields via `applyView` (sempre dispara\n * o callback). Builder `presetView()` pode declarar `viewMode/groupBy/\n * expandedRowIds` em presets read-only. */\n const [internalViewMode, setInternalViewMode] = useState<DataTableViewMode>(\n // Hidrata do localStorage (v3+) com fallback pra prop `defaultViewMode`\n persistedInitial?.viewMode ?? props.defaultViewMode ?? \"table\",\n );\n const viewMode: DataTableViewMode = props.viewMode ?? internalViewMode;\n const setViewMode = useCallback((mode: DataTableViewMode) => {\n if (props.viewMode === undefined) setInternalViewMode(mode);\n props.onViewModeChange?.(mode);\n }, [props.viewMode, props.onViewModeChange]);\n\n const [internalGroupBy, setInternalGroupBy] = useState<string | undefined>(\n persistedInitial?.groupBy ?? props.defaultGroupBy,\n );\n const groupBy: string | undefined = props.groupBy ?? internalGroupBy;\n const setGroupBy = useCallback((next: string | undefined) => {\n if (props.groupBy === undefined) setInternalGroupBy(next);\n props.onGroupByChange?.(next);\n }, [props.groupBy, props.onGroupByChange]);\n\n const [internalExpandedRowIds, setInternalExpandedRowIdsRaw] = useState<GridRowId[]>(\n () => persistedInitial?.expandedRowIds ?? props.defaultExpandedRowIds ?? [],\n );\n const expandedRowIds: GridRowId[] = props.expandedRowIds ?? internalExpandedRowIds;\n const setExpandedRowIds = useCallback((next: GridRowId[]) => {\n if (props.expandedRowIds === undefined) setInternalExpandedRowIdsRaw(next);\n props.onExpandedRowIdsChange?.(next);\n }, [props.expandedRowIds, props.onExpandedRowIdsChange]);\n\n /** Toggle de uma row específica. Respeita `singleExpand` (default false). */\n const toggleRowExpansion = useCallback((id: GridRowId) => {\n const current = props.expandedRowIds ?? internalExpandedRowIds;\n const has = current.includes(id);\n let next: GridRowId[];\n if (has) {\n next = current.filter((x) => x !== id);\n } else if (props.singleExpand) {\n next = [id];\n } else {\n next = [...current, id];\n }\n setExpandedRowIds(next);\n }, [props.expandedRowIds, internalExpandedRowIds, props.singleExpand, setExpandedRowIds]);\n\n /* ── Modo: client (rows) vs server (fetchData) ───────────────── */\n\n const isServerMode = !!props.fetchData;\n const clientRows = props.rows ?? [];\n\n /* ── Processor (client mode pipeline) ────────────────────────── */\n\n // Skip paginate quando:\n // - paginationConfig.enabled === false (consumer não quer paginação)\n // - props.virtualize (virtualizer cuida do \"render só visível\", precisa de\n // todas as rows pra calcular scroll height total)\n // - groupBy state (Fase F.4: agrupamento precisa de todas as rows pra montar\n // grupos completos; paginar quebraria o conceito)\n const shouldPaginate =\n props.paginationConfig?.enabled !== false &&\n !props.virtualize &&\n !groupBy;\n\n const processed = useDataTableProcessor({\n rows: isServerMode ? [] : clientRows,\n columns: props.columns,\n filterModel: filters.filterModel,\n search: search.debouncedValue,\n sortModel: sort.sortModels,\n paginationModel: pagination.paginationModel,\n paginate: shouldPaginate,\n });\n\n /* ── Query (server mode) — só executa quando fetchData presente ── */\n\n const query = useDataTableQuery({\n // Quando fetchData é undefined, passamos uma função no-op estável\n // pra não quebrar a regra de hooks. A useEffect interna roda em ambos\n // os modos, mas em client mode o NOOP_FETCH não causa fetch real.\n fetchData: props.fetchData ?? NOOP_FETCH,\n filterModel: filters.filterModel,\n search: search.debouncedValue,\n searchField: undefined,\n sortModel: sort.sortModels,\n paginationModel: pagination.paginationModel,\n externalLoading: props.loading,\n });\n\n // Seleciona output baseado no modo\n const effectiveRows = isServerMode ? query.rowsToRender : processed.rowsToRender;\n const effectiveTotal = isServerMode\n ? (props.rowCount ?? query.totalAfterFilter)\n : processed.totalAfterFilter;\n const allPagesProcessed = isServerMode ? query.rowsToRender : processed.rowsAllPagesProcessed;\n\n const selection = useDataTableSelection({\n rows: allPagesProcessed,\n getRowId,\n selectionModel: props.selectionModel,\n onSelectionModelChange: props.onSelectionModelChange,\n });\n\n /* ── Export (CSV) ─────────────────────────────────────────────── */\n\n const exportHook = useDataTableExport({\n columns: props.columns,\n rowsCurrentPage: effectiveRows,\n rowsAfterFilter: allPagesProcessed,\n rowsAll: clientRows, // server mode = [] (usa pagina atual via scope fallback)\n selectedIds: selection.selectedIds,\n getRowId,\n filename: props.toolbar?.title?.toLowerCase().replace(/\\s+/g, \"-\") ?? \"export\",\n });\n\n /* ── Estados de feedback ──────────────────────────────────────── */\n\n const isLoading = isServerMode ? query.isLoading : !!props.loading;\n const totalRowsForEmpty = isServerMode\n ? effectiveTotal\n : clientRows.length;\n const isDataEmpty = !isLoading && totalRowsForEmpty === 0 && effectiveRows.length === 0;\n const isNoResults =\n !isLoading &&\n !isDataEmpty &&\n effectiveTotal === 0 &&\n (filters.filterModel.items.length > 0 || search.debouncedValue.length > 0);\n\n /* ── Snapshot do estado pra getState() ───────────────────────── */\n\n const getState = useCallback((): DataTableState => ({\n density: density.density,\n sortModel: sort.sortModels,\n paginationModel: pagination.paginationModel,\n selectionModel: selection.state,\n filterModel: filters.filterModel,\n search: search.debouncedValue,\n columnWidths: cols.columnWidths,\n pinnedColumns: cols.pinnedColumns,\n hiddenColumns: cols.hiddenColumns,\n columnOrder: cols.columnOrder,\n }), [\n density.density,\n sort.sortModels,\n pagination.paginationModel,\n selection.state,\n filters.filterModel,\n search.debouncedValue,\n cols.columnWidths,\n cols.pinnedColumns,\n cols.hiddenColumns,\n cols.columnOrder,\n ]);\n\n /* ── Saved Views ──────────────────────────────────────────────── */\n\n const savedViews = useDataTableSavedViews({\n persistId: props.persistId,\n service: props.savedViewsService,\n });\n\n /* ── Persist (localStorage) — salva debounced quando state muda ──\n *\n * Estratégia \"Default workspace\":\n * - O `defaultSnapshotRef` rastreia o estado APENAS quando `currentViewId === null`\n * (usuário está na tab Default). Quando uma view específica (preset/saved)\n * está aplicada, o defaultSnapshot fica congelado.\n * - O `applyDefault` lê do defaultSnapshotRef → restaura o \"workspace pessoal\"\n * do usuário, NÃO zera tudo.\n * - O persistedSnapshot completo continua sendo salvo (pra hidratação no\n * próximo mount) — inclusive quando uma view está aplicada. O\n * `lastActiveViewId` re-aplica a view, e o defaultSnapshot fica disponível\n * pra quando o usuário clicar Default. */\n\n const persistedSnapshot = useMemo(() => ({\n density: density.density,\n sortModel: sort.sortModels,\n pageSize: pagination.paginationModel.pageSize,\n columnWidths: cols.columnWidths,\n pinnedColumns: cols.pinnedColumns,\n hiddenColumns: Array.from(cols.hiddenColumns),\n columnOrder: cols.columnOrder,\n // Fase v3 — features novas também persistem (workspace completo da Default)\n viewMode,\n groupBy,\n expandedRowIds,\n // Persistir ultima view ativa (preset id, saved view id, ou null pra Default)\n lastActiveViewId: savedViews.currentViewId,\n }), [\n density.density,\n sort.sortModels,\n pagination.paginationModel.pageSize,\n cols.columnWidths,\n cols.pinnedColumns,\n cols.hiddenColumns,\n cols.columnOrder,\n viewMode,\n groupBy,\n expandedRowIds,\n savedViews.currentViewId,\n ]);\n\n /**\n * Snapshot do workspace \"Default\" do usuário — atualizado APENAS quando\n * nenhuma view específica está aplicada. Usado pelo `applyDefault` pra\n * restaurar o estado que o usuário tinha antes de clicar numa view.\n *\n * Inicializado com persistedInitial (hidratação do mount). Atualizado em\n * useEffect sempre que persistedSnapshot muda E currentViewId === null.\n */\n const defaultSnapshotRef = useRef(persistedInitial);\n useEffect(() => {\n if (savedViews.currentViewId === null) {\n // Salva snapshot sem o lastActiveViewId (sempre null pra defaults)\n const { lastActiveViewId: _ignore, ...rest } = persistedSnapshot;\n defaultSnapshotRef.current = rest;\n }\n }, [persistedSnapshot, savedViews.currentViewId]);\n\n useDataTableStatePersistence({\n persistId: props.persistId,\n state: persistedSnapshot,\n });\n\n /**\n * Aplica TODOS os campos capturáveis de uma view (saved OR preset).\n * Campos ausentes na view → aplica defaults razoáveis:\n * - layout (columnWidths/pinned/hidden/order) → `{}`/`[]`\n * - viewMode → \"table\" (default histórico)\n * - groupBy → undefined (sem agrupamento)\n * - expandedRowIds → [] (todas colapsadas)\n *\n * Comportamento idêntico pra saved view e preset view (mesmo shape de state).\n */\n const applyViewState = useCallback(\n (id: string, state: import(\"../services/saved-views.types\").DataTableSavedViewState) => {\n density.setDensity(state.density);\n sort.setSortModels(state.sortModel);\n filters.setFilterModel(state.filterModel);\n cols.applyColumnState({\n columnWidths: state.columnWidths,\n pinnedColumns: state.pinnedColumns,\n hiddenColumns: state.hiddenColumns,\n columnOrder: state.columnOrder,\n });\n // Features novas — fallback explícito quando campo ausente (views antigas)\n setViewMode(state.viewMode ?? \"table\");\n setGroupBy(state.groupBy);\n setExpandedRowIds(state.expandedRowIds ?? []);\n savedViews.setCurrentViewId(id);\n },\n [density, sort, filters, cols, setViewMode, setGroupBy, setExpandedRowIds, savedViews],\n );\n\n const applyView = useCallback(\n (view: SavedView) => applyViewState(view.id, view.state),\n [applyViewState],\n );\n\n /** Aplica preset view (read-only) — mesma lógica do applyView (state unificado). */\n const applyPresetView = useCallback(\n (preset: DataTablePresetView) => applyViewState(preset.id, preset.state),\n [applyViewState],\n );\n\n /**\n * Apply unificado por id — procura primeiro em defaultViews (presets), depois\n * em savedViews. Usado pelo TableToolbarViews via onApply(id).\n */\n const applyViewById = useCallback(\n (id: string) => {\n const preset = props.defaultViews?.find((v) => v.id === id);\n if (preset) {\n applyPresetView(preset);\n return;\n }\n const saved = savedViews.views.find((v) => v.id === id);\n if (saved) applyView(saved);\n },\n [props.defaultViews, savedViews.views, applyPresetView, applyView],\n );\n\n /* ── Restore lastActiveViewId no mount (depois de savedViews carregar) ── */\n\n const restoredRef = useRef(false);\n useEffect(() => {\n if (restoredRef.current) return;\n if (!props.persistId) return;\n // Espera savedViews terminar de carregar pra ter a lista completa pra lookup\n if (savedViews.isLoading) return;\n restoredRef.current = true;\n\n const lastId = persistedInitial?.lastActiveViewId;\n if (!lastId) return;\n\n // Tenta preset primeiro, depois saved\n const preset = props.defaultViews?.find((v) => v.id === lastId);\n if (preset) {\n applyPresetView(preset);\n return;\n }\n const saved = savedViews.views.find((v) => v.id === lastId);\n if (saved) applyView(saved);\n }, [\n props.persistId,\n persistedInitial,\n savedViews.isLoading,\n savedViews.views,\n props.defaultViews,\n applyPresetView,\n applyView,\n ]);\n\n const saveCurrentAsView = useCallback(\n (name: string, opts?: { isPublic?: boolean }) => {\n return savedViews.saveView(\n name,\n {\n filterModel: filters.filterModel,\n sortModel: sort.sortModels,\n density: density.density,\n columnWidths: cols.columnWidths,\n pinnedColumns: cols.pinnedColumns,\n hiddenColumns: Array.from(cols.hiddenColumns),\n columnOrder: cols.columnOrder,\n // Features novas — capturadas no snapshot\n viewMode,\n groupBy,\n expandedRowIds,\n },\n opts,\n );\n },\n [\n savedViews,\n filters.filterModel,\n sort.sortModels,\n density.density,\n cols.columnWidths,\n cols.pinnedColumns,\n cols.hiddenColumns,\n cols.columnOrder,\n viewMode,\n groupBy,\n expandedRowIds,\n ],\n );\n\n /**\n * Tab \"Default\" — restaura o \"workspace pessoal\" do usuário (estado salvo\n * no localStorage), NÃO zera tudo.\n *\n * Quando `persistId` está presente:\n * - Lê do `defaultSnapshotRef.current` (mantido em sincronia conforme o\n * usuário mexia na Default antes de aplicar uma view).\n * - Filters/search permanecem voláteis (sempre limpos na transição pra Default,\n * porque não persistem no localStorage por design).\n *\n * Quando `persistId` ausente (sem persistence):\n * - Comportamento legado: zera tudo (Default = empty state).\n */\n const applyDefault = useCallback(() => {\n const snapshot = props.persistId ? defaultSnapshotRef.current : null;\n\n if (snapshot) {\n density.setDensity(snapshot.density ?? \"standard\");\n sort.setSortModels(snapshot.sortModel ?? []);\n cols.applyColumnState({\n columnWidths: snapshot.columnWidths ?? {},\n pinnedColumns: snapshot.pinnedColumns ?? {},\n hiddenColumns: snapshot.hiddenColumns ?? [],\n columnOrder: snapshot.columnOrder ?? props.columns.map((c) => String(c.field)),\n });\n setViewMode(snapshot.viewMode ?? \"table\");\n setGroupBy(snapshot.groupBy);\n setExpandedRowIds(snapshot.expandedRowIds ?? []);\n } else {\n // Sem persistId: comportamento legado (empty state)\n density.setDensity(\"standard\");\n sort.setSortModels([]);\n cols.applyColumnState({\n columnWidths: {},\n pinnedColumns: {},\n hiddenColumns: [],\n columnOrder: props.columns.map((c) => String(c.field)),\n });\n setViewMode(\"table\");\n setGroupBy(undefined);\n setExpandedRowIds([]);\n }\n\n // Filters/search são voláteis (sessão) — sempre limpos na transição pra Default\n filters.setFilterModel({ items: [], logicOperator: \"AND\" });\n savedViews.setCurrentViewId(null);\n }, [props.persistId, props.columns, density, sort, filters, cols, setViewMode, setGroupBy, setExpandedRowIds, savedViews]);\n\n /* ── Imperative ref ──────────────────────────────────────────── */\n\n useImperativeHandle(ref, () => ({\n refresh: () => {\n if (isServerMode) query.refresh();\n // Client mode: refresh é no-op (rows já estão em memória).\n },\n getState,\n getSelectedIds: () => selection.selectedIds,\n getSelectedCount: () => selection.selectedCount,\n clearSelection: selection.clear,\n exportCsv: exportHook.exportCsv,\n resetPersistedState: () => {\n clearPersistedState(props.persistId);\n },\n }), [getState, selection, isServerMode, query, exportHook, props.persistId]);\n\n /* ── Context value memoizado ─────────────────────────────────── */\n\n const contextValue = useMemo<DataTableContextValue<T>>(() => ({\n rows: clientRows,\n effectiveColumns: cols.effectiveColumns,\n columnWidths: cols.columnWidths,\n stickyOffsets: cols.stickyOffsets,\n columnOrder: cols.columnOrder,\n hiddenColumns: cols.hiddenColumns,\n pinnedColumns: cols.pinnedColumns,\n sortModel: sort.sortModels,\n paginationModel: pagination.paginationModel,\n selection: {\n state: selection.state,\n isRowSelected: selection.isRowSelected,\n selectedCount: selection.selectedCount,\n },\n density: density.density,\n search: search.inputValue,\n filterModel: filters.filterModel,\n getRowId,\n }), [\n clientRows,\n cols.effectiveColumns,\n cols.columnWidths,\n cols.stickyOffsets,\n cols.columnOrder,\n cols.hiddenColumns,\n cols.pinnedColumns,\n sort.sortModels,\n pagination.paginationModel,\n selection.state,\n selection.isRowSelected,\n selection.selectedCount,\n density.density,\n search.inputValue,\n filters.filterModel,\n getRowId,\n ]);\n\n return {\n contextValue,\n isLoading,\n isDataEmpty,\n isNoResults,\n rowsToRender: effectiveRows,\n /** Todas as rows após filter/search/sort (sem paginate) — usado por totalizers\n * pra agregar sobre tudo, nao só pagina atual. Em server mode = current page. */\n rowsAllPagesProcessed: allPagesProcessed,\n totalAfterFilter: effectiveTotal,\n cols,\n sort,\n pagination,\n selection,\n density,\n search,\n filters,\n exportHook,\n isServerMode,\n savedViews,\n applyView,\n applyViewById,\n applyDefault,\n saveCurrentAsView,\n query,\n // States novos centralizados (controlled/uncontrolled)\n viewMode,\n setViewMode,\n groupBy,\n setGroupBy,\n expandedRowIds,\n setExpandedRowIds,\n toggleRowExpansion,\n };\n}\n","import type { ReactNode } from \"react\";\nimport { Inbox } from \"lucide-react\";\n\nexport type DataTableEmptyProps = {\n /** Icone na ilustração. Default: Inbox. Renderizado dentro de circulo com bg-bg-muted. */\n icon?: ReactNode;\n /** Titulo principal. Default: \"Nenhum dado cadastrado\". */\n title?: string;\n /** Descricao secundaria. Default: orientacao de proximos passos. */\n description?: string;\n /** Acao primaria — ex: <Button>Adicionar</Button>. Renderizada abaixo da descricao. */\n action?: ReactNode;\n};\n\n/**\n * Estado vazio (dataset sem nenhum registro). Usado quando a tabela nao tem\n * dados em absoluto — diferente de NoResults (que aplica quando filtros zeraram).\n *\n * Estrutura: ilustracao circular > titulo > descricao > acao opcional.\n * Consumer pode customizar via props ou substituir 100% via `props.renderEmpty`.\n */\nexport function DataTableEmpty({\n icon = <Inbox aria-hidden />,\n title = \"Nenhum dado cadastrado\",\n description = \"Comece adicionando novos itens para visualizar aqui.\",\n action,\n}: DataTableEmptyProps = {}) {\n return (\n <div className=\"flex-1 min-h-0 flex flex-col items-center justify-center gap-gp-lg p-pad-4xl text-center\">\n <div\n className=\"flex items-center justify-center size-[80px] rounded-full bg-bg-muted [&_svg]:size-icon-2xl [&_svg]:text-fg-muted\"\n aria-hidden\n >\n {icon}\n </div>\n <div className=\"flex flex-col gap-gp-2xs items-center\">\n <p className=\"text-title-md text-fg-strong\">{title}</p>\n <p className=\"text-paragraph-sm text-fg-muted max-w-[360px]\">\n {description}\n </p>\n </div>\n {action && <div className=\"mt-pad-md\">{action}</div>}\n </div>\n );\n}\n","/**\n * DataTableLoading — esqueleto de loading que simula a estrutura da tabela.\n *\n * Renderiza header bar + N rows com células fluidas que se distribuem em todas\n * as colunas — visualmente próximo da tabela final pra evitar layout shift quando\n * dados chegam. Cada cell tem placeholder bg-bg-muted animate-pulse com largura\n * relativa (50-90% da cell) pra parecer texto real.\n */\nexport type DataTableLoadingProps = {\n /** Quantas linhas fake renderizar. Default 10. */\n rows?: number;\n /** Quantas colunas fake renderizar. Default 6. */\n columns?: number;\n};\n\nexport function DataTableLoading({\n rows = 10,\n columns = 6,\n}: DataTableLoadingProps = {}) {\n // Pesos pra distribuir colunas (1 = base; 2 = duas vezes maior).\n // Primeira coluna mais estreita (ID/checkbox), segunda mais larga (nome),\n // demais variando. Repete o padrão se columns > 6.\n const widthPattern = [0.5, 1.5, 1.4, 1.2, 1, 0.9];\n // Larguras INTERNAS da placeholder dentro da cell (% — varia pra parecer texto)\n const innerPattern = [70, 85, 75, 60, 80, 65];\n\n return (\n <div\n role=\"status\"\n aria-label=\"Carregando dados\"\n aria-busy=\"true\"\n // Mesmo container do Table primitivo (table.styles.ts → root) — garante\n // que skeleton tenha bordas, radius e shadow idênticos ao estado loaded,\n // evitando o \"salto visual\" quando dados chegam (quadrado → arredondado).\n className=\"flex flex-col w-full bg-bg-table border border-border-table rounded-radius-xl shadow-sh-sm overflow-hidden\"\n >\n {/* Header fake — barra mais escura simulando o head da tabela */}\n <div className=\"flex w-full h-[42px] items-center px-pad-2xl gap-gp-2xl border-b border-border-table bg-bg-table-head\">\n {Array.from({ length: columns }).map((_, colIdx) => (\n <div\n key={colIdx}\n className=\"flex-1 min-w-0\"\n style={{ flex: widthPattern[colIdx % widthPattern.length] }}\n >\n <div\n className=\"h-3 rounded-radius-sm bg-bg-muted animate-pulse\"\n style={{ width: `${innerPattern[colIdx % innerPattern.length]}%` }}\n />\n </div>\n ))}\n </div>\n\n {/* Body rows fake */}\n {Array.from({ length: rows }).map((_, rowIdx) => (\n <div\n key={rowIdx}\n className=\"flex w-full h-[56px] items-center px-pad-2xl gap-gp-2xl border-b border-border-table last:border-b-0\"\n >\n {Array.from({ length: columns }).map((_, colIdx) => {\n // Variacao pseudo-random estavel pra evitar todas linhas identicas\n const seed = (rowIdx * 31 + colIdx * 17) % 100;\n const width = 40 + ((seed * 1.5) % 50); // 40-90%\n return (\n <div\n key={colIdx}\n className=\"flex-1 min-w-0\"\n style={{ flex: widthPattern[colIdx % widthPattern.length] }}\n >\n <div\n className=\"h-form-sm rounded-radius-md bg-bg-muted animate-pulse\"\n style={{\n width: `${width}%`,\n animationDelay: `${(rowIdx * 60 + colIdx * 30) % 600}ms`,\n }}\n />\n </div>\n );\n })}\n </div>\n ))}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { SearchX, FilterX } from \"lucide-react\";\nimport { Button } from \"../../Button/button\";\n\nexport type DataTableNoResultsProps = {\n /** Icone na ilustracao. Default: SearchX. */\n icon?: ReactNode;\n /** Titulo principal. Default: \"Nenhum dado encontrado\". */\n title?: string;\n /** Descricao secundaria. */\n description?: string;\n /** Acao primaria customizada — substitui o botao \"Limpar filtros\" default. */\n action?: ReactNode;\n /** Callback que limpa filtros — quando definido SEM `action`, renderiza\n * botao default \"Limpar filtros\". DataTable auto-wira isso pra\n * filters.clearFilters / search.flush. */\n onClearFilters?: () => void;\n};\n\n/**\n * Estado \"nada encontrado com filtros aplicados\". Diferente de Empty\n * (dataset vazio em absoluto). Sugere ajustar/limpar filtros.\n *\n * Auto-wire: DataTable passa `onClearFilters` que limpa filterModel + search.\n * Consumer pode customizar via props ou substituir 100% via `props.renderNoResults`.\n */\nexport function DataTableNoResults({\n icon = <SearchX aria-hidden />,\n title = \"Nenhum dado encontrado\",\n description = \"Não encontramos nada com os critérios pesquisados. Tente ajustar os filtros.\",\n action,\n onClearFilters,\n}: DataTableNoResultsProps = {}) {\n // Render default action quando onClearFilters definido E action nao customizado\n const resolvedAction =\n action ??\n (onClearFilters ? (\n <Button\n size=\"sm\"\n variant=\"outline\"\n color=\"secondary\"\n iconLeft={<FilterX />}\n onClick={onClearFilters}\n >\n Limpar filtros\n </Button>\n ) : null);\n\n return (\n <div className=\"flex-1 min-h-0 flex flex-col items-center justify-center gap-gp-lg p-pad-4xl text-center\">\n <div\n className=\"flex items-center justify-center size-[80px] rounded-full bg-bg-muted [&_svg]:size-icon-2xl [&_svg]:text-fg-muted\"\n aria-hidden\n >\n {icon}\n </div>\n <div className=\"flex flex-col gap-gp-2xs items-center\">\n <p className=\"text-title-md text-fg-strong\">{title}</p>\n <p className=\"text-paragraph-sm text-fg-muted max-w-[360px]\">\n {description}\n </p>\n </div>\n {resolvedAction && <div className=\"mt-pad-md\">{resolvedAction}</div>}\n </div>\n );\n}\n","import { useEffect, useState, type ReactNode } from \"react\";\nimport {\n ArrowUp,\n ArrowDown,\n PinIcon,\n PinOff,\n EyeOff,\n MoreHorizontal,\n X as XIcon,\n} from \"lucide-react\";\nimport { Button } from \"../../Button/button\";\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n} from \"../../../shadcn/dropdown-menu\";\n\nexport type DataTableColumnMenuItem = {\n id: string;\n label: ReactNode;\n icon?: ReactNode;\n onSelect?: () => void;\n destructive?: boolean;\n disabled?: boolean;\n};\n\nexport type DataTableColumnMenuProps = {\n /** Nome da coluna (usado no aria-label). */\n columnName: string;\n /** Direção atual do sort (null = sem sort). */\n sortDirection: \"asc\" | \"desc\" | null;\n /** Pin atual (null = sem pin). */\n pinned: \"left\" | \"right\" | null;\n /** Pode esconder essa coluna? Default true. */\n canHide?: boolean;\n /** Handlers — null disabled */\n onSortAsc?: () => void;\n onSortDesc?: () => void;\n onSortClear?: () => void;\n onPinLeft?: () => void;\n onPinRight?: () => void;\n onUnpin?: () => void;\n onHide?: () => void;\n /** Items extras (slot pro consumer adicionar). */\n extraItems?: DataTableColumnMenuItem[];\n};\n\n/**\n * Menu 3-pontos no header de cada coluna do DataTable.\n * Acoes: Sort asc/desc/clear, Pin left/right/unpin, Hide column, extras.\n */\nexport function DataTableColumnMenu({\n columnName,\n sortDirection,\n pinned,\n canHide = true,\n onSortAsc,\n onSortDesc,\n onSortClear,\n onPinLeft,\n onPinRight,\n onUnpin,\n onHide,\n extraItems,\n}: DataTableColumnMenuProps) {\n // Controlled open + keepMounted: mantem o botão visível durante a animação\n // de fechamento do portal (~200ms). Sem isso, o seletor :has([data-state=open])\n // do wrapper headMenuItem perde o match assim que Radix muda pra \"closed\", o\n // botao some e o portal animando pisca em (0,0) por ter perdido a âncora.\n const [open, setOpen] = useState(false);\n const [keepMounted, setKeepMounted] = useState(false);\n\n useEffect(() => {\n if (open) {\n setKeepMounted(true);\n return;\n }\n if (!keepMounted) return;\n const t = setTimeout(() => setKeepMounted(false), 200);\n return () => clearTimeout(t);\n }, [open, keepMounted]);\n\n return (\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger asChild>\n <Button\n size=\"icon-2xs\"\n variant=\"ghost\"\n color=\"secondary\"\n aria-label={`Menu da coluna ${columnName}`}\n // data-menu-active fica true durante toda a vida do menu (abrindo,\n // aberto e janela de close animation). Wrapper headMenuItem usa\n // :has([data-menu-active=true]) pra continuar visivel.\n data-menu-active={keepMounted || undefined}\n // Interrompe propagacao em TODOS os eventos relevantes pra evitar\n // que o header sortable dispare handleSort enquanto o menu abre\n // (re-render durante anchor calculation faz o portal teleportar).\n onClick={(e) => e.stopPropagation()}\n onPointerDown={(e) => e.stopPropagation()}\n onMouseDown={(e) => e.stopPropagation()}\n >\n <MoreHorizontal />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" onClick={(e) => e.stopPropagation()}>\n {/* Sort */}\n <DropdownMenuItem\n onClick={onSortAsc}\n disabled={sortDirection === \"asc\"}\n >\n <ArrowUp className=\"size-icon-xs\" />\n Ordenar crescente\n </DropdownMenuItem>\n <DropdownMenuItem\n onClick={onSortDesc}\n disabled={sortDirection === \"desc\"}\n >\n <ArrowDown className=\"size-icon-xs\" />\n Ordenar decrescente\n </DropdownMenuItem>\n {sortDirection !== null && (\n <DropdownMenuItem onClick={onSortClear}>\n <XIcon className=\"size-icon-xs\" />\n Limpar ordenação\n </DropdownMenuItem>\n )}\n\n <DropdownMenuSeparator />\n\n {/* Pin */}\n {pinned !== \"left\" && (\n <DropdownMenuItem onClick={onPinLeft}>\n <PinIcon className=\"size-icon-xs\" />\n Fixar à esquerda\n </DropdownMenuItem>\n )}\n {pinned !== \"right\" && (\n <DropdownMenuItem onClick={onPinRight}>\n <PinIcon className=\"size-icon-xs\" />\n Fixar à direita\n </DropdownMenuItem>\n )}\n {pinned !== null && (\n <DropdownMenuItem onClick={onUnpin}>\n <PinOff className=\"size-icon-xs\" />\n Remover fixação\n </DropdownMenuItem>\n )}\n\n {canHide && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem onClick={onHide}>\n <EyeOff className=\"size-icon-xs\" />\n Ocultar coluna\n </DropdownMenuItem>\n </>\n )}\n\n {extraItems && extraItems.length > 0 && (\n <>\n <DropdownMenuSeparator />\n {extraItems.map((item) => (\n <DropdownMenuItem\n key={item.id}\n onClick={item.onSelect}\n disabled={item.disabled}\n variant={item.destructive ? \"destructive\" : \"default\"}\n >\n {item.icon}\n {item.label}\n </DropdownMenuItem>\n ))}\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n","import { MoreHorizontal } from \"lucide-react\";\nimport { Button } from \"../../Button/button\";\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n} from \"../../../shadcn/dropdown-menu\";\nimport type { DataTableActionItem } from \"../data-table.types\";\n\nexport type DataTableActionsCellProps<T> = {\n /** Row da linha — passado pra disabled/hidden/onClick. */\n row: T;\n /** Lista de actions resolvida pra esta row. */\n actions: DataTableActionItem<T>[];\n};\n\n/**\n * Celula da coluna `type: \"actions\"` — renderiza icone-buttons inline\n * (items com `showInMenu` false ou undefined) e/ou dropdown 3-pontos\n * (items com `showInMenu: true`).\n *\n * Items com `hidden(row) === true` somem completamente. Items com\n * `disabled(row) === true` ficam atenuados e sem click.\n *\n * Stopa propagacao no click do botao/menu pra nao disparar `onRowClick`\n * do TableRow ancestral.\n */\nexport function DataTableActionsCell<T>({\n row,\n actions,\n}: DataTableActionsCellProps<T>) {\n // Resolve hidden por row e separa inline vs menu\n const visible = actions.filter((a) => {\n if (typeof a.hidden === \"function\") return !a.hidden(row);\n return !a.hidden;\n });\n const inlineActions = visible.filter((a) => !a.showInMenu);\n const menuActions = visible.filter((a) => a.showInMenu);\n\n if (visible.length === 0) return null;\n\n const resolveDisabled = (a: DataTableActionItem<T>): boolean => {\n if (typeof a.disabled === \"function\") return a.disabled(row);\n return !!a.disabled;\n };\n\n return (\n <div className=\"flex items-center gap-gp-2xs justify-end w-full\">\n {/* Icones inline */}\n {inlineActions.map((a) => (\n <Button\n key={a.id}\n size=\"icon-2xs\"\n variant=\"ghost\"\n color={a.destructive ? \"critical\" : \"secondary\"}\n aria-label={a.label}\n title={a.label}\n disabled={resolveDisabled(a)}\n onClick={(e) => {\n e.stopPropagation();\n a.onClick(row);\n }}\n >\n {a.icon}\n </Button>\n ))}\n\n {/* Dropdown 3-pontos com items showInMenu */}\n {menuActions.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n size=\"icon-2xs\"\n variant=\"ghost\"\n color=\"secondary\"\n aria-label=\"Mais acoes\"\n onClick={(e) => e.stopPropagation()}\n onPointerDown={(e) => e.stopPropagation()}\n onMouseDown={(e) => e.stopPropagation()}\n >\n <MoreHorizontal />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align=\"end\"\n onClick={(e) => e.stopPropagation()}\n >\n {menuActions.map((a) => (\n <DropdownMenuItem\n key={a.id}\n onClick={() => a.onClick(row)}\n disabled={resolveDisabled(a)}\n variant={a.destructive ? \"destructive\" : \"default\"}\n >\n {a.icon}\n {a.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { useSortable } from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport { TableHeadCell } from \"../../Table\";\nimport type { TableHeadCellProps } from \"../../Table\";\n\nexport type DataTableSortableHeadCellProps = TableHeadCellProps & {\n /** ID unico do item no SortableContext (== field). Obrigatorio pra dnd. */\n sortableId: string;\n /** Quando true, desabilita drag (usado pra coluna actions). */\n disableDrag?: boolean;\n children?: ReactNode;\n};\n\n/**\n * Wrapper do TableHeadCell que adiciona drag-and-drop via @dnd-kit/sortable.\n *\n * - Activation constraint de 5px no PointerSensor (DndContext) preserva click-to-sort.\n * - Aplica `transform` + `transition` durante drag (CSS smooth movement).\n * - Reduz opacidade do item em drag pra dar feedback visual.\n * - Spread `attributes` + `listeners` via `rootProps` — listeners ficam na cell\n * inteira (drag activator) mas mousedown/click do resize handle + column menu\n * button já tem stopPropagation, então não conflitam.\n *\n * Quando `disableDrag=true`, o item participa do SortableContext (mantem layout)\n * mas não pode ser arrastado nem ser drop target.\n */\nexport function DataTableSortableHeadCell({\n sortableId,\n disableDrag = false,\n children,\n ...headCellProps\n}: DataTableSortableHeadCellProps) {\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({\n id: sortableId,\n disabled: disableDrag,\n });\n\n // Cursor strategy:\n // - drag desabilitado → cursor default do TableHeadCell (pointer se sortable, default se não)\n // - durante drag ativo → grabbing (feedback visual de \"está sendo movido\")\n // - sortable + draggable → pointer (sort = ação primária ao click; drag é secundário)\n // - apenas draggable (não sortable) → grab (drag é a única ação interativa)\n const cursor: React.CSSProperties[\"cursor\"] = disableDrag\n ? undefined\n : isDragging\n ? \"grabbing\"\n : headCellProps.sortable\n ? \"pointer\"\n : \"grab\";\n\n const dragStyle: React.CSSProperties = {\n transform: CSS.Translate.toString(transform),\n transition,\n opacity: isDragging ? 0.4 : undefined,\n cursor,\n zIndex: isDragging ? 30 : undefined,\n // Override do sticky positioning durante drag pra cell flutuar acompanhando o cursor\n position: isDragging ? \"relative\" : undefined,\n };\n\n return (\n <TableHeadCell\n {...headCellProps}\n ref={setNodeRef}\n style={dragStyle}\n rootProps={{\n ...attributes,\n ...listeners,\n }}\n >\n {children}\n </TableHeadCell>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { Loader2, AlertCircle } from \"lucide-react\";\nimport { Input } from \"../../../shadcn/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../../shadcn/select\";\nimport type { DataTableColumnDef } from \"../data-table.types\";\nimport { columnTypeRegistry } from \"../column-types\";\n\nexport type DataTableEditCellProps<T> = {\n column: DataTableColumnDef<T>;\n row: T;\n initialValue: any;\n /** Fase F.1 — quando true, mostra spinner overlay e bloqueia input (commit em andamento). */\n isLoading?: boolean;\n /** Fase F.1 — quando definido, mostra ícone de erro com tooltip e mantem edit aberto. */\n error?: string | null;\n onCommit: (newValue: any) => void;\n onCancel: () => void;\n};\n\n/**\n * Editor inline para celulas com `editable: true`.\n *\n * - Se `column.renderEdit` definido, delega 100% pro consumer (escape hatch).\n * - Caso contrario, renderiza editor default baseado em `column.editType`\n * (ou derivado de `column.type` / `column.filterOptions`).\n *\n * Eventos do editor default:\n * - Enter → commit\n * - Esc → cancel\n * - Blur → commit (delay 1 tick pra permitir Radix internal events terminarem)\n *\n * Editor SE auto-foca no mount. Input ganha selection.all pra usuario\n * sobrescrever rapidamente.\n */\nexport function DataTableEditCell<T>({\n column,\n row,\n initialValue,\n isLoading = false,\n error = null,\n onCommit,\n onCancel,\n}: DataTableEditCellProps<T>) {\n const [value, setValue] = useState(initialValue);\n\n // Wrapper com overlay de loading/error. Inputs internos ficam por baixo\n // com pointer-events bloqueado quando loading.\n const wrap = (children: React.ReactNode) => (\n <div className=\"relative w-full\">\n <div\n className={\n isLoading\n ? \"pointer-events-none opacity-60 transition-opacity\"\n : \"transition-opacity\"\n }\n >\n {children}\n </div>\n {isLoading && (\n <div\n className=\"absolute inset-0 flex items-center justify-end pr-pad-md pointer-events-none\"\n aria-live=\"polite\"\n >\n <Loader2\n className=\"size-icon-sm text-fg-brand animate-spin\"\n aria-label=\"Salvando...\"\n />\n </div>\n )}\n {error && !isLoading && (\n <div\n className=\"absolute inset-y-0 right-pad-md flex items-center pointer-events-none\"\n aria-live=\"assertive\"\n title={error}\n >\n <AlertCircle\n className=\"size-icon-sm text-fg-danger\"\n aria-label={error}\n />\n </div>\n )}\n </div>\n );\n\n // Custom editor — consumer controla 100%\n if (column.renderEdit) {\n return wrap(\n column.renderEdit({\n row,\n value,\n onChange: setValue,\n onCommit: () => onCommit(value),\n onCancel,\n }),\n );\n }\n\n // Fase G.2 — registry-aware: se o tipo da coluna definir renderEdit, usa ele\n const typeDef = column.type ? columnTypeRegistry.get(column.type) : undefined;\n if (typeDef?.renderEdit) {\n return wrap(\n typeDef.renderEdit({\n row,\n value,\n onChange: (v) => setValue(v),\n onCommit: () => onCommit(value),\n onCancel,\n options: column.filterOptions,\n }),\n );\n }\n\n // Default editor — deriva editType\n const editType = resolveEditType(column);\n\n if (editType === \"select\") {\n return wrap(\n <SelectEditor\n value={value == null ? \"\" : String(value)}\n options={column.filterOptions ?? []}\n onChange={(v) => {\n // Select dispara onValueChange uma vez no commit (nao tem onChange + Enter).\n // Commit imediato no select pra UX direta.\n setValue(v);\n onCommit(v);\n }}\n onCancel={onCancel}\n disabled={isLoading}\n />,\n );\n }\n\n return wrap(\n <InputEditor\n type={editType === \"number\" ? \"number\" : \"text\"}\n value={value == null ? \"\" : String(value)}\n onChange={(v) => setValue(editType === \"number\" ? (v === \"\" ? null : Number(v)) : v)}\n onCommit={() => onCommit(value)}\n onCancel={onCancel}\n disabled={isLoading}\n hasError={!!error}\n />,\n );\n}\n\n/* ── Editor: Input (text/number) ─────────────────────────────────── */\n\nfunction InputEditor({\n type,\n value,\n onChange,\n onCommit,\n onCancel,\n disabled = false,\n hasError = false,\n}: {\n type: \"text\" | \"number\";\n value: string;\n onChange: (next: string) => void;\n onCommit: () => void;\n onCancel: () => void;\n disabled?: boolean;\n hasError?: boolean;\n}) {\n const ref = useRef<HTMLInputElement>(null);\n\n // Auto-focus + select-all no mount\n useEffect(() => {\n const el = ref.current;\n if (!el || disabled) return;\n el.focus();\n el.select();\n }, [disabled]);\n\n return (\n <Input\n ref={ref}\n type={type}\n size=\"xs\"\n state={hasError ? \"error\" : \"default\"}\n value={value}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n onCommit();\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n onCancel();\n }\n }}\n onBlur={() => {\n // Durante loading, NAO commitar via blur — usuario pode estar so movendo\n // foco temporariamente enquanto a request voa. Commit explicito via Enter\n // ja foi disparado e a Promise esta em curso.\n if (disabled) return;\n // Delay 1 tick pra permitir cliques internos no row (caso usuario\n // clique em outra celula durante edicao) terminarem antes do commit.\n setTimeout(onCommit, 0);\n }}\n // Bloqueia bubbling pra TableRow.onClick / dnd / sort\n onClick={(e) => e.stopPropagation()}\n onPointerDown={(e) => e.stopPropagation()}\n onMouseDown={(e) => e.stopPropagation()}\n onDoubleClick={(e) => e.stopPropagation()}\n className=\"border-0 rounded-radius-sm shadow-none focus-visible:shadow-sh-ring pr-pad-2xl\"\n />\n );\n}\n\n/* ── Editor: Select ──────────────────────────────────────────────── */\n\nfunction SelectEditor({\n value,\n options,\n onChange,\n onCancel,\n disabled = false,\n}: {\n value: string;\n options: Array<{ value: any; label: string }>;\n onChange: (next: string) => void;\n onCancel: () => void;\n disabled?: boolean;\n}) {\n return (\n <div\n onClick={(e) => e.stopPropagation()}\n onPointerDown={(e) => e.stopPropagation()}\n onMouseDown={(e) => e.stopPropagation()}\n onDoubleClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onCancel();\n }\n }}\n className=\"w-full\"\n >\n <Select defaultOpen={!disabled} value={value} onValueChange={onChange} disabled={disabled}>\n <SelectTrigger className=\"h-form-sm min-h-form-sm rounded-radius-sm\">\n <SelectValue placeholder=\"Selecionar...\" />\n </SelectTrigger>\n <SelectContent>\n {options.map((o) => (\n <SelectItem key={String(o.value)} value={String(o.value)}>\n {o.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n );\n}\n\n/* ── Helpers ─────────────────────────────────────────────────────── */\n\nfunction resolveEditType<T>(col: DataTableColumnDef<T>): \"text\" | \"number\" | \"select\" {\n if (col.editType) return col.editType;\n // Deriva de filterType primeiro (mais especifico que `type`)\n if (col.filterType === \"select\" || col.filterType === \"multiSelect\") return \"select\";\n if (col.filterType === \"number\") return \"number\";\n // Deriva de `type` da coluna\n if (col.type === \"number\" || col.type === \"currency\") return \"number\";\n if (col.type === \"status\" || col.type === \"boolean\") return \"select\";\n return \"text\";\n}\n","import type { ReactNode } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { TableCell } from \"../../Table\";\nimport type { DataTableColumnDef } from \"../data-table.types\";\n\nexport type DataTableTotalizerRowProps<T> = {\n /** Colunas efetivas (apos hidden/order) — mesma fonte do header. */\n columns: DataTableColumnDef<T>[];\n /** Rows pra agregar. Em client mode: allPagesProcessed (todas filtradas).\n * Em server mode: current page rows (ou empty se consumer só usar aggregateRow). */\n rows: T[];\n /** Override pre-computado por field — vence aggregate built-in/custom. */\n overrides?: Record<string, ReactNode>;\n /** Widths efetivos por field (mesma fonte do header pra alinhar). */\n columnWidths: Record<string, number>;\n /** Sticky offsets pra colunas pinned. */\n stickyOffsets: Record<string, number>;\n /** Tem coluna de selection enabled? Renderiza cell vazia na esquerda. */\n hasSelection?: boolean;\n};\n\n/**\n * Footer row sticky no bottom do body — mostra agregacoes por coluna.\n *\n * Para cada coluna:\n * - Se `overrides[field]` definido → renderiza esse valor (server mode).\n * - Senao, se `column.aggregate` definido → computa local.\n * - Senao, cell vazia (apenas mantem largura/alinhamento).\n *\n * `column.aggregate` aceita:\n * - 'sum' | 'avg' | 'count' | 'min' | 'max' — built-ins (so funcionam em valores numericos).\n * - (rows: T[]) => ReactNode — funcao custom, recebe rows pra computar livremente.\n *\n * Formatacao do resultado built-in: `column.aggregateFormatter(value)` >\n * `column.valueFormatter(value)` > toString.\n */\nexport function DataTableTotalizerRow<T>({\n columns,\n rows,\n overrides,\n columnWidths,\n stickyOffsets,\n hasSelection = false,\n}: DataTableTotalizerRowProps<T>) {\n return (\n <div\n role=\"row\"\n className={cn(\n \"flex w-max min-w-full\",\n \"sticky bottom-0 z-[8]\",\n \"bg-bg-table-head border-t border-border-table\",\n \"h-[42px]\",\n )}\n >\n {hasSelection && (\n <TableCell width={56} align=\"center\" className=\"!px-0\">\n {/* Empty cell pra alinhar com checkbox column. */}\n </TableCell>\n )}\n {columns.map((col) => {\n const field = String(col.field);\n const content = resolveTotalizerContent(col, rows, overrides?.[field]);\n return (\n <TableCell\n key={field}\n field={field}\n width={columnWidths[field]}\n pinned={col.pinned}\n pinOffset={stickyOffsets[field]}\n align={col.align}\n ellipsis={col.ellipsis}\n className=\"text-label-sm text-fg-strong bg-bg-table-head\"\n >\n {content}\n </TableCell>\n );\n })}\n </div>\n );\n}\n\n/* ── Helpers ─────────────────────────────────────────────────────── */\n\nfunction resolveTotalizerContent<T>(\n col: DataTableColumnDef<T>,\n rows: T[],\n override: ReactNode | undefined,\n): ReactNode {\n if (override !== undefined) return override;\n if (col.aggregate === undefined) return null;\n\n // Custom function\n if (typeof col.aggregate === \"function\") {\n return col.aggregate(rows);\n }\n\n // Built-in keyword\n const field = String(col.field);\n const values = rows\n .map((r) => getFieldValue(r, field))\n .filter((v): v is number => typeof v === \"number\" && !isNaN(v));\n\n let result: number;\n switch (col.aggregate) {\n case \"sum\":\n result = values.reduce((acc, v) => acc + v, 0);\n break;\n case \"avg\":\n result = values.length === 0 ? 0 : values.reduce((acc, v) => acc + v, 0) / values.length;\n break;\n case \"count\":\n result = rows.length;\n break;\n case \"min\":\n result = values.length === 0 ? 0 : Math.min(...values);\n break;\n case \"max\":\n result = values.length === 0 ? 0 : Math.max(...values);\n break;\n default:\n return null;\n }\n\n const formatter = col.aggregateFormatter ?? col.valueFormatter;\n return formatter ? formatter(result) : String(result);\n}\n\nfunction getFieldValue<T>(row: T, field: string): unknown {\n if (!field.includes(\".\")) return (row as Record<string, unknown>)[field];\n return field\n .split(\".\")\n .reduce<unknown>(\n (acc, key) => (acc as Record<string, unknown> | null | undefined)?.[key],\n row,\n );\n}\n","import { ChevronDown, ChevronRight } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport type { DataTableColumnDef } from \"../data-table.types\";\nimport type { DataTableGroupRow } from \"../utils/group-rows\";\n\nexport type DataTableGroupHeaderRowProps<T> = {\n group: DataTableGroupRow<T>;\n /** Colunas efetivas (visíveis) — usado pra renderizar subtotalizers inline. */\n columns: DataTableColumnDef<T>[];\n columnWidths: Record<string, number>;\n stickyOffsets: Record<string, number>;\n hasSelection?: boolean;\n /** Click no chevron — toggle expand/collapse. */\n onToggle: () => void;\n /** Style inline pra virtualização (position absolute + transform). */\n style?: React.CSSProperties;\n /** Override do conteúdo — quando passado, substitui o layout default\n * (chevron + label + count + subtotalizers nas cells) por ReactNode livre\n * ocupando a row inteira. Mantém o click handler do toggle no wrapper. */\n renderHeader?: (params: {\n group: {\n key: string;\n field: string;\n value: unknown;\n label: string;\n count: number;\n isExpanded: boolean;\n };\n toggle: () => void;\n }) => React.ReactNode;\n};\n\n/**\n * Header row de um grupo. Span full-width, mostra:\n * - Chevron clicável (▶/▼)\n * - Label do grupo (valor formatado via column.valueFormatter)\n * - Count badge \"(N)\"\n * - Subtotalizers inline para colunas com `aggregate` (alinhados às cells)\n *\n * Sticky lateral é preservado pra colunas pinned (o chevron + label moram na\n * primeira cell não-pinned, demais cells renderizam aggregate se houver).\n */\nexport function DataTableGroupHeaderRow<T>({\n group,\n columns,\n columnWidths,\n stickyOffsets,\n hasSelection = false,\n onToggle,\n style,\n renderHeader,\n}: DataTableGroupHeaderRowProps<T>) {\n const ChevronIcon = group.isExpanded ? ChevronDown : ChevronRight;\n\n // Override: free-form render ocupando full row, sem alinhamento de colunas.\n if (renderHeader) {\n return (\n <div\n role=\"row\"\n data-group-header=\"true\"\n data-group-key={group.key}\n aria-expanded={group.isExpanded}\n style={style}\n className={cn(\n \"flex w-full min-w-full\",\n \"bg-bg-subtle\",\n \"border-b border-border-table\",\n \"transition-colors duration-150\",\n // Sticky horizontal: free-form header gruda no left=0 e ocupa\n // viewport width pra não ser cortado por scroll horizontal.\n \"sticky left-0\",\n )}\n >\n {renderHeader({\n group: {\n key: group.key,\n field: group.field,\n value: group.value,\n label: group.label,\n count: group.count,\n isExpanded: group.isExpanded,\n },\n toggle: onToggle,\n })}\n </div>\n );\n }\n\n return (\n <div\n role=\"row\"\n data-group-header=\"true\"\n data-group-key={group.key}\n aria-expanded={group.isExpanded}\n style={style}\n className={cn(\n \"flex w-max min-w-full h-[42px]\",\n \"bg-bg-subtle hover:bg-bg-muted\",\n \"border-b border-border-table\",\n \"cursor-pointer select-none\",\n \"transition-colors duration-150\",\n )}\n onClick={onToggle}\n >\n {hasSelection && (\n <div className=\"shrink-0 w-[56px] h-[42px]\" />\n )}\n {columns.map((col, idx) => {\n const field = String(col.field);\n const width = columnWidths[field];\n const isPinned = col.pinned === \"left\" || col.pinned === \"right\";\n // Cell style (width + sticky offsets quando pinned)\n const cellStyle: React.CSSProperties = {\n width,\n minWidth: width,\n maxWidth: width,\n };\n if (isPinned && stickyOffsets[field] !== undefined) {\n if (col.pinned === \"left\") cellStyle.left = stickyOffsets[field];\n if (col.pinned === \"right\") cellStyle.right = stickyOffsets[field];\n }\n // Primeira cell não-pinned (ou primeira cell se nenhuma pinned-left)\n // recebe chevron + label + count. Demais recebem aggregate se definido.\n const isFirstNonPinnedLeft =\n idx === columns.findIndex((c) => c.pinned !== \"left\");\n\n return (\n <div\n key={field}\n data-field={field}\n className={cn(\n \"shrink-0 flex items-center px-pad-2xl gap-gp-md\",\n \"text-label-sm text-fg-strong\",\n isPinned && \"sticky z-[5] bg-bg-subtle\",\n )}\n style={cellStyle}\n >\n {isFirstNonPinnedLeft ? (\n <>\n <ChevronIcon\n className=\"shrink-0 size-icon-sm text-fg-muted transition-transform\"\n aria-hidden\n />\n <span className=\"truncate\">{group.label}</span>\n <span className=\"text-fg-muted tabular-nums\">\n ({group.count})\n </span>\n </>\n ) : col.aggregate ? (\n <GroupAggregate column={col} rows={group.rows} />\n ) : null}\n </div>\n );\n })}\n </div>\n );\n}\n\n/* ── Subtotalizer inline — reusa logica do TotalizerRow ──────────── */\n\nfunction GroupAggregate<T>({\n column,\n rows,\n}: {\n column: DataTableColumnDef<T>;\n rows: T[];\n}) {\n const content = resolveAggregate(column, rows);\n if (content == null || content === \"\") return null;\n return <span className=\"text-fg-muted\">{content}</span>;\n}\n\nfunction resolveAggregate<T>(\n col: DataTableColumnDef<T>,\n rows: T[],\n): React.ReactNode {\n if (col.aggregate === undefined) return null;\n if (typeof col.aggregate === \"function\") return col.aggregate(rows);\n\n const field = String(col.field);\n const values = rows\n .map((r) => {\n if (col.valueGetter) return col.valueGetter(r);\n if (!field.includes(\".\")) return (r as Record<string, unknown>)[field];\n return field\n .split(\".\")\n .reduce<unknown>(\n (acc, key) => (acc as Record<string, unknown> | null | undefined)?.[key],\n r,\n );\n })\n .filter((v): v is number => typeof v === \"number\" && !isNaN(v));\n\n let result: number;\n switch (col.aggregate) {\n case \"sum\":\n result = values.reduce((acc, v) => acc + v, 0);\n break;\n case \"avg\":\n result = values.length === 0 ? 0 : values.reduce((acc, v) => acc + v, 0) / values.length;\n break;\n case \"count\":\n result = rows.length;\n break;\n case \"min\":\n result = values.length === 0 ? 0 : Math.min(...values);\n break;\n case \"max\":\n result = values.length === 0 ? 0 : Math.max(...values);\n break;\n default:\n return null;\n }\n\n const formatter = col.aggregateFormatter ?? col.valueFormatter;\n return formatter ? formatter(result) : String(result);\n}\n","import type { ReactNode } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport type { DataTableGroupRow } from \"../utils/group-rows\";\n\nexport type DataTableGroupContentRowProps<T> = {\n group: DataTableGroupRow<T>;\n /** Render do consumer — recebe `group` (incluindo `rows`) e devolve qualquer ReactNode. */\n render: (params: {\n group: {\n key: string;\n field: string;\n value: unknown;\n label: string;\n count: number;\n rows: T[];\n };\n }) => ReactNode;\n /** Style inline pra virtualização. */\n style?: React.CSSProperties;\n};\n\n/**\n * Slot de conteúdo livre do grupo — substitui as N child TableRows quando\n * consumer passa renderGroupContent. Ocupa row inteira (não alinhado a colunas),\n * sticky left=0 pra não ser cortado por scroll horizontal da tabela principal.\n *\n * Use cases: sub-tabela com colunas diferentes, lista compacta, cards, gráficos,\n * qualquer composição que o consumer queira dentro do grupo expandido.\n *\n * Trade-off com virtualização: tanstack/react-virtual usa `estimateRowHeight`\n * fixo. Se o conteúdo customizado tem altura variável, virtualização pode\n * sub/super estimar — passe `estimateRowHeight` adequado ao seu conteúdo,\n * ou desligue virtualize quando renderGroupContent estiver ativo.\n */\nexport function DataTableGroupContentRow<T>({\n group,\n render,\n style,\n}: DataTableGroupContentRowProps<T>) {\n return (\n <div\n role=\"row\"\n data-group-content=\"true\"\n data-group-key={group.key}\n style={style}\n className={cn(\n \"flex w-full min-w-full\",\n \"bg-bg-table\",\n \"border-b border-border-table\",\n // Sticky horizontal: gruda no left=0 do viewport pra ocupar área visível\n // independente do scroll horizontal da tabela.\n \"sticky left-0\",\n )}\n >\n {render({\n group: {\n key: group.key,\n field: group.field,\n value: group.value,\n label: group.label,\n count: group.count,\n rows: group.rows,\n },\n })}\n </div>\n );\n}\n","import type { DataTableColumnDef } from \"../data-table.types\";\nimport { applyValueGetter } from \"./resolve-value\";\n\n/** Marker symbol pra distinguir GroupRow de data row T no render branching.\n * Pattern symbol-as-discriminator evita conflito acidental com props do T. */\nexport const GROUP_ROW_TYPE = Symbol(\"dt-group-row\");\n\n/** Marker symbol pra \"slot de conteúdo customizado do grupo\" — quando consumer\n * passa renderGroupContent, esse marker substitui as N child rows por 1 row\n * full-width que delega 100% pro render do consumer. */\nexport const GROUP_CONTENT_TYPE = Symbol(\"dt-group-content\");\n\n/** Row sintética inserida no array antes de cada grupo. */\nexport type DataTableGroupRow<T = unknown> = {\n __type: typeof GROUP_ROW_TYPE;\n /** Field usado pra agrupar (== props.groupBy). */\n field: string;\n /** Valor raw do grupo (ex: \"active\", \"inactive\"). */\n value: unknown;\n /** Label formatado pra display (passa por column.valueFormatter se houver). */\n label: string;\n /** Quantidade de rows nesse grupo. */\n count: number;\n /** Rows do grupo — usado pra subtotalizers + selectGroup. */\n rows: T[];\n /** Está expandido? Se false, child rows são skipped do array. */\n isExpanded: boolean;\n /** Chave unica do grupo — `${field}|${value}` */\n key: string;\n};\n\n/** \"Content slot\" marker — substitui as child rows quando consumer passa\n * renderGroupContent. Carrega referência ao group pra que o consumer tenha\n * acesso a label/count/rows no callback. */\nexport type DataTableGroupContent<T = unknown> = {\n __type: typeof GROUP_CONTENT_TYPE;\n /** Mesma key do group pai. */\n key: string;\n /** Referência ao group pai (label, count, rows). */\n group: DataTableGroupRow<T>;\n};\n\n/** Type guard pra GroupRow. */\nexport function isGroupRow<T>(\n row: T | DataTableGroupRow<T> | DataTableGroupContent<T>,\n): row is DataTableGroupRow<T> {\n return (\n row != null &&\n typeof row === \"object\" &&\n \"__type\" in row &&\n (row as { __type: symbol }).__type === GROUP_ROW_TYPE\n );\n}\n\n/** Type guard pra GroupContent (slot custom). */\nexport function isGroupContent<T>(\n row: T | DataTableGroupRow<T> | DataTableGroupContent<T>,\n): row is DataTableGroupContent<T> {\n return (\n row != null &&\n typeof row === \"object\" &&\n \"__type\" in row &&\n (row as { __type: symbol }).__type === GROUP_CONTENT_TYPE\n );\n}\n\n// resolveGroupValue agora delega pro shared `applyValueGetter` (utils/resolve-value.ts).\n// Quando `col` não existe (field sem ColumnDef), usa stub minimal pra reaproveitar.\n\n/**\n * Reshape do array de rows em (GroupRow | T)[] alternados.\n *\n * Ordem: groups aparecem na ordem da primeira ocorrencia (não sortado por label).\n * Pra ordem específica, consumer pode passar rows já ordenadas pelo group field.\n *\n * Rows com value `undefined`/`null` no field caem no grupo \"(sem valor)\".\n *\n * @param rows Rows já filtradas/buscadas/ordenadas (output do processor)\n * @param field Campo de agrupamento (== props.groupBy)\n * @param expandedKeys Set de keys de grupos expandidos\n * @param defaultExpanded Quando grupo NÃO está em expandedKeys, este é o estado default\n * @param col Column def do field — usada pra valueGetter e valueFormatter\n */\nexport function groupRows<T>(\n rows: T[],\n field: string,\n expandedKeys: Set<string>,\n defaultExpanded: boolean,\n col: DataTableColumnDef<T> | undefined,\n /** Quando true, substitui as N child rows por 1 GroupContent marker.\n * Consumer renderiza conteúdo livre via renderGroupContent. */\n useCustomContent = false,\n): Array<DataTableGroupRow<T> | DataTableGroupContent<T> | T> {\n const groupsMap = new Map<string, { value: unknown; rows: T[] }>();\n\n // Stub minimal pra reusar applyValueGetter quando col não existe (field órfão).\n const colOrStub = (col ?? {\n field,\n headerName: \"\",\n }) as DataTableColumnDef<T>;\n\n for (const row of rows) {\n const rawValue = applyValueGetter(row, colOrStub);\n const key = `${field}|${rawValue ?? \"__null__\"}`;\n if (!groupsMap.has(key)) {\n groupsMap.set(key, { value: rawValue, rows: [] });\n }\n groupsMap.get(key)!.rows.push(row);\n }\n\n const result: Array<DataTableGroupRow<T> | DataTableGroupContent<T> | T> = [];\n for (const [key, group] of groupsMap.entries()) {\n // Resolve label via valueFormatter da coluna, senão toString do valor\n const labelRaw =\n group.value == null || group.value === \"\"\n ? \"(sem valor)\"\n : col?.valueFormatter\n ? col.valueFormatter(group.value)\n : String(group.value);\n\n // Default expanded a menos que key esteja explicitamente collapsada\n // (toggle inverte do default). Tracking via Set de keys que diferem do default.\n const isExpanded = expandedKeys.has(key) ? !defaultExpanded : defaultExpanded;\n\n const groupRow: DataTableGroupRow<T> = {\n __type: GROUP_ROW_TYPE,\n field,\n value: group.value,\n label: labelRaw,\n count: group.rows.length,\n rows: group.rows,\n isExpanded,\n key,\n };\n result.push(groupRow);\n if (isExpanded) {\n if (useCustomContent) {\n // 1 slot custom no lugar das N rows — consumer decide o render\n result.push({\n __type: GROUP_CONTENT_TYPE,\n key,\n group: groupRow,\n });\n } else {\n // Default: N TableRows iguais a uma tabela normal\n result.push(...group.rows);\n }\n }\n }\n return result;\n}\n","import type { ReactNode } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport type DataTableRowExpansionProps<T> = {\n row: T;\n render: (params: { row: T }) => ReactNode;\n /** Style inline pra virtualização. */\n style?: React.CSSProperties;\n};\n\n/**\n * Slot expandido abaixo de uma row — full-width, sticky-left no eixo horizontal.\n *\n * Não respeita estrutura de colunas da tabela. Consumer pode renderizar:\n * - Sub-tabela com colunas próprias\n * - Lista compacta de campos (key/value)\n * - Cards de detalhe\n * - Gráficos, timeline, qualquer coisa\n *\n * `sticky left-0` garante que o conteúdo fica visível mesmo quando há scroll\n * horizontal na tabela principal (cells da row vão pra direita, mas o\n * expansion permanece ancorado no viewport).\n *\n * Trade-off com virtualize: `estimateRowHeight` é fixo. Se conteúdo expandido\n * tem altura variável grande, virtualização pode sub/super estimar — passe\n * `estimateRowHeight` adequado ou desligue virtualize.\n */\nexport function DataTableRowExpansion<T>({\n row,\n render,\n style,\n}: DataTableRowExpansionProps<T>) {\n return (\n <div\n role=\"row\"\n data-row-expansion=\"true\"\n style={style}\n className={cn(\n \"flex w-full min-w-full\",\n \"bg-bg-subtle\",\n \"border-b border-border-table\",\n // Sticky horizontal pra ocupar viewport visível, não cortar no scroll-X\n \"sticky left-0\",\n )}\n >\n {render({ row })}\n </div>\n );\n}\n","import type { GridRowId } from \"../data-table.types\";\n\n/** Marker pra \"row expansion\" — substitui ou se intercala com data rows.\n * Symbol-as-discriminator pra evitar conflito com props do T. */\nexport const ROW_EXPANSION_TYPE = Symbol(\"dt-row-expansion\");\n\nexport type DataTableRowExpansionItem<T = unknown> = {\n __type: typeof ROW_EXPANSION_TYPE;\n /** ID da row que está expandida (== getRowId(row)). */\n id: GridRowId;\n /** Referência à row pai pra que o render do consumer tenha acesso. */\n row: T;\n};\n\n/** Type guard pra ExpansionRow. Aceita union ampla (T | GroupRow | GroupContent | etc)\n * pra coexistir com outras transformações no mesmo array. */\nexport function isExpansionRow<T>(\n item: unknown,\n): item is DataTableRowExpansionItem<T> {\n return (\n item != null &&\n typeof item === \"object\" &&\n \"__type\" in item &&\n (item as { __type: symbol }).__type === ROW_EXPANSION_TYPE\n );\n}\n\n/**\n * Reshape do array de rows pra incluir markers de expansão.\n * Após cada row que tem ID em `expandedIds`, insere 1 marker de expansão.\n *\n * Resultado é um array misto `(T | DataTableRowExpansionItem<T>)[]` — o render\n * faz branching via `isExpansionRow` type guard. Virtualizer recebe esse array\n * direto e calcula scroll height baseado em count.\n *\n * Quando `expandedIds` vazia ou nenhum row match, retorna o array original\n * (referência preservada pra evitar re-renders desnecessários).\n */\nexport function expandRows<T>(\n rows: T[],\n expandedIds: Set<GridRowId>,\n getRowId: (row: T) => GridRowId,\n): Array<T | DataTableRowExpansionItem<T>> {\n if (expandedIds.size === 0) return rows;\n let hasAnyMatch = false;\n for (const row of rows) {\n if (expandedIds.has(getRowId(row))) {\n hasAnyMatch = true;\n break;\n }\n }\n if (!hasAnyMatch) return rows;\n\n const result: Array<T | DataTableRowExpansionItem<T>> = [];\n for (const row of rows) {\n result.push(row);\n const id = getRowId(row);\n if (expandedIds.has(id)) {\n result.push({ __type: ROW_EXPANSION_TYPE, id, row });\n }\n }\n return result;\n}\n","import type { FilterItem } from \"../data-table.types\";\n\n/**\n * Mapeamento de operadores entre FilterPopover (UI) e FilterOperator (logic).\n *\n * FilterPopover usa nomes curtos compatíveis com SQL parser (eq, neq, gt, lt).\n * Processor/FilterModel usa nomes longos semânticos (equals, neq, gt, lt).\n *\n * Single source of truth — adicione 1 entrada aqui e ambos os maps refletem.\n */\nconst OPERATOR_PAIRS: ReadonlyArray<[string, FilterItem[\"operator\"]]> = [\n [\"eq\", \"equals\"],\n [\"neq\", \"neq\"],\n [\"contains\", \"contains\"],\n [\"gt\", \"gt\"],\n [\"lt\", \"lt\"],\n [\"between\", \"between\"],\n];\n\n/** FilterPopover op (eq, neq, contains, gt, lt, between) → FilterModel operator (equals, …) */\nexport const POPOVER_OP_TO_FILTER_OP: Record<string, FilterItem[\"operator\"]> =\n Object.fromEntries(OPERATOR_PAIRS) as Record<string, FilterItem[\"operator\"]>;\n\n/** FilterModel operator → FilterPopover op id (reverso do POPOVER_OP_TO_FILTER_OP). */\nexport const FILTER_OP_TO_POPOVER_OP: Record<string, string> =\n Object.fromEntries(OPERATOR_PAIRS.map(([k, v]) => [v, k]));\n","import { useMemo } from \"react\";\nimport type {\n SortPopoverColumn,\n SortPopoverCriterion,\n} from \"../../TableToolbar\";\nimport type { DataTableColumnDef, SortModel } from \"../data-table.types\";\n\nexport type UseSortPopoverAdapterParams<T> = {\n effectiveColumns: DataTableColumnDef<T>[];\n sortModels: SortModel[];\n setSortModels: (models: SortModel[]) => void;\n};\n\nexport type UseSortPopoverAdapterResult = {\n /** Colunas filtradas (sem actions, sortable !== false) no formato do SortPopover. */\n sortPopoverColumns: SortPopoverColumn[];\n /** Critérios atuais (field + dir) — mapeado de sortModels. */\n sortPopoverCriteria: SortPopoverCriterion[];\n /** Handler que converte critérios do popover → setSortModels. */\n handleSortChange: (criteria: SortPopoverCriterion[]) => void;\n};\n\n/**\n * Adapter: ColumnDef + SortModel ↔ SortPopover props.\n *\n * Extraído do data-table.tsx pra isolar a tradução entre tipos do TableToolbar\n * e tipos do DataTable. Filtra colunas não-sortables (type === \"actions\" ou\n * sortable === false) — só aparecem no popover as que fazem sentido.\n */\nexport function useSortPopoverAdapter<T>({\n effectiveColumns,\n sortModels,\n setSortModels,\n}: UseSortPopoverAdapterParams<T>): UseSortPopoverAdapterResult {\n const sortPopoverColumns = useMemo<SortPopoverColumn[]>(\n () =>\n effectiveColumns\n .filter((c) => c.type !== \"actions\" && c.sortable !== false)\n .map((c) => ({\n key: String(c.field),\n label: c.headerName,\n icon: c.icon,\n })),\n [effectiveColumns],\n );\n\n const sortPopoverCriteria = useMemo<SortPopoverCriterion[]>(\n () => sortModels.map((s) => ({ key: s.field, dir: s.direction })),\n [sortModels],\n );\n\n const handleSortChange = (criteria: SortPopoverCriterion[]) => {\n setSortModels(criteria.map((c) => ({ field: c.key, direction: c.dir })));\n };\n\n return {\n sortPopoverColumns,\n sortPopoverCriteria,\n handleSortChange,\n };\n}\n","import { useMemo } from \"react\";\nimport type { ColsPopoverColumn } from \"../../TableToolbar\";\nimport type { ColumnPinned } from \"../../Table\";\nimport type { DataTableColumnDef } from \"../data-table.types\";\n\nexport type UseColsPopoverAdapterParams<T> = {\n columns: DataTableColumnDef<T>[];\n hiddenColumns: Set<string>;\n pinnedColumns: Record<string, ColumnPinned>;\n handleShow: (field: string) => void;\n handleHide: (field: string) => void;\n handlePin: (field: string, side: ColumnPinned) => void;\n handleReorder: (order: string[]) => void;\n};\n\nexport type UseColsPopoverAdapterResult = {\n /** Colunas no formato do ColsPopover (sem actions). */\n colsPopoverColumns: ColsPopoverColumn[];\n /** Set de fields visíveis (calculado de hiddenColumns). */\n visibleColsSet: Set<string>;\n /** Set de fields pinned (left ou right). */\n pinnedColsSet: Set<string>;\n /** Aplica toggle de visibilidade — converte Set → handleShow/handleHide. */\n handleVisibleChange: (next: Set<string>) => void;\n /** Aplica toggle de pin — converte Set → handlePin(\"left\"/undefined). */\n handlePinnedChange: (next: Set<string>) => void;\n /** Reordena colunas via dnd interno do popover. */\n handleColumnsReorder: (reordered: ColsPopoverColumn[]) => void;\n};\n\n/**\n * Adapter: ColumnDef + visibility/pin state ↔ ColsPopover props.\n *\n * Extraído do data-table.tsx pra isolar a tradução entre o popover de colunas\n * (que trabalha com Sets de keys) e o estado interno do DataTable (que usa\n * `Set<hiddenColumns>` + `Record<field, \"left\"|\"right\">`).\n */\nexport function useColsPopoverAdapter<T>({\n columns,\n hiddenColumns,\n pinnedColumns,\n handleShow,\n handleHide,\n handlePin,\n handleReorder,\n}: UseColsPopoverAdapterParams<T>): UseColsPopoverAdapterResult {\n const colsPopoverColumns = useMemo<ColsPopoverColumn[]>(\n () =>\n columns\n // Coluna actions é estrutural — não aparece no popover de visibilidade.\n .filter((c) => c.type !== \"actions\")\n .map((c) => ({\n key: String(c.field),\n label: c.headerName,\n icon: c.icon,\n })),\n [columns],\n );\n\n const visibleColsSet = useMemo<Set<string>>(\n () =>\n new Set(\n columns\n .map((c) => String(c.field))\n .filter((f) => !hiddenColumns.has(f)),\n ),\n [columns, hiddenColumns],\n );\n\n const pinnedColsSet = useMemo<Set<string>>(\n () =>\n new Set(\n Object.entries(pinnedColumns)\n .filter(([, pin]) => pin === \"left\" || pin === \"right\")\n .map(([field]) => field),\n ),\n [pinnedColumns],\n );\n\n const handleVisibleChange = (next: Set<string>) => {\n const allFields = columns.map((c) => String(c.field));\n for (const f of allFields) {\n if (next.has(f) && hiddenColumns.has(f)) {\n handleShow(f);\n } else if (!next.has(f) && !hiddenColumns.has(f)) {\n handleHide(f);\n }\n }\n };\n\n const handlePinnedChange = (next: Set<string>) => {\n const allFields = columns.map((c) => String(c.field));\n for (const f of allFields) {\n const isPinned =\n pinnedColumns[f] === \"left\" || pinnedColumns[f] === \"right\";\n if (next.has(f) && !isPinned) {\n handlePin(f, \"left\");\n } else if (!next.has(f) && isPinned) {\n handlePin(f, undefined);\n }\n }\n };\n\n const handleColumnsReorder = (reordered: ColsPopoverColumn[]) => {\n handleReorder(reordered.map((c) => c.key));\n };\n\n return {\n colsPopoverColumns,\n visibleColsSet,\n pinnedColsSet,\n handleVisibleChange,\n handlePinnedChange,\n handleColumnsReorder,\n };\n}\n","import { useMemo } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type {\n AppliedFilter,\n FilterPopoverColumn,\n FilterPopoverEntry,\n} from \"../../TableToolbar\";\nimport { columnTypeRegistry } from \"../column-types\";\nimport type { ColumnOption } from \"../column-types\";\nimport type {\n DataTableColumnDef,\n FilterItem,\n FilterModel,\n} from \"../data-table.types\";\nimport {\n FILTER_OP_TO_POPOVER_OP,\n POPOVER_OP_TO_FILTER_OP,\n} from \"../utils/operator-mapping\";\n\n/** True quando um FilterValue é \"vazio\" (sem efeito) — null, string vazia,\n * ou tupla com todos sides nulos/strings vazias. */\nfunction isFilterValueEmpty(v: unknown): boolean {\n if (v == null) return true;\n if (typeof v === \"string\") return v.length === 0;\n if (Array.isArray(v)) {\n return v.every(\n (x) => x == null || (typeof x === \"string\" && x.length === 0),\n );\n }\n return false;\n}\n\nexport type FilterGroup<T> = {\n key: string;\n field: string;\n operator: FilterItem[\"operator\"];\n items: FilterItem[];\n};\n\nexport type UseFilterPopoverAdapterParams<T> = {\n /** Colunas efetivas pós hidden/order. */\n effectiveColumns: DataTableColumnDef<T>[];\n /** ColumnDef props originais — usado pra options de filtros. */\n allColumns: DataTableColumnDef<T>[];\n /** Rows (client mode) pra auto-extract options de select. */\n rows: T[] | undefined;\n /** FilterModel atual + setter. */\n filterModel: FilterModel;\n setFilterModel: (model: FilterModel) => void;\n /** Map de field → DataTableColumnDef (memoized externamente pra evitar dupla criação). */\n colsByField: Map<string, DataTableColumnDef<T>>;\n /** Map de field → label do header. */\n colLabelMap: Record<string, string>;\n /** Chave de chip pendente de abertura — pra incluir items vazios renderizando \"phantom chip\". */\n pendingOpenChipKey: string | null;\n};\n\nexport type UseFilterPopoverAdapterResult<T> = {\n filterPopoverColumns: FilterPopoverColumn[];\n filterPopoverEntries: FilterPopoverEntry[];\n appliedGroups: FilterGroup<T>[];\n appliedFilters: AppliedFilter[];\n removeGroup: (groupKey: string) => void;\n updateGroupValue: (groupKey: string, newValue: unknown) => void;\n getGroupOptions: (groupKey: string) => ColumnOption[];\n handleFiltersChange: (entries: FilterPopoverEntry[]) => void;\n isFilterValueEmpty: (v: unknown) => boolean;\n};\n\n/**\n * Adapter completo: ColumnDef + FilterModel ↔ FilterPopover/ToolbarApplied props.\n *\n * Encapsula a tradução entre o estado do DataTable (FilterModel.items lista flat)\n * e o estado visual do TableToolbar (chips agrupados por field+operator). Mantém\n * regras importantes:\n * - \"Phantom chip\" (item vazio renderiza chip se `pendingOpenChipKey` casa) pra\n * que o filter shortcut do header tenha popover âncora válido.\n * - `between` (tupla) → 1 item single com value=tupla; demais → spread em N items.\n * - `renderChipValue` do registry vence labelOf padrão.\n * - Items vazios filtrados na renderização normal (sem polluir o toolbar).\n */\nexport function useFilterPopoverAdapter<T>({\n effectiveColumns,\n allColumns,\n rows,\n filterModel,\n setFilterModel,\n colsByField,\n colLabelMap,\n pendingOpenChipKey,\n}: UseFilterPopoverAdapterParams<T>): UseFilterPopoverAdapterResult<T> {\n const filterPopoverColumns = useMemo<FilterPopoverColumn[]>(\n () =>\n effectiveColumns\n .filter((c) => c.enableColumnFilter)\n .map((c) => {\n let popoverType: FilterPopoverColumn[\"type\"] = \"text\";\n if (c.filterType === \"number\") popoverType = \"number\";\n else if (c.filterType === \"select\" || c.filterType === \"multiSelect\") {\n popoverType = \"select\";\n }\n let options = c.filterOptions?.map((o) => ({\n value: String(o.value),\n label: o.label,\n }));\n if (popoverType === \"select\" && (!options || options.length === 0) && rows) {\n const set = new Set<string>();\n for (const r of rows) {\n const v = c.valueGetter\n ? c.valueGetter(r)\n : (r as Record<string, unknown>)[String(c.field)];\n if (v != null && v !== \"\") set.add(String(v));\n }\n options = Array.from(set).map((v) => ({ value: v, label: v }));\n }\n return {\n key: String(c.field),\n label: c.headerName,\n type: popoverType,\n options,\n filterType: c.filterType,\n };\n }),\n [effectiveColumns, rows],\n );\n\n const filterPopoverEntries = useMemo<FilterPopoverEntry[]>(\n () =>\n filterModel.items.map((item) => ({\n id: item.id,\n columnKey: item.field,\n op: FILTER_OP_TO_POPOVER_OP[item.operator] ?? item.operator,\n value: item.value ?? \"\",\n })),\n [filterModel],\n );\n\n const appliedGroups = useMemo<FilterGroup<T>[]>(() => {\n const grouped = new Map<string, FilterItem[]>();\n for (const item of filterModel.items) {\n const key = `${item.field}|${item.operator}`;\n const isEmpty = isFilterValueEmpty(item.value);\n // Items vazios são pulados — exceção: pending pra abrir popover (filter shortcut)\n if (isEmpty && key !== pendingOpenChipKey) continue;\n if (!grouped.has(key)) grouped.set(key, []);\n grouped.get(key)!.push(item);\n }\n return Array.from(grouped.entries()).map(([key, items]) => ({\n key,\n field: items[0].field,\n operator: items[0].operator,\n items,\n }));\n }, [filterModel, pendingOpenChipKey]);\n\n const appliedFilters = useMemo<AppliedFilter[]>(\n () =>\n appliedGroups.map((g) => {\n const col = colsByField.get(g.field);\n const columnLabel = colLabelMap[g.field] ?? g.field;\n\n const labelOf = (v: unknown): string => {\n const opt = col?.filterOptions?.find(\n (o) => String(o.value) === String(v),\n );\n return opt?.label ?? String(v);\n };\n\n const typeId = col?.filterType ?? col?.type ?? \"text\";\n const typeDef = columnTypeRegistry.get(typeId);\n if (typeDef.renderChipValue && g.items.length > 0) {\n const chipValues = g.items.map((it) =>\n typeDef.renderChipValue!(it.value as never),\n );\n const filteredChips = chipValues.filter(\n (v) => v != null && v !== \"\",\n );\n const value: ReactNode | ReactNode[] =\n filteredChips.length === 1\n ? filteredChips[0]\n : filteredChips.length <= 2\n ? (filteredChips as ReactNode[])\n : `${filteredChips.length} selecionados`;\n return {\n id: g.key,\n columnLabel,\n op: FILTER_OP_TO_POPOVER_OP[g.operator] ?? g.operator,\n value,\n };\n }\n\n const allValues: string[] = [];\n for (const item of g.items) {\n if (Array.isArray(item.value)) {\n for (const v of item.value as unknown[]) allValues.push(labelOf(v));\n } else if (item.value != null) {\n allValues.push(labelOf(item.value));\n }\n }\n const value: ReactNode | ReactNode[] =\n allValues.length <= 2 ? allValues : `${allValues.length} selecionados`;\n return {\n id: g.key,\n columnLabel,\n op: FILTER_OP_TO_POPOVER_OP[g.operator] ?? g.operator,\n value,\n };\n }),\n [appliedGroups, colLabelMap, colsByField],\n );\n\n const removeGroup = (groupKey: string) => {\n const group = appliedGroups.find((g) => g.key === groupKey);\n if (!group) return;\n const ids = new Set(group.items.map((i) => i.id));\n setFilterModel({\n ...filterModel,\n items: filterModel.items.filter((i) => !ids.has(i.id)),\n });\n };\n\n const updateGroupValue = (groupKey: string, newValue: unknown) => {\n const group = appliedGroups.find((g) => g.key === groupKey);\n if (!group) return;\n const otherItems = filterModel.items.filter(\n (i) => !group.items.some((gi) => gi.id === i.id),\n );\n const newId = () =>\n typeof crypto !== \"undefined\" && \"randomUUID\" in crypto\n ? crypto.randomUUID()\n : `f-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n const newItems: FilterItem[] = [];\n const isTupleOperator = group.operator === \"between\";\n if (isTupleOperator) {\n const isEmpty =\n newValue == null ||\n (Array.isArray(newValue) &&\n newValue.every(\n (x) => x == null || (typeof x === \"string\" && x.length === 0),\n ));\n if (!isEmpty) {\n newItems.push({\n id: newId(),\n field: group.field,\n operator: group.operator,\n value: newValue as FilterItem[\"value\"],\n });\n }\n } else {\n const arr = Array.isArray(newValue)\n ? (newValue as unknown[])\n : newValue != null && newValue !== \"\"\n ? [newValue]\n : [];\n for (const v of arr) {\n newItems.push({\n id: newId(),\n field: group.field,\n operator: group.operator,\n value: v as FilterItem[\"value\"],\n });\n }\n }\n setFilterModel({\n ...filterModel,\n items: [...otherItems, ...newItems],\n });\n };\n\n const getGroupOptions = (groupKey: string): ColumnOption[] => {\n const group = appliedGroups.find((g) => g.key === groupKey);\n if (!group) return [];\n const col = colsByField.get(group.field);\n if (col?.filterOptions && col.filterOptions.length > 0) {\n return col.filterOptions.map((o) => ({\n label: o.label,\n value: o.value as string | number,\n color: o.color,\n }));\n }\n const rowsForExtract = rows ?? [];\n const set = new Set<string>();\n for (const r of rowsForExtract) {\n const v = col?.valueGetter\n ? col.valueGetter(r)\n : (r as Record<string, unknown>)[group.field];\n if (v != null && v !== \"\") set.add(String(v));\n }\n return Array.from(set).map((v) => ({ label: v, value: v }));\n };\n\n const handleFiltersChange = (entries: FilterPopoverEntry[]) => {\n const items: FilterItem[] = entries.map((e) => ({\n id: e.id,\n field: e.columnKey,\n operator: POPOVER_OP_TO_FILTER_OP[e.op] ?? (e.op as FilterItem[\"operator\"]),\n value: e.value as FilterItem[\"value\"],\n }));\n setFilterModel({ ...filterModel, items });\n };\n\n return {\n filterPopoverColumns,\n filterPopoverEntries,\n appliedGroups,\n appliedFilters,\n removeGroup,\n updateGroupValue,\n getGroupOptions,\n handleFiltersChange,\n isFilterValueEmpty,\n };\n}\n","import { useMemo } from \"react\";\nimport type { KanbanCardData, KanbanColumn } from \"../../Kanban\";\nimport { getFieldValue } from \"../utils/resolve-value\";\nimport type {\n DataTableKanbanConfig,\n GridRowId,\n} from \"../data-table.types\";\n\ntype UseDataTableViewModeOptions<T> = {\n /** Rows processadas (já com filter+search+sort aplicados pelo processor). */\n rows: T[];\n config: DataTableKanbanConfig<T> | undefined;\n /** Resolve id da row (default: row.id). */\n getRowId: (row: T) => GridRowId;\n};\n\ntype UseDataTableViewModeResult = {\n columns: KanbanColumn[];\n cards: KanbanCardData[];\n};\n\n/**\n * Transformer DataTable → Kanban.\n *\n * Recebe as rows já processadas pelo `useDataTableProcessor` (filter + search +\n * sort + selection aplicados) e produz `{ columns, cards }` no formato que o\n * `<Kanban>` primitive consome.\n *\n * Colunas:\n * - Quando `config.columns` é fornecido, usa diretamente (consumer controla ordem,\n * labels, dotColor, canReceiveDrop, canDragFrom).\n * - Caso contrário, deriva automaticamente: extrai valores únicos de\n * `groupByField` na ordem de primeira aparição, gera `KanbanColumn` com\n * `id = String(value)`, `label = String(value)` — sem dotColor.\n *\n * Cards:\n * - Cada row vira 1 `KanbanCardData` com:\n * - `id = getRowId(row)` convertido pra string (KanbanCardData.id é string)\n * - `columnId = String(row[groupByField])`\n * - Demais slots de `config.renderCard({ row })`\n * - Rows com `groupByField` resolvendo pra null/undefined são silenciosamente\n * omitidas (não há coluna fantasma \"sem categoria\"). Consumer pode declarar\n * uma coluna explícita com canReceiveDrop:false se quiser tratar esse caso.\n *\n * Performance: memoizado em `rows` + `config`. Não recomputa quando paginação\n * ou outros estados não-relevantes pra board mudam.\n */\nexport function useDataTableViewMode<T>({\n rows,\n config,\n getRowId,\n}: UseDataTableViewModeOptions<T>): UseDataTableViewModeResult {\n return useMemo(() => {\n if (!config) return { columns: [], cards: [] };\n\n const { groupByField, columns: explicitColumns, renderCard } = config;\n const field = String(groupByField);\n\n // Build cards primeiro — precisamos dos columnIds pra derivar colunas\n const cards: KanbanCardData[] = [];\n const seenColumnIds = new Set<string>();\n const orderedColumnIds: string[] = [];\n\n for (const row of rows) {\n const rawColumnValue = getFieldValue(row as Record<string, unknown>, field);\n if (rawColumnValue === null || rawColumnValue === undefined) continue;\n\n const columnId = String(rawColumnValue);\n const slots = renderCard({ row });\n\n cards.push({\n id: String(getRowId(row)),\n columnId,\n ...slots,\n });\n\n if (!seenColumnIds.has(columnId)) {\n seenColumnIds.add(columnId);\n orderedColumnIds.push(columnId);\n }\n }\n\n // Resolve colunas: explícitas (consumer controla) OU derivadas (ordem de aparição)\n const columns: KanbanColumn[] = explicitColumns\n ? explicitColumns\n : orderedColumnIds.map((id) => ({ id, label: id }));\n\n return { columns, cards };\n }, [rows, config, getRowId]);\n}\n","import { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { Ref, ReactNode } from \"react\";\nimport {\n DndContext,\n PointerSensor,\n KeyboardSensor,\n useSensor,\n useSensors,\n closestCenter,\n type DragEndEvent,\n} from \"@dnd-kit/core\";\nimport {\n SortableContext,\n horizontalListSortingStrategy,\n arrayMove,\n sortableKeyboardCoordinates,\n} from \"@dnd-kit/sortable\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { cn } from \"@/lib/utils\";\nimport {\n Table,\n TableBody,\n TableCell,\n TableCardRow,\n TableHead,\n TableHeadCell,\n TableRow,\n SELECTION_COLUMN_WIDTH,\n} from \"../Table\";\nimport { useMediaQuery } from \"../MenuSidebar/use-media-query\";\nimport { Checkbox } from \"@/components/shadcn/checkbox\";\nimport { Button } from \"@/components/ui/Button/button\";\nimport {\n MoreHorizontal,\n Rows2,\n Rows3,\n Rows4,\n SlidersHorizontal,\n ArrowUpDown,\n Columns,\n Download,\n RefreshCw,\n FileText,\n FileSpreadsheet,\n Filter as FilterIcon,\n ChevronRight,\n LayoutGrid,\n Table as TableIcon,\n} from \"lucide-react\";\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n} from \"@/components/shadcn/dropdown-menu\";\nimport {\n TableToolbar,\n ToolbarSearch,\n ToolbarToolButton,\n ToolbarSegmented,\n ToolbarDivider,\n ToolbarApplied,\n BulkActionsBar,\n FilterPopover,\n SortPopover,\n ColsPopover,\n TableToolbarViews,\n MoreMenu,\n MoreMenuItem as MoreMenuItemEl,\n MoreMenuSeparator,\n} from \"../TableToolbar\";\nimport type {\n FilterPopoverColumn,\n FilterPopoverEntry,\n SortPopoverColumn,\n SortPopoverCriterion,\n ColsPopoverColumn,\n ToolbarSegmentedItem,\n AppliedFilter,\n} from \"../TableToolbar\";\nimport { FooterTable, FooterTableSkeleton } from \"../FooterTable\";\nimport { Kanban } from \"../Kanban\";\nimport type {\n DataTableProps,\n DataTableColumnDef,\n DataTableRef,\n DataTableViewMode,\n FilterItem,\n FilterValue,\n DataTableExportFormat,\n DataTableMoreMenuItem,\n GridRowId,\n} from \"./data-table.types\";\nimport type { TableDensity } from \"../Table\";\nimport { dataTableStyles } from \"./data-table.styles\";\nimport { DataTableProvider } from \"./context/data-table-context\";\nimport { useDataTableController } from \"./hooks/use-data-table-controller\";\nimport { DataTableEmpty } from \"./parts/data-table-empty\";\nimport { DataTableLoading } from \"./parts/data-table-loading\";\nimport { DataTableNoResults } from \"./parts/data-table-no-results\";\nimport { DataTableColumnMenu } from \"./parts/data-table-column-menu\";\nimport { DataTableActionsCell } from \"./parts/data-table-actions-cell\";\nimport { DataTableSortableHeadCell } from \"./parts/sortable-head-cell\";\nimport { DataTableEditCell } from \"./parts/data-table-edit-cell\";\nimport { DataTableTotalizerRow } from \"./parts/data-table-totalizer-row\";\nimport { DataTableGroupHeaderRow } from \"./parts/data-table-group-header-row\";\nimport { DataTableGroupContentRow } from \"./parts/data-table-group-content-row\";\nimport { groupRows, isGroupRow, isGroupContent } from \"./utils/group-rows\";\nimport { DataTableRowExpansion } from \"./parts/data-table-row-expansion\";\nimport { expandRows, isExpansionRow } from \"./utils/expand-rows\";\nimport {\n POPOVER_OP_TO_FILTER_OP,\n FILTER_OP_TO_POPOVER_OP,\n} from \"./utils/operator-mapping\";\nimport { useSortPopoverAdapter } from \"./hooks/use-sort-popover-adapter\";\nimport { useColsPopoverAdapter } from \"./hooks/use-cols-popover-adapter\";\nimport { useFilterPopoverAdapter } from \"./hooks/use-filter-popover-adapter\";\nimport { useDataTableViewMode } from \"./hooks/use-data-table-view-mode\";\nimport { applyValueGetter } from \"./utils/resolve-value\";\nimport {\n Popover,\n PopoverTrigger,\n PopoverContent,\n} from \"../../shadcn/popover\";\nimport { columnTypeRegistry } from \"./column-types\";\nimport type { ColumnOption } from \"./column-types\";\n// DataTableFloatingBulkBar still exported from barrel for opt-in use;\n// default DataTable now uses inline BulkActionsBar via TableToolbar.bulkBar.\n\nconst styles = dataTableStyles();\n\n/* ── Density toggle items (stable ref) ────────────────────────────── */\n\nconst DENSITY_ITEMS: ToolbarSegmentedItem<TableDensity>[] = [\n { value: \"compact\", children: <Rows4 />, label: \"Compacto\" },\n { value: \"standard\", children: <Rows3 />, label: \"Padrão\" },\n { value: \"comfortable\", children: <Rows2 />, label: \"Confortável\" },\n];\n\n/* ── View mode toggle items (stable ref) ───────────────────────────── */\n\nconst DEFAULT_VIEW_MODE_ITEMS: ToolbarSegmentedItem<\"table\" | \"kanban\">[] = [\n { value: \"table\", children: <TableIcon />, label: \"Tabela\" },\n { value: \"kanban\", children: <LayoutGrid />, label: \"Kanban\" },\n];\n\n// Operator mapping consolidado em utils/operator-mapping.ts.\n\n/**\n * Resolve o valor de uma cell — delega pro shared `applyValueGetter`\n * (utils/resolve-value.ts) pra evitar duplicação com processor + group-rows.\n */\nfunction resolveCellValue<T>(\n row: T,\n col: DataTableColumnDef<T>,\n): unknown {\n return applyValueGetter(row, col);\n}\n\nfunction DataTableInternal<T>(\n props: DataTableProps<T>,\n ref: Ref<DataTableRef>,\n) {\n const controller = useDataTableController(props, ref);\n const {\n contextValue,\n isLoading,\n isDataEmpty,\n isNoResults,\n rowsToRender,\n rowsAllPagesProcessed,\n totalAfterFilter,\n cols,\n sort,\n pagination,\n selection,\n density,\n search,\n filters,\n exportHook,\n isServerMode,\n savedViews,\n applyView,\n applyViewById,\n applyDefault,\n saveCurrentAsView,\n query,\n // States novos centralizados (viewMode/groupBy/expandedRowIds + setters)\n viewMode,\n setViewMode,\n groupBy,\n expandedRowIds: controllerExpandedRowIds,\n toggleRowExpansion: controllerToggleRowExpansion,\n } = controller;\n\n const toolbarConfig = props.toolbar ?? {};\n const paginationConfig = props.paginationConfig ?? { enabled: true };\n const selectionConfig = props.selectionConfig ?? { enabled: false };\n\n const isKanban = viewMode === \"kanban\" && Boolean(props.kanbanConfig);\n\n const handleViewModeChange = useCallback(\n (mode: DataTableViewMode) => {\n setViewMode(mode);\n },\n [setViewMode],\n );\n\n /**\n * Resolved view toggle: consumer-provided OR auto-rendered.\n * Auto-render quando `kanbanConfig` está definido E `toolbar.viewToggle`\n * NÃO foi explicitamente passado (undefined = \"use default\"; null = \"esconder\").\n */\n const resolvedViewToggle = useMemo<ReactNode>(() => {\n if (props.toolbar?.viewToggle !== undefined) return props.toolbar.viewToggle;\n if (!props.kanbanConfig) return null;\n return (\n <ToolbarSegmented\n value={viewMode}\n onValueChange={handleViewModeChange}\n items={DEFAULT_VIEW_MODE_ITEMS}\n aria-label=\"Modo de visualização\"\n />\n );\n }, [props.toolbar?.viewToggle, props.kanbanConfig, viewMode, handleViewModeChange]);\n\n /* ── Kanban transformer (somente quando viewMode=kanban) ──────── */\n const kanbanView = useDataTableViewMode({\n // Em kanban, paginação não se aplica — usamos `rowsAllPagesProcessed`\n // (filter+search+sort completos, sem paginação) pra alimentar o board.\n rows: isKanban ? rowsAllPagesProcessed : ([] as T[]),\n config: isKanban ? props.kanbanConfig : undefined,\n getRowId: contextValue.getRowId,\n });\n\n /* ── Bridge selection (GridSelectionState ↔ Set<string>) ──────── */\n const kanbanSelectedIds = useMemo<Set<string> | undefined>(() => {\n if (!isKanban || !selectionConfig.enabled) return undefined;\n if (selection.state.type !== \"include\") return undefined; // exclude-mode N/A em kanban\n return new Set(Array.from(selection.state.ids).map(String));\n }, [isKanban, selectionConfig.enabled, selection.state]);\n\n /**\n * Lookup `cardId → row` memoizado pra bridges que precisam resolver row\n * original a partir do cardId (renderCardContent, getCardMenuItems,\n * toggleSelect, onOpenCard). Evita N find() lineares por render.\n */\n const kanbanCardIdToRow = useMemo<Map<string, T>>(() => {\n if (!isKanban) return new Map();\n const map = new Map<string, T>();\n for (const row of rowsAllPagesProcessed) {\n map.set(String(contextValue.getRowId(row)), row);\n }\n return map;\n }, [isKanban, rowsAllPagesProcessed, contextValue.getRowId]);\n\n const kanbanToggleSelect = useCallback(\n (cardId: string) => {\n if (!isKanban || !selectionConfig.enabled) return;\n const row = kanbanCardIdToRow.get(cardId);\n if (row) selection.toggleRow(row);\n },\n [isKanban, selectionConfig.enabled, kanbanCardIdToRow, selection],\n );\n\n /* ── Bridge getCardMenuItems (cardId → row → consumer fn) ─────── */\n const kanbanGetCardMenuItems = useMemo(() => {\n if (!isKanban || !props.kanbanConfig?.getCardMenuItems) return undefined;\n const userFn = props.kanbanConfig.getCardMenuItems;\n return (card: { id: string }) => {\n const row = kanbanCardIdToRow.get(card.id);\n return row ? userFn(row) : [];\n };\n }, [isKanban, props.kanbanConfig, kanbanCardIdToRow]);\n\n /* ── Bridge onOpenCard (delega ao onRowClick existente) ───────── */\n const kanbanOnOpenCard = useMemo(() => {\n if (!isKanban || !props.onRowClick) return undefined;\n const userFn = props.onRowClick;\n return (cardId: string) => {\n const row = kanbanCardIdToRow.get(cardId);\n if (row) userFn(row);\n };\n }, [isKanban, props.onRowClick, kanbanCardIdToRow]);\n\n /* ── Bridge renderCardContent (resolve row + delega) ──────────── */\n const kanbanRenderCardContent = useMemo(() => {\n if (!isKanban || !props.kanbanConfig?.renderCardContent) return undefined;\n const userFn = props.kanbanConfig.renderCardContent;\n return (params: { card: { id: string }; selected: boolean; open: boolean }) => {\n const row = kanbanCardIdToRow.get(params.card.id);\n if (!row) return null;\n return userFn({\n // KanbanRenderCardParams (do primitive) já entrega { card, selected, open }\n // mas o consumer do DataTable espera receber também a `row` original\n card: params.card as never,\n row,\n selected: params.selected,\n open: params.open,\n });\n };\n }, [isKanban, props.kanbanConfig, kanbanCardIdToRow]);\n\n /* ── Adapters: ColumnDef → FilterPopover props (extraído em hook) ── */\n\n /** Filter shortcut state — chip a abrir auto após click no header icon.\n * Mora aqui porque várias funções fora do adapter usam (handleFilterShortcut,\n * renderChip onOpenChange, isFilterValueEmpty cleanup). O adapter consome via prop. */\n const [pendingOpenChipKey, setPendingOpenChipKey] = useState<string | null>(null);\n\n /** Column label lookup for applied filter chips. */\n const colLabelMap = useMemo<Record<string, string>>(\n () =>\n Object.fromEntries(\n cols.effectiveColumns.map((c) => [String(c.field), c.headerName]),\n ),\n [cols.effectiveColumns],\n );\n\n /** Column lookup map for option label resolution. */\n const colsByField = useMemo(\n () => new Map(cols.effectiveColumns.map((c) => [String(c.field), c])),\n [cols.effectiveColumns],\n );\n\n const {\n filterPopoverColumns,\n filterPopoverEntries,\n appliedGroups,\n appliedFilters,\n removeGroup,\n updateGroupValue,\n getGroupOptions,\n handleFiltersChange,\n isFilterValueEmpty,\n } = useFilterPopoverAdapter({\n effectiveColumns: cols.effectiveColumns,\n allColumns: props.columns,\n rows: props.rows,\n filterModel: filters.filterModel,\n setFilterModel: filters.setFilterModel,\n colsByField,\n colLabelMap,\n pendingOpenChipKey,\n });\n\n /* ── Adapters: ColumnDef → SortPopover props (extraído em hook) ── */\n\n const {\n sortPopoverColumns,\n sortPopoverCriteria,\n handleSortChange,\n } = useSortPopoverAdapter({\n effectiveColumns: cols.effectiveColumns,\n sortModels: sort.sortModels,\n setSortModels: sort.setSortModels,\n });\n\n /* ── Adapters: ColumnDef → ColsPopover props (extraído em hook) ── */\n\n const {\n colsPopoverColumns,\n visibleColsSet,\n pinnedColsSet,\n handleVisibleChange,\n handlePinnedChange,\n handleColumnsReorder,\n } = useColsPopoverAdapter({\n columns: props.columns,\n hiddenColumns: cols.hiddenColumns,\n pinnedColumns: cols.pinnedColumns,\n handleShow: cols.handleShow,\n handleHide: cols.handleHide,\n handlePin: cols.handlePin,\n handleReorder: cols.handleReorder,\n });\n\n /* ── Saved Views: shape adapter pro TableToolbarViews ──────────── */\n // Mock sem multi-user: TODAS as views salvas localmente sao \"minhas\"\n // (eu sou o criador, posso deletar todas — publica ou privada).\n // Backend real depois vai mapear owner ao usuario que criou; views publicas\n // de OUTROS chegam com `owner: <id>` + `ownerName: \"Nome\"`.\n\n /**\n * Views pro toolbar: presets (read-only, owner='preset') primeiro,\n * depois as criadas pelo user (owner='me').\n */\n const viewsForToolbar = useMemo(\n () => [\n ...(props.defaultViews ?? []).map((p) => ({\n id: p.id,\n name: p.name,\n owner: \"preset\",\n })),\n ...savedViews.views.map((v) => ({\n id: v.id,\n name: v.name,\n owner: \"me\",\n })),\n ],\n [props.defaultViews, savedViews.views],\n );\n\n const handleViewApply = (id: string) => {\n applyViewById(id);\n };\n\n /* ── Refresh: server dispara refetch; client pisca spinner ────── */\n\n const [isRefreshing, setIsRefreshing] = useState(false);\n const handleRefresh = () => {\n if (isRefreshing) return;\n setIsRefreshing(true);\n if (isServerMode) {\n query.refresh();\n }\n // Mantem o spinner visivel por 400ms minimo (UX feedback)\n setTimeout(() => setIsRefreshing(false), 400);\n };\n\n /* ── Export config tipada ─────────────────────────────────────── */\n\n const exportConfig = useMemo(() => {\n const raw = toolbarConfig.enableExport;\n if (!raw) return null;\n const defaultCsv: DataTableExportFormat[] = [\n { id: \"csv\", label: \"CSV\", icon: <FileText /> },\n ];\n if (raw === true) {\n return { formats: defaultCsv, items: [] as DataTableMoreMenuItem[] };\n }\n return {\n formats: raw.formats?.length ? raw.formats : defaultCsv,\n items: raw.items ?? [],\n };\n }, [toolbarConfig.enableExport]);\n\n /* ── Column DnD (Fase C) ──────────────────────────────────────────\n * Sensors: PointerSensor com `distance: 5` exige 5px de drag antes de ativar —\n * preserva click-to-sort no header (click puro nao dispara dnd).\n * KeyboardSensor permite reordenar via teclado (Space/Enter pra \"pegar\",\n * Setas pra mover, Space/Enter pra soltar, Esc pra cancelar).\n */\n const dndSensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),\n useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),\n );\n\n const handleColumnDragEnd = (event: DragEndEvent) => {\n const { active, over } = event;\n if (!over || active.id === over.id) return;\n // active.id e over.id sao os fields (sortableId == field)\n const order = cols.columnOrder;\n const fromIdx = order.indexOf(String(active.id));\n const toIdx = order.indexOf(String(over.id));\n if (fromIdx < 0 || toIdx < 0) return;\n cols.handleReorder(arrayMove(order, fromIdx, toIdx));\n };\n\n // IDs dos itens sortable — usa columnOrder (que respeita visibilidade nao,\n // mas effectiveColumns sim). Usar effectiveColumns garante que itens hidden\n // nao entram no contexto (evita ID stale).\n const sortableIds = useMemo(\n () => cols.effectiveColumns.map((c) => String(c.field)),\n [cols.effectiveColumns],\n );\n\n /* ── Inline edit state (Fase D) ────────────────────────────────────\n * Uma celula editavel por vez. Identificada por { rowId, field }.\n * Double-click numa cell com `column.editable: true` entra em edit mode.\n * Commit (Enter/blur) chama `onCellEditCommit({id,field,value,oldValue,row})`.\n * Esc cancela sem chamar callback. */\n const [editingCell, setEditingCell] = useState<{\n rowId: GridRowId;\n field: string;\n } | null>(null);\n // Fase F.1 — async commit. Quando onCellEditCommit retorna Promise:\n // editLoading=true mostra spinner overlay + bloqueia input; editError guarda\n // mensagem se promise rejeitar (mantem edit aberto pra retry).\n const [editLoading, setEditLoading] = useState(false);\n const [editError, setEditError] = useState<string | null>(null);\n\n /** Adiciona filtro vazio pra coluna (ou abre o existente) + sinaliza pra abrir\n * o popover do chip correspondente. Operador default deriva do filterType:\n * - select/multiSelect → equals\n * - date → between (range — preset mais útil pra datas)\n * - demais (text/number) → contains */\n const handleFilterShortcut = (col: DataTableColumnDef<T>) => {\n const field = String(col.field);\n const isSelectish = col.filterType === \"select\" || col.filterType === \"multiSelect\";\n const isDate = col.filterType === \"date\";\n const operator: FilterItem[\"operator\"] = isSelectish\n ? \"equals\"\n : isDate\n ? \"between\"\n : \"contains\";\n const chipKey = `${field}|${operator}`;\n const initialValue: FilterValue = isDate ? [null, null] : \"\";\n\n // Se ja existe grupo pra essa coluna+operator, so abre. Senao, adiciona vazio + abre.\n const existing = filters.filterModel.items.find(\n (it) => it.field === field && it.operator === operator,\n );\n if (!existing) {\n filters.setFilterModel({\n ...filters.filterModel,\n items: [\n ...filters.filterModel.items,\n {\n id: `shortcut-${field}-${operator}-${Date.now()}`,\n field,\n operator,\n value: initialValue,\n },\n ],\n });\n }\n // setTimeout 0 garante que o chip ja foi renderizado quando setamos o pending\n setTimeout(() => setPendingOpenChipKey(chipKey), 0);\n };\n\n /* ── Keyboard nav state (Fase E.1) ────────────────────────────────\n * focusedRowIndex eh o indice (0-based) da row focada na pagina atual.\n * null = nenhuma. Setado pelo handler de keyDown abaixo e pelo click.\n * Row focada recebe tabIndex=0 + visual outline brand. Restante tabIndex=-1.\n * Auto-scroll via ref.scrollIntoView({block:\"nearest\"}). */\n const [focusedRowIndex, setFocusedRowIndex] = useState<number | null>(null);\n const rowRefs = useRef<Map<number, HTMLDivElement>>(new Map());\n\n // Reset focus quando a pagina muda (pagination, filter, sort, page size).\n // Sem isso, indice stale aponta pra row que nao existe mais.\n useEffect(() => {\n setFocusedRowIndex(null);\n }, [\n pagination.paginationModel.page,\n pagination.paginationModel.pageSize,\n filters.filterModel,\n search.debouncedValue,\n sort.sortModels,\n ]);\n\n const handleRowKeyDown = (\n e: React.KeyboardEvent<HTMLDivElement>,\n rowIndex: number,\n row: T,\n ) => {\n const lastIdx = rowsToRender.length - 1;\n let nextIdx: number | null = null;\n\n if (e.key === \"ArrowDown\") {\n nextIdx = Math.min(rowIndex + 1, lastIdx);\n } else if (e.key === \"ArrowUp\") {\n nextIdx = Math.max(rowIndex - 1, 0);\n } else if (e.key === \"Home\") {\n nextIdx = 0;\n } else if (e.key === \"End\") {\n nextIdx = lastIdx;\n } else if (e.key === \"PageDown\") {\n nextIdx = Math.min(rowIndex + 10, lastIdx);\n } else if (e.key === \"PageUp\") {\n nextIdx = Math.max(rowIndex - 10, 0);\n } else if (e.key === \"Enter\") {\n e.preventDefault();\n props.onRowClick?.(row);\n return;\n } else if (e.key === \" \" && selectionConfig.enabled) {\n e.preventDefault();\n selection.toggleRow(row);\n return;\n } else {\n return;\n }\n\n e.preventDefault();\n setFocusedRowIndex(nextIdx);\n // Foco programatico + scroll.\n // - Modo normal: setTimeout 0 (espera React reconciliar tabIndex) → focus + scrollIntoView.\n // - Modo virtualizado: scrollToIndex primeiro pra row entrar no DOM;\n // depois setTimeout maior (50ms) pra virtualizer renderizar; depois focus.\n if (virtualize) {\n rowVirtualizer.scrollToIndex(nextIdx, { align: \"auto\" });\n setTimeout(() => {\n const el = rowRefs.current.get(nextIdx!);\n el?.focus();\n }, 50);\n } else {\n setTimeout(() => {\n const el = rowRefs.current.get(nextIdx!);\n el?.focus();\n el?.scrollIntoView({ block: \"nearest\", behavior: \"smooth\" });\n }, 0);\n }\n };\n\n const handleCellEditCommit = async (params: {\n row: T;\n field: string;\n value: any;\n oldValue: any;\n }) => {\n const id = contextValue.getRowId(params.row);\n const result = props.onCellEditCommit?.({\n id,\n field: params.field,\n value: params.value,\n oldValue: params.oldValue,\n row: params.row,\n });\n // Sincrono ou sem callback → fecha imediato\n if (!(result instanceof Promise)) {\n setEditingCell(null);\n setEditError(null);\n return;\n }\n // Async: loading overlay + await + tratamento de erro.\n setEditLoading(true);\n setEditError(null);\n try {\n await result;\n setEditingCell(null);\n } catch (err) {\n setEditError(err instanceof Error ? err.message : String(err));\n // NAO fecha — user pode corrigir e tentar de novo, ou Esc pra cancelar\n } finally {\n setEditLoading(false);\n }\n };\n\n /** Cancelamento manual (Esc) — limpa tudo. */\n const handleCellEditCancel = () => {\n setEditingCell(null);\n setEditLoading(false);\n setEditError(null);\n };\n\n /* ── Agrupamento — Fase F.4 ────────────────────────────────────────\n * `groupBy` vem do controller (controlled/uncontrolled). Quando definido,\n * rows são reshape em (GroupRow | T)[] alternados. expandedGroupKeys guarda\n * toggles DIFERENTES do default — if defaultGroupExpanded=true: keys no set\n * são collapsed; vice-versa. Permite \"expandir tudo\" sem precisar setar N\n * keys explicitamente. */\n const groupByField = groupBy;\n const defaultGroupExpanded = props.defaultGroupExpanded !== false; // default true\n const [expandedGroupKeys, setExpandedGroupKeys] = useState<Set<string>>(\n () => new Set(),\n );\n const groupColumn = useMemo(\n () =>\n groupByField\n ? props.columns.find((c) => String(c.field) === groupByField)\n : undefined,\n [props.columns, groupByField],\n );\n const useCustomGroupContent = !!props.renderGroupContent;\n const groupedRows = useMemo(() => {\n if (!groupByField) return rowsToRender;\n return groupRows(\n rowsToRender,\n groupByField,\n expandedGroupKeys,\n defaultGroupExpanded,\n groupColumn,\n useCustomGroupContent,\n );\n }, [\n rowsToRender,\n groupByField,\n expandedGroupKeys,\n defaultGroupExpanded,\n groupColumn,\n useCustomGroupContent,\n ]);\n\n const toggleGroup = (key: string) => {\n setExpandedGroupKeys((prev) => {\n const next = new Set(prev);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n return next;\n });\n };\n\n /* ── Row expansion — Fase F.4b ──────────────────────────────────────\n * State `expandedRowIds: GridRowId[]` vem do controller (controlled/\n * uncontrolled). Aliasing local com Set pra preservar API interna usada\n * por `isRowExpanded` lookups O(1) + iteração. */\n const expandedRowIds = useMemo(\n () => new Set(controllerExpandedRowIds),\n [controllerExpandedRowIds],\n );\n const useRowExpansion = !!props.renderRowExpansion && !groupByField;\n\n const toggleRowExpansion = controllerToggleRowExpansion;\n\n // Pre-compute expandable column field pra usar no cell render\n const expandableColField = useMemo(() => {\n if (!useRowExpansion) return null;\n const col = props.columns.find((c) => c.expandable === true);\n return col ? String(col.field) : null;\n }, [props.columns, useRowExpansion]);\n\n // Array de items renderizados — quando há expansion, intercala markers.\n // Mutuamente exclusivo com groupBy (que tem precedência).\n const finalItems = useMemo(() => {\n if (groupByField) return groupedRows;\n if (useRowExpansion && expandedRowIds.size > 0) {\n return expandRows(rowsToRender, expandedRowIds, contextValue.getRowId);\n }\n return rowsToRender;\n }, [\n groupByField,\n groupedRows,\n useRowExpansion,\n expandedRowIds,\n rowsToRender,\n contextValue,\n ]);\n\n /* ── Virtualização — Fase F.3 ──────────────────────────────────────\n * Quando props.virtualize, renderiza apenas rows visíveis. Estimate de\n * row height deriva de density (compact=40, standard=56, comfortable=64).\n * Consumer pode override via props.estimateRowHeight. */\n const scrollContainerRef = useRef<HTMLDivElement | null>(null);\n const defaultRowHeight =\n density.density === \"compact\"\n ? 40\n : density.density === \"comfortable\"\n ? 64\n : 56;\n const estimateRowHeight = props.estimateRowHeight ?? defaultRowHeight;\n const virtualize = props.virtualize === true;\n\n const rowVirtualizer = useVirtualizer({\n // count cobre todos os casos: rows simples, agrupadas, ou com expansion intercalada\n count: virtualize ? finalItems.length : 0,\n getScrollElement: () => scrollContainerRef.current,\n estimateSize: () => estimateRowHeight,\n overscan: props.overscan ?? 10,\n });\n\n /* ── Body content (Table primitivo) ───────────────────────────── */\n\n const tableBody = (\n <DndContext\n sensors={dndSensors}\n collisionDetection={closestCenter}\n onDragEnd={handleColumnDragEnd}\n >\n <Table\n density={density.density}\n cardBreakpoint={props.cardBreakpoint ?? 768}\n className=\"min-h-0 max-h-full\"\n scrollRef={scrollContainerRef}\n >\n <TableHead>\n {selectionConfig.enabled && (\n <TableHeadCell width={SELECTION_COLUMN_WIDTH} align=\"center\" purpose=\"selection\">\n <Checkbox\n checked={\n selection.isPageSelected(rowsToRender)\n ? true\n : selection.isPageIndeterminate(rowsToRender)\n ? \"indeterminate\"\n : false\n }\n onCheckedChange={() => selection.togglePage(rowsToRender)}\n aria-label=\"Selecionar página\"\n />\n </TableHeadCell>\n )}\n <SortableContext items={sortableIds} strategy={horizontalListSortingStrategy}>\n {cols.effectiveColumns.map((col) => {\n const field = String(col.field);\n const isActions = col.type === \"actions\";\n return (\n <DataTableSortableHeadCell\n key={field}\n sortableId={field}\n disableDrag={isActions}\n field={field}\n width={cols.columnWidths[field]}\n pinned={col.pinned}\n pinOffset={cols.stickyOffsets[field]}\n align={col.align}\n purpose={isActions ? \"actions\" : undefined}\n sortable={!isActions && col.sortable !== false}\n sortDirection={\n sort.sortModels.find((s) => s.field === field)?.direction ?? null\n }\n sortIndex={(() => {\n // Mostra badge 1/2/3... apenas quando ha multi-sort (>= 2 criterios).\n if (sort.sortModels.length < 2) return undefined;\n const idx = sort.sortModels.findIndex((s) => s.field === field);\n return idx >= 0 ? idx + 1 : undefined;\n })()}\n onSortClick={() => sort.handleSort(field)}\n resizable={!isActions && col.resizable !== false}\n // Comita no state APENAS no mouseup — durante o drag a largura\n // é atualizada via DOM direto pelo TableHeadCell (sem re-render\n // do DataTable a cada mousemove, que parecia \"atualizando\").\n onResizeEnd={(w) => cols.handleResize(field, w)}\n icon={\n isActions\n ? undefined\n : col.icon ??\n (col.type ? columnTypeRegistry.get(col.type).defaultIcon : undefined)\n }\n headMenu={\n !isActions ? (\n <>\n {/* Filter shortcut — abre popover do chip da coluna pra digitar valor.\n Se ja existe filtro, reabre. Visivel apenas em colunas enableColumnFilter. */}\n {col.enableColumnFilter && (\n <Button\n size=\"icon-2xs\"\n variant=\"ghost\"\n color=\"secondary\"\n aria-label={`Filtrar ${col.headerName}`}\n title={`Filtrar ${col.headerName}`}\n onClick={(e) => {\n e.stopPropagation();\n handleFilterShortcut(col);\n }}\n onPointerDown={(e) => e.stopPropagation()}\n onMouseDown={(e) => e.stopPropagation()}\n >\n <FilterIcon />\n </Button>\n )}\n {col.enableColumnMenu !== false && (\n <DataTableColumnMenu\n columnName={col.headerName}\n sortDirection={\n sort.sortModels.find((s) => s.field === field)?.direction ?? null\n }\n pinned={\n cols.pinnedColumns[field] === \"left\"\n ? \"left\"\n : cols.pinnedColumns[field] === \"right\"\n ? \"right\"\n : null\n }\n canHide={col.hideable !== false}\n onSortAsc={() =>\n sort.setSortModels([{ field, direction: \"asc\" }])\n }\n onSortDesc={() =>\n sort.setSortModels([{ field, direction: \"desc\" }])\n }\n onSortClear={() => sort.setSortModels([])}\n onPinLeft={() => cols.handlePin(field, \"left\")}\n onPinRight={() => cols.handlePin(field, \"right\")}\n onUnpin={() => cols.handlePin(field, undefined)}\n onHide={() => cols.handleHide(field)}\n extraItems={col.columnMenuItems}\n />\n )}\n </>\n ) : undefined\n }\n >\n {/* Header da coluna actions é sempre vazio — independe do `headerName`\n passado pelo consumer (uniformiza padrão de UX). */}\n {isActions ? null : col.headerName}\n </DataTableSortableHeadCell>\n );\n })}\n </SortableContext>\n </TableHead>\n <TableBody\n // Modo virtualizado é prop do TableBody primitive — aplica\n // height/position/block internamente. Sem hardcode no DataTable.\n virtualized={\n virtualize ? { totalHeight: rowVirtualizer.getTotalSize() } : undefined\n }\n >\n {(() => {\n // Branching: GroupHeader / GroupContent / DataRow.\n // - GroupHeader: column-aligned default, ou free-form via renderGroupHeader.\n // - GroupContent: slot custom (só aparece quando renderGroupContent definido) —\n // substitui as N child rows por 1 row full-width com conteudo livre.\n // - DataRow: fluxo normal (TableRow + cells).\n const renderItem = (\n item: T | (typeof groupedRows[number] & { __type?: symbol }),\n index: number,\n virtualStyle?: React.CSSProperties,\n ) => {\n if (isGroupRow<T>(item)) {\n return (\n <DataTableGroupHeaderRow\n key={item.key}\n group={item}\n columns={cols.effectiveColumns}\n columnWidths={cols.columnWidths}\n stickyOffsets={cols.stickyOffsets}\n hasSelection={selectionConfig.enabled === true}\n onToggle={() => toggleGroup(item.key)}\n style={virtualStyle}\n renderHeader={props.renderGroupHeader}\n />\n );\n }\n if (isGroupContent<T>(item) && props.renderGroupContent) {\n return (\n <DataTableGroupContentRow\n key={`${item.key}-content`}\n group={item.group}\n render={props.renderGroupContent}\n style={virtualStyle}\n />\n );\n }\n if (isExpansionRow<T>(item) && props.renderRowExpansion) {\n return (\n <DataTableRowExpansion\n key={`exp-${String(item.id)}`}\n row={item.row}\n render={props.renderRowExpansion}\n style={virtualStyle}\n />\n );\n }\n const row = item as T;\n return renderRow(row, index, virtualStyle);\n };\n\n const renderRow = (\n row: T,\n index: number,\n virtualStyle?: React.CSSProperties,\n ) => {\n const isSel = selection.isRowSelected(row);\n const rowClass = props.getRowClassName?.({ row, index });\n const isRowFocused = focusedRowIndex === index;\n return (\n <TableRow\n key={String(contextValue.getRowId(row))}\n ref={(el) => {\n if (el) rowRefs.current.set(index, el);\n else rowRefs.current.delete(index);\n }}\n selected={isSel}\n focused={isRowFocused}\n clickable={!!props.onRowClick}\n onClick={() => {\n setFocusedRowIndex(index);\n props.onRowClick?.(row);\n }}\n rootProps={{\n onKeyDown: (e) => handleRowKeyDown(e, index, row),\n onFocus: () => {\n // Atualiza focused quando Tab traz foco direto (sem keyDown anterior)\n if (focusedRowIndex !== index) setFocusedRowIndex(index);\n },\n style: virtualStyle,\n }}\n className={rowClass}\n >\n {selectionConfig.enabled && (\n <TableCell width={SELECTION_COLUMN_WIDTH} align=\"center\" purpose=\"selection\">\n <Checkbox\n checked={isSel}\n onCheckedChange={() => selection.toggleRow(row)}\n onClick={(e) => e.stopPropagation()}\n aria-label=\"Selecionar linha\"\n />\n </TableCell>\n )}\n {cols.effectiveColumns.map((col) => {\n const field = String(col.field);\n const isActionsCol = col.type === \"actions\";\n const value = isActionsCol ? undefined : resolveCellValue(row, col);\n const rowId = contextValue.getRowId(row);\n const isEditingThisCell =\n editingCell?.rowId === rowId && editingCell.field === field;\n const isEditable = !isActionsCol && col.editable === true;\n // Fase F.4b — coluna marcada como expand trigger.\n // Mostra chevron + cursor pointer; click toggla expansão da row.\n const isExpandableCol =\n useRowExpansion && col.expandable === true && field === expandableColField;\n const isRowExpanded = expandedRowIds.has(rowId);\n\n // Actions column com getActions → auto-renderiza DataTableActionsCell.\n // Se consumer passar `render` numa coluna actions, render ganha (escape hatch).\n // Inline edit (isEditingThisCell) → DataTableEditCell substitui o content.\n // Expandable col → prefixa chevron antes do content.\n // Fase G.2 — fallback chain:\n // 1. col.render (consumer custom)\n // 2. registry.renderCell (tipo prebuilt)\n // 3. col.valueFormatter\n // 4. registry.formatValue\n // 5. raw value\n const typeDef = col.type\n ? columnTypeRegistry.get(col.type)\n : undefined;\n const baseContent = isEditingThisCell\n ? (\n <DataTableEditCell\n column={col}\n row={row}\n initialValue={value}\n isLoading={editLoading}\n error={editError}\n onCommit={(newValue) =>\n handleCellEditCommit({\n row,\n field,\n value: newValue,\n oldValue: value,\n })\n }\n onCancel={handleCellEditCancel}\n />\n )\n : isActionsCol && col.getActions && !col.render\n ? (\n <DataTableActionsCell\n row={row}\n actions={col.getActions({ row })}\n />\n )\n : col.render\n ? col.render({ row, value })\n : typeDef?.renderCell\n ? typeDef.renderCell({\n value,\n row,\n options: col.filterOptions,\n column: {\n field: String(col.field),\n headerName: col.headerName,\n valueFormatter: col.valueFormatter,\n typeOptions: col.typeOptions,\n },\n })\n : col.valueFormatter\n ? col.valueFormatter(value)\n : typeDef?.formatValue\n ? typeDef.formatValue(value)\n : value;\n const content = isExpandableCol ? (\n <span className=\"flex items-center gap-gp-md w-full\">\n <ChevronRight\n className={cn(\n \"shrink-0 size-icon-sm text-fg-muted transition-transform duration-150\",\n isRowExpanded && \"rotate-90\",\n )}\n aria-hidden\n />\n <span className=\"flex-1 min-w-0\">{baseContent as ReactNode}</span>\n </span>\n ) : (\n baseContent\n );\n // Tooltip nativo: string formatada quando ellipsis ou texto plano (sem custom render)\n // Nao aplica em colunas actions (icones tem proprio title) ou em cell em edicao.\n const tooltipText =\n isActionsCol || isEditingThisCell\n ? undefined\n : col.ellipsis || !col.render\n ? col.valueFormatter\n ? col.valueFormatter(value)\n : value != null\n ? String(value)\n : undefined\n : undefined;\n // onDoubleClick em celulas editaveis entra em edit mode.\n // onClick em cells expandable toggla expansão da row.\n // stopPropagation em ambos evita disparar onRowClick.\n const cellRootProps: React.HTMLAttributes<HTMLDivElement> | undefined =\n isEditable || isExpandableCol\n ? {\n ...(isEditable && {\n onDoubleClick: (e: React.MouseEvent) => {\n e.stopPropagation();\n setEditingCell({ rowId, field });\n },\n \"data-editable\": \"true\",\n }),\n ...(isExpandableCol && {\n onClick: (e: React.MouseEvent) => {\n e.stopPropagation();\n toggleRowExpansion(rowId);\n },\n \"data-expandable\": \"true\",\n \"aria-expanded\": isRowExpanded,\n style: { cursor: \"pointer\" },\n }),\n }\n : undefined;\n // Fase G.2 — defaults vindos do registry quando consumer não override\n const effectiveAlign = col.align ?? typeDef?.defaultAlign;\n const effectiveEllipsis = col.ellipsis ?? typeDef?.defaultEllipsis;\n return (\n <TableCell\n key={field}\n field={field}\n width={cols.columnWidths[field]}\n pinned={col.pinned}\n pinOffset={cols.stickyOffsets[field]}\n align={effectiveAlign}\n ellipsis={effectiveEllipsis}\n purpose={isActionsCol ? \"actions\" : undefined}\n label={col.headerName}\n tooltip={tooltipText}\n rootProps={cellRootProps}\n // Celula em edicao remove padding pra editor ocupar 100% sem margem\n className={isEditingThisCell ? \"!px-pad-xs !py-0\" : undefined}\n >\n {content as ReactNode}\n </TableCell>\n );\n })}\n </TableRow>\n );\n };\n\n // Render: virtualizado vs todos as rows. `finalItems` cobre rows\n // simples + agrupadas + com expansion intercalada.\n if (virtualize) {\n return rowVirtualizer.getVirtualItems().map((vi) =>\n renderItem(finalItems[vi.index], vi.index, {\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: `${vi.size}px`,\n transform: `translateY(${vi.start}px)`,\n }),\n );\n }\n return finalItems.map((item, i) => renderItem(item, i));\n })()}\n {/* Totalizer footer row (Fase E.2) — sticky no bottom do body */}\n {props.showTotalizers && (\n <DataTableTotalizerRow\n columns={cols.effectiveColumns}\n rows={rowsAllPagesProcessed}\n overrides={props.aggregateRow}\n columnWidths={cols.columnWidths}\n stickyOffsets={cols.stickyOffsets}\n hasSelection={selectionConfig.enabled === true}\n />\n )}\n </TableBody>\n </Table>\n </DndContext>\n );\n\n /* ── Card mode (responsivo mobile) ────────────────────────────────\n * Quando `cardBreakpoint` está habilitado e o viewport é menor que ele,\n * renderiza cada row como `<TableCardRow>` em vez de `<TableRow>`. O\n * toolbar e footer continuam idênticos — só o body que troca de view.\n *\n * Mapeamento das colunas → card:\n * - selection (checkbox) → header do card (esquerda)\n * - col.isPrimary OU 1ª não-actions → header do card (label primário)\n * - col.type === \"actions\" → headerActions (canto sup. direito)\n * - resto das colunas visíveis → items label/value no body\n *\n * Não suportado em card mode (degradam silenciosamente):\n * - Virtualização (renderiza todas as rows)\n * - Row expansion (toggle escondido)\n * - Inline editing (double-click pra editar)\n * - Column reordering / pinning / resize (sem sentido num card vertical)\n */\n const cardBp = props.cardBreakpoint ?? 768;\n const cardModeQuery =\n cardBp === false ? \"(max-width: 0px)\" : `(max-width: ${cardBp - 1}px)`;\n const isCardMode =\n useMediaQuery(cardModeQuery) && cardBp !== false && !isKanban;\n\n /** Render do conteúdo de uma cell — versão simplificada (sem edit/expansion). */\n const getCardCellContent = (\n col: (typeof cols.effectiveColumns)[number],\n row: T,\n ): ReactNode => {\n const isActionsCol = col.type === \"actions\";\n const value = isActionsCol ? undefined : resolveCellValue(row, col);\n const typeDef = col.type ? columnTypeRegistry.get(col.type) : undefined;\n\n if (isActionsCol && col.getActions && !col.render) {\n return (\n <DataTableActionsCell row={row} actions={col.getActions({ row })} />\n );\n }\n if (col.render) {\n return col.render({ row, value });\n }\n if (typeDef?.renderCell) {\n return typeDef.renderCell({\n value,\n row,\n options: col.filterOptions,\n column: {\n field: String(col.field),\n headerName: col.headerName,\n valueFormatter: col.valueFormatter,\n typeOptions: col.typeOptions,\n },\n });\n }\n if (col.valueFormatter) return col.valueFormatter(value) as ReactNode;\n if (typeDef?.formatValue) return typeDef.formatValue(value) as ReactNode;\n return value as ReactNode;\n };\n\n // Resolve colunas especiais uma vez fora do map (evita re-cálculo por row)\n const cardPrimaryCol = isCardMode\n ? cols.effectiveColumns.find((c) => c.isPrimary) ??\n cols.effectiveColumns.find((c) => c.type !== \"actions\")\n : undefined;\n const cardActionsCol = isCardMode\n ? cols.effectiveColumns.find((c) => c.type === \"actions\")\n : undefined;\n const cardItemCols = isCardMode\n ? cols.effectiveColumns.filter(\n (c) => c !== cardPrimaryCol && c !== cardActionsCol,\n )\n : [];\n\n const cardBody = (\n <div className=\"flex flex-col gap-gp-md p-pad-2xl overflow-auto scrollbar-thin min-h-0 flex-1\">\n {rowsToRender.map((row, index) => {\n const isSel = selection.isRowSelected(row);\n const rowId = contextValue.getRowId(row);\n return (\n <TableCardRow\n key={String(rowId)}\n selected={isSel}\n clickable={!!props.onRowClick}\n onClick={\n props.onRowClick ? () => props.onRowClick?.(row) : undefined\n }\n header={\n <>\n {selectionConfig.enabled && (\n <Checkbox\n checked={isSel}\n onCheckedChange={() => selection.toggleRow(row)}\n onClick={(e) => e.stopPropagation()}\n aria-label=\"Selecionar linha\"\n />\n )}\n {cardPrimaryCol && (\n <div className=\"font-medium text-fg-default truncate flex-1 min-w-0\">\n {getCardCellContent(cardPrimaryCol, row)}\n </div>\n )}\n </>\n }\n headerActions={\n cardActionsCol\n ? getCardCellContent(cardActionsCol, row)\n : undefined\n }\n items={cardItemCols.map((col) => ({\n key: String(col.field),\n label: col.headerName ?? String(col.field),\n value: getCardCellContent(col, row),\n }))}\n />\n );\n })}\n </div>\n );\n\n /* ── Render principal ─────────────────────────────────────────── */\n\n return (\n <DataTableProvider value={contextValue}>\n <div className={cn(styles.root(), props.className)}>\n {/* Toolbar */}\n <div className={styles.toolbarWrap()}>\n <TableToolbar\n left={\n <>\n {/* Input area — Search + Refresh juntos (sem divider entre eles) */}\n {toolbarConfig.enableSearch !== false && (\n <ToolbarSearch\n value={search.inputValue}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n search.setInputValue(e.target.value)\n }\n placeholder=\"Buscar...\"\n />\n )}\n {toolbarConfig.enableRefresh !== false && (\n <ToolbarToolButton\n icon={\n <RefreshCw\n className={isRefreshing ? \"animate-spin\" : \"\"}\n />\n }\n aria-label=\"Atualizar\"\n onClick={handleRefresh}\n />\n )}\n\n {/* Divider — só aparece se há algo do lado direito */}\n {(resolvedViewToggle || props.persistId || toolbarConfig.customLeft) && (\n <ToolbarDivider />\n )}\n\n {/* View toggle (table/kanban) — slot dedicado, auto OU consumer-provided */}\n {resolvedViewToggle}\n\n {/* Saved Views — opt-in via persistId */}\n {props.persistId && (\n <TableToolbarViews\n views={viewsForToolbar}\n activeViewId={savedViews.currentViewId ?? undefined}\n onApply={handleViewApply}\n onApplyDefault={applyDefault}\n onDelete={savedViews.deleteView}\n onSave={async (data) => {\n await saveCurrentAsView(data.name, {\n isPublic: data.isPublic,\n });\n }}\n // Divider já foi colocado acima; views ficam coladas\n hideDivider\n />\n )}\n\n {/* Slot livre (mantém retrocompat) */}\n {toolbarConfig.customLeft}\n </>\n }\n actions={\n <>\n {/* FilterPopover — Filtrar */}\n {toolbarConfig.enableFilters !== false && filterPopoverColumns.length > 0 && (\n <FilterPopover\n columns={filterPopoverColumns}\n filters={filterPopoverEntries}\n onFiltersChange={handleFiltersChange}\n enableAdvanced\n // Fase G.1 — delega input de valor pro registry, eliminando\n // o text input genérico pra date/multiSelect/boolean/etc.\n // FilterPopoverEntry.value agora é `unknown` — passa direto\n // sem stringify (preserva arrays/tuplas pra multiSelect/between).\n renderValueInput={({ column, operator, value, onChange }) => {\n const typeId = column.filterType ?? column.type ?? \"text\";\n const def = columnTypeRegistry.get(typeId);\n const filterOp =\n POPOVER_OP_TO_FILTER_OP[operator] ??\n (operator as FilterItem[\"operator\"]);\n return def.renderFilterInput({\n value: value as never,\n onChange: (v) => onChange(v),\n operator: filterOp,\n options: column.options,\n });\n }}\n trigger={\n <ToolbarToolButton\n icon={<SlidersHorizontal />}\n label=\"Filtrar\"\n isActive={filterPopoverEntries.length > 0}\n hasIndicator={filterPopoverEntries.length > 0}\n />\n }\n />\n )}\n {/* SortPopover — Ordenar */}\n <SortPopover\n columns={sortPopoverColumns}\n sortBy={sortPopoverCriteria}\n onSortByChange={handleSortChange}\n trigger={\n <ToolbarToolButton\n icon={<ArrowUpDown />}\n aria-label=\"Ordenar\"\n hasIndicator={sortPopoverCriteria.length > 0}\n />\n }\n />\n {/* ColsPopover — Colunas */}\n {toolbarConfig.enableColumns !== false && (\n <ColsPopover\n columns={colsPopoverColumns}\n visibleCols={visibleColsSet}\n onVisibleChange={handleVisibleChange}\n pinnedCols={pinnedColsSet}\n onPinnedChange={handlePinnedChange}\n onColumnsReorder={handleColumnsReorder}\n trigger={\n <ToolbarToolButton\n icon={<Columns />}\n aria-label=\"Colunas\"\n />\n }\n />\n )}\n\n {/* Divider antes do Density */}\n {toolbarConfig.enableDensity !== false && <ToolbarDivider />}\n\n {/* Density toggle */}\n {toolbarConfig.enableDensity !== false && (\n <ToolbarSegmented\n value={density.density}\n onValueChange={(v) => density.setDensity(v as TableDensity)}\n items={props.densityItems ?? DENSITY_ITEMS}\n ariaLabel=\"Densidade da tabela\"\n />\n )}\n\n {/* Divider antes da area de actions (Export/MoreMenu) */}\n {(exportConfig || toolbarConfig.moreMenu?.items?.length) && (\n <ToolbarDivider />\n )}\n\n {/* Export dropdown — formatos + items append */}\n {exportConfig && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <ToolbarToolButton\n icon={<Download />}\n label=\"Exportar\"\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {exportConfig.formats.map((fmt) => {\n const isCsvDefault = fmt.id === \"csv\" && !fmt.onSelect;\n if (!isCsvDefault) {\n return (\n <DropdownMenuItem\n key={fmt.id}\n onClick={fmt.onSelect}\n >\n {fmt.icon}\n {fmt.label}\n </DropdownMenuItem>\n );\n }\n // CSV default: usa escopos internos\n return (\n <div key={fmt.id}>\n {isServerMode ? (\n <DropdownMenuItem onClick={() => exportHook.exportCsv(\"all\")}>\n {fmt.icon}\n {fmt.label} — Página atual\n </DropdownMenuItem>\n ) : (\n <>\n <DropdownMenuItem onClick={() => exportHook.exportCsv(\"all\")}>\n {fmt.icon}\n {fmt.label} — Todos\n </DropdownMenuItem>\n <DropdownMenuItem onClick={() => exportHook.exportCsv(\"filtered\")}>\n {fmt.icon}\n {fmt.label} — Filtrados\n </DropdownMenuItem>\n </>\n )}\n <DropdownMenuItem\n onClick={() => exportHook.exportCsv(\"selected\")}\n disabled={selection.selectedCount === 0}\n >\n {fmt.icon}\n {fmt.label} — Selecionados ({selection.selectedCount})\n </DropdownMenuItem>\n </div>\n );\n })}\n {exportConfig.items.length > 0 && (\n <>\n <DropdownMenuItem disabled className=\"opacity-50\">\n ───\n </DropdownMenuItem>\n {exportConfig.items.map((it) => (\n <DropdownMenuItem\n key={it.id}\n onClick={it.onSelect}\n disabled={it.disabled}\n >\n {it.icon}\n {it.label}\n </DropdownMenuItem>\n ))}\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n\n {/* MoreMenu — ⋯ padrao com items custom */}\n {toolbarConfig.moreMenu?.items?.length ? (\n <MoreMenu\n trigger={\n <ToolbarToolButton\n icon={<MoreHorizontal />}\n aria-label=\"Mais opções\"\n />\n }\n >\n {toolbarConfig.moreMenu.items.map((it) => (\n <MoreMenuItemEl\n key={it.id}\n onSelect={it.onSelect}\n disabled={it.disabled}\n variant={it.destructive ? \"destructive\" : \"default\"}\n >\n {it.icon}\n {it.label}\n </MoreMenuItemEl>\n ))}\n </MoreMenu>\n ) : null}\n\n {/* Legacy slot — deprecated, mantem pra compat */}\n {toolbarConfig.customActions}\n </>\n }\n bulkBar={\n selectionConfig.enabled && selection.selectedCount > 0 ? (\n <BulkActionsBar\n count={selection.selectedCount}\n onClear={selection.clear}\n >\n {selectionConfig.actions?.(selection.selectedIds, selection.clear)}\n </BulkActionsBar>\n ) : undefined\n }\n />\n {/* Applied filter chips — agrupados por field+operator, clicaveis via renderChip → Popover.\n `pendingOpenId` deixa ToolbarApplied controlar visual de \"abrir auto\" sem\n o DataTable precisar saber qual chip está pendente (state mora no toolbar). */}\n <ToolbarApplied\n filters={appliedFilters}\n onRemove={removeGroup}\n onClearAll={filters.clearFilters}\n pendingOpenId={pendingOpenChipKey}\n onPendingOpenIdChange={setPendingOpenChipKey}\n renderChip={(f, defaultChip, isPendingOpen) => {\n const group = appliedGroups.find((g) => g.key === f.id);\n if (!group) return defaultChip;\n const col = colsByField.get(group.field);\n const items = group.items;\n // `between` (date/number range) é um caso especial — operador tupla.\n // Não spread, não promove pra multiSelect, usa o column-type direto\n // e passa value como tupla pro renderFastFilterInput.\n const isTupleOperator = group.operator === \"between\";\n const aggregateValues = isTupleOperator\n ? []\n : items.flatMap((it) =>\n Array.isArray(it.value)\n ? (it.value as unknown[])\n : it.value != null\n ? [it.value]\n : [],\n );\n const useMulti =\n !isTupleOperator &&\n (aggregateValues.length > 1 ||\n group.operator === \"isAnyOf\" ||\n group.operator === \"isNoneOf\" ||\n col?.filterType === \"multiSelect\" ||\n (col?.filterType === \"select\" && (col?.filterOptions?.length ?? 0) > 0));\n const def = columnTypeRegistry.get(\n isTupleOperator\n ? (col?.filterType ?? \"text\")\n : useMulti\n ? \"multiSelect\"\n : (col?.filterType ?? \"text\"),\n );\n // currentValue:\n // - tuple (between): pega o value do primeiro item (já é tupla)\n // - multi: array agregado\n // - single: primeiro valor agregado\n const currentValue = isTupleOperator\n ? (items[0]?.value as unknown)\n : useMulti\n ? aggregateValues\n : aggregateValues[0];\n const options = getGroupOptions(group.key);\n // Controlled open: `isPendingOpen` vem do ToolbarApplied via\n // `pendingOpenId` prop — state mora no toolbar, DataTable só\n // controla quando setar via `setPendingOpenChipKey`.\n // Ao fechar, se o grupo só tem itens com valor vazio (caso do\n // shortcut que abriu mas user nao digitou nada), remove do filterModel.\n return (\n <Popover\n open={isPendingOpen || undefined}\n onOpenChange={(o) => {\n if (o) return;\n if (isPendingOpen) setPendingOpenChipKey(null);\n // Cleanup: remove itens vazios deste grupo do filterModel\n const groupItems = group.items;\n const allEmpty = groupItems.every((it) =>\n isFilterValueEmpty(it.value),\n );\n if (allEmpty) {\n const ids = new Set(groupItems.map((it) => it.id));\n filters.setFilterModel({\n ...filters.filterModel,\n items: filters.filterModel.items.filter((it) => !ids.has(it.id)),\n });\n }\n }}\n >\n <PopoverTrigger asChild>{defaultChip}</PopoverTrigger>\n <PopoverContent align=\"start\" className=\"p-0\">\n {def.renderFastFilterInput({\n value: currentValue as never,\n onChange: (v) => updateGroupValue(group.key, v),\n options,\n })}\n </PopoverContent>\n </Popover>\n );\n }}\n />\n </div>\n\n {/* Conteúdo */}\n {isLoading ? (\n props.renderLoading ?? <DataTableLoading />\n ) : isKanban ? (\n // Kanban gerencia seu próprio empty state interno (coluna sem cards).\n // Filter/search/sort/selection já estão aplicados via rowsAllPagesProcessed.\n <Kanban\n columns={kanbanView.columns}\n cards={kanbanView.cards}\n // Selection (bridge)\n selectedIds={kanbanSelectedIds}\n onToggleSelect={\n kanbanSelectedIds ? kanbanToggleSelect : undefined\n }\n // Detail panel (controlled) + click\n openCardId={props.kanbanConfig?.openCardId}\n onOpenCard={kanbanOnOpenCard}\n // Add card (botões \"+\" header + footer)\n onAddCard={props.kanbanConfig?.onAddCard}\n onAddInFooter={props.kanbanConfig?.onAddInFooter}\n hideFooterAdd={props.kanbanConfig?.hideFooterAdd}\n // Menus (auto via items OU manual via callback — items ganham se ambos definidos)\n getCardMenuItems={kanbanGetCardMenuItems}\n onCardMenu={\n kanbanGetCardMenuItems ? undefined : props.kanbanConfig?.onCardMenu\n }\n getColumnMenuItems={props.kanbanConfig?.getColumnMenuItems}\n onColumnMenu={\n props.kanbanConfig?.getColumnMenuItems\n ? undefined\n : props.kanbanConfig?.onColumnMenu\n }\n // Card content custom (override total do miolo)\n renderCard={kanbanRenderCardContent}\n // DnD\n enableDnD={props.kanbanConfig?.enableDnD}\n onCardMove={props.kanbanConfig?.onCardMove}\n // Textos\n emptyLabel={props.kanbanConfig?.emptyLabel}\n addLabel={props.kanbanConfig?.addLabel}\n />\n ) : isDataEmpty ? (\n props.renderEmpty ?? <DataTableEmpty />\n ) : isNoResults ? (\n props.renderNoResults ?? (\n <DataTableNoResults\n onClearFilters={() => {\n filters.setFilterModel({ items: [], logicOperator: \"AND\" });\n search.setInputValue(\"\");\n }}\n />\n )\n ) : isCardMode ? (\n cardBody\n ) : (\n tableBody\n )}\n\n {/* Footer (paginação) — só na view table.\n Durante loading mostra skeleton no lugar (mesma silhueta) pra\n evitar paginação \"1 página\" enquanto fetchData responde. */}\n {!isKanban && paginationConfig.enabled !== false && (\n isLoading ? (\n <div className={styles.footerWrap()}>\n <FooterTableSkeleton />\n </div>\n ) : !isDataEmpty && (\n <div className={styles.footerWrap()}>\n <FooterTable\n totalCount={totalAfterFilter}\n page={pagination.paginationModel.page}\n pageSize={pagination.paginationModel.pageSize}\n onPageChange={pagination.setPage}\n onPageSizeChange={pagination.setPageSize}\n pageSizeOptions={paginationConfig.pageSizeOptions}\n selectionCount={selection.selectedCount}\n />\n </div>\n )\n )}\n </div>\n </DataTableProvider>\n );\n}\n\ntype DataTableComponent = <T>(\n props: DataTableProps<T> & { ref?: Ref<DataTableRef> },\n) => React.ReactElement;\n\nexport const DataTable = forwardRef(DataTableInternal) as DataTableComponent;\n","import type { ReactNode } from \"react\";\nimport { X } from \"lucide-react\";\nimport { Button } from \"@/components/ui/Button/button\";\nimport { dataTableStyles } from \"../data-table.styles\";\n\nconst styles = dataTableStyles();\n\nexport type DataTableFloatingBulkBarProps = {\n count: number;\n onClear: () => void;\n /** Render custom de actions a direita do count. */\n actions?: ReactNode;\n};\n\n/**\n * @deprecated DataTable usa `TableToolbar.bulkBar` slot com `<BulkActionsBar>`\n * inline desde 2026-05-12. Este componente flutuante é mantido por\n * backward-compat pra consumers standalone. Avaliar remoção em V2.\n */\nexport function DataTableFloatingBulkBar({\n count,\n onClear,\n actions,\n}: DataTableFloatingBulkBarProps) {\n if (count === 0) return null;\n return (\n <div className={styles.bulkBar()} role=\"region\" aria-label=\"Acoes em massa\">\n <span className=\"text-label-sm whitespace-nowrap\">\n {count} selecionado{count > 1 ? \"s\" : \"\"}\n </span>\n {actions && <div className=\"flex items-center gap-gp-sm\">{actions}</div>}\n <Button\n size=\"icon-xs\"\n variant=\"ghost\"\n color=\"secondary\"\n aria-label=\"Limpar selecao\"\n onClick={onClear}\n >\n <X />\n </Button>\n </div>\n );\n}\n","import type {\n DataTablePresetView,\n DataTableViewMode,\n FilterItem,\n FilterModel,\n FilterOperator,\n FilterValue,\n GridRowId,\n SortModel,\n} from \"../data-table.types\";\nimport type { ColumnPinned, TableDensity } from \"../../Table\";\n\n/**\n * Filtro simplificado pra builder — `id` gerado automaticamente, `logicOperator`\n * default \"AND\". Consumer só fornece field/operator/value.\n */\nexport type PresetFilterInput = {\n field: string;\n operator?: FilterOperator;\n value?: FilterValue;\n};\n\nexport type PresetViewInput = {\n /** ID único e estável — sugerido prefixo `preset:` (ex: `\"preset:ativos\"`). */\n id: string;\n /** Label da view nos tabs e popovers. */\n name: string;\n /**\n * Filtros aplicados. Forma curta: `[{ field, operator?, value? }]`.\n * Operator default = `\"equals\"`. `id` é gerado automaticamente.\n */\n filters?: PresetFilterInput[];\n /** Combinação dos filtros — `\"AND\"` (default) ou `\"OR\"`. */\n filterLogic?: \"AND\" | \"OR\";\n /** Multi-sort: `[{ field, direction }]`. Default `[]`. */\n sort?: SortModel[];\n /** Density visual. Default `\"standard\"`. */\n density?: TableDensity;\n /** Colunas escondidas (default `[]`). */\n hiddenColumns?: string[];\n /** Pin por field — `{ \"field\": \"left\" | \"right\" }`. Default `{}`. */\n pinnedColumns?: Record<string, ColumnPinned>;\n /** Width override por field (px). Default `{}`. */\n columnWidths?: Record<string, number>;\n /** Ordem visual das colunas. Default = ordem original. */\n columnOrder?: string[];\n /** Modo de visualização — `\"table\"` (default) ou `\"kanban\"`. */\n viewMode?: DataTableViewMode;\n /** Field pelo qual agrupar (sem agrupamento se ausente). */\n groupBy?: string;\n /** Rows que iniciam expandidas. Default `[]`. */\n expandedRowIds?: GridRowId[];\n};\n\n/**\n * Builder pra declarar `DataTablePresetView` com defaults razoáveis e shape\n * mínimo. Elimina boilerplate de `filterModel.items[0].id`, `logicOperator`,\n * `sortModel: []`, etc.\n *\n * Exemplos:\n *\n * ```tsx\n * // Filtro simples\n * presetView({\n * id: \"preset:ativos\",\n * name: \"Ativos\",\n * filters: [{ field: \"statusId\", value: \"active\" }],\n * });\n *\n * // Kanban view agrupada\n * presetView({\n * id: \"preset:pipeline\",\n * name: \"Pipeline (Kanban)\",\n * viewMode: \"kanban\",\n * groupBy: \"statusId\",\n * });\n *\n * // Multi-filter + sort + layout customizado\n * presetView({\n * id: \"preset:high-value\",\n * name: \"Alto valor (decrescente)\",\n * filters: [\n * { field: \"value\", operator: \"gt\", value: 10000 },\n * { field: \"statusId\", value: \"active\" },\n * ],\n * sort: [{ field: \"value\", direction: \"desc\" }],\n * pinnedColumns: { name: \"left\" },\n * hiddenColumns: [\"lastContact\"],\n * });\n * ```\n */\nexport function presetView(input: PresetViewInput): DataTablePresetView {\n const {\n id,\n name,\n filters = [],\n filterLogic = \"AND\",\n sort = [],\n density = \"standard\",\n hiddenColumns,\n pinnedColumns,\n columnWidths,\n columnOrder,\n viewMode,\n groupBy,\n expandedRowIds,\n } = input;\n\n const filterItems: FilterItem[] = filters.map((f, idx) => ({\n id: `${id}-filter-${idx}`,\n field: f.field,\n operator: f.operator ?? \"equals\",\n value: f.value,\n }));\n\n const filterModel: FilterModel = {\n items: filterItems,\n logicOperator: filterLogic,\n };\n\n return {\n id,\n name,\n state: {\n filterModel,\n sortModel: sort,\n density,\n hiddenColumns,\n pinnedColumns,\n columnWidths,\n columnOrder,\n viewMode,\n groupBy,\n expandedRowIds,\n },\n };\n}\n","import { tv } from \"@/utils/tv\";\n\n/**\n * FloatingPanel — drawer \"card flutuante\" que convive com a interação\n * atrás (sem backdrop modal). Versão do `<Panel>` para casos non-modal:\n * detail panels, side info, configurações secundárias.\n *\n * Diferenças vs `<Panel>`:\n * - Sem Sheet/Dialog (sem foco trap, sem overlay scrim)\n * - Suporte a resize horizontal (drag handle no edge)\n * - Suporte a maximize (toggle pra ocupar quase a tela toda)\n * - Em max-md vira sheet bottom-up (responsive)\n */\nexport const floatingPanelStyles = tv({\n slots: {\n root: [\n \"fixed z-50 flex flex-col overflow-hidden\",\n \"bg-bg-surface dark:bg-bg-canvas text-fg-default\",\n \"rounded-radius-xl border border-border-default outline-float shadow-sh-2xl\",\n // Desktop (md+) — gutter top/bottom 24px\n \"md:top-pad-4xl md:bottom-pad-4xl\",\n // Mobile (max-md) — sheet bottom-up\n \"max-md:inset-x-pad-md max-md:bottom-pad-md max-md:top-auto max-md:!w-auto max-md:h-[85dvh]\",\n // Entrada animada\n \"ease-[cubic-bezier(0.4,0,0.2,1)] duration-[220ms]\",\n \"animate-in fade-in-0\",\n ],\n handle: [\n \"absolute top-0 bottom-0 w-[6px] cursor-col-resize z-10\",\n // Linha 1px que aparece sutil no hover do panel + linha brand 2px no hover direto\n \"after:content-[''] after:absolute after:top-[16px] after:bottom-[16px]\",\n \"after:left-1/2 after:-translate-x-1/2 after:w-px after:bg-border-default\",\n \"after:transition-all after:duration-150 after:opacity-60\",\n \"hover:after:bg-bg-brand hover:after:w-[2px] hover:after:top-0 hover:after:bottom-0 hover:after:opacity-100\",\n \"data-[dragging=true]:after:bg-bg-brand data-[dragging=true]:after:w-[2px]\",\n \"data-[dragging=true]:after:top-0 data-[dragging=true]:after:bottom-0 data-[dragging=true]:after:opacity-100\",\n // Hide em mobile (não-resizable) e quando maximized\n \"max-md:hidden\",\n ],\n header: [\n \"flex items-center gap-gp-md flex-none\",\n \"px-[18px] py-[14px] min-h-[60px]\",\n \"border-b border-border-default\",\n ],\n headerText: \"flex flex-col gap-gp-2xs min-w-0 flex-1\",\n headerTitle: [\n \"flex items-center gap-gp-md min-w-0\",\n \"text-[16px] font-bold tracking-[-0.01em] text-fg-default truncate\",\n ],\n headerTitleIcon: \"size-[18px] text-fg-brand shrink-0\",\n headerDescription: \"text-paragraph-sm text-fg-muted truncate\",\n headerActions: \"flex items-center gap-gp-xs flex-none\",\n body: [\n \"flex-1 overflow-y-auto scrollbar-thin\",\n ],\n footer: [\n \"flex items-center justify-end gap-gp-md flex-none\",\n \"px-[18px] py-[14px]\",\n \"border-t border-border-default\",\n ],\n },\n variants: {\n side: {\n right: {\n root: \"md:right-pad-4xl md:slide-in-from-right-12 max-md:slide-in-from-bottom-12\",\n handle: \"left-0\",\n },\n left: {\n root: \"md:left-pad-4xl md:slide-in-from-left-12 max-md:slide-in-from-bottom-12\",\n handle: \"right-0\",\n },\n },\n maximized: {\n true: {\n // Ocupa quase a tela inteira (16px gutter em todas as direções)\n // !important sobrescreve as positions do side e do mobile\n root: \"md:!inset-pad-md md:!w-auto\",\n handle: \"md:hidden\",\n },\n },\n },\n});\n\n/* ── Map de sizes pré-definidos (px) ──────────────────────────── */\nexport const FLOATING_PANEL_SIZE_PX: Record<\n \"sm\" | \"md\" | \"lg\" | \"xl\",\n number\n> = {\n sm: 320,\n md: 400,\n lg: 560,\n xl: 720,\n};\n","import { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport type UseFloatingPanelResizeOptions = {\n /** Largura inicial (em px) antes do localStorage hidratar. */\n initial: number;\n /** Largura mínima permitida (em px). */\n min: number;\n /** Largura máxima permitida (em px). */\n max: number;\n /** Lado em que o panel está ancorado — determina o sentido do delta. */\n side: \"left\" | \"right\";\n /** Chave no localStorage pra persistir (opcional). */\n storageKey?: string;\n /** Se false, o hook não atualiza width (modo \"maximizado\" ou disabled). */\n enabled?: boolean;\n};\n\nexport type UseFloatingPanelResizeResult = {\n width: number;\n /** Handler pra começar o drag — atribuir em `onMouseDown` do handle. */\n onResizeStart: (e: React.MouseEvent) => void;\n};\n\n/**\n * Hook de drag-resize horizontal pra panels flutuantes com persist opcional\n * em localStorage. Suporta painéis ancorados à direita OU à esquerda — o\n * sentido do delta é invertido automaticamente.\n *\n * side=\"right\" → handle no LEFT edge → arrastar pra esquerda AUMENTA width\n * side=\"left\" → handle no RIGHT edge → arrastar pra direita AUMENTA width\n *\n * Cleanup: listeners globais são removidos no mouseup + restaura cursor/userSelect.\n */\nexport function useFloatingPanelResize({\n initial,\n min,\n max,\n side,\n storageKey,\n enabled = true,\n}: UseFloatingPanelResizeOptions): UseFloatingPanelResizeResult {\n const [width, setWidth] = useState<number>(initial);\n const hydrated = useRef(false);\n\n // Hidrata do localStorage no mount (se storageKey)\n useEffect(() => {\n if (!storageKey || typeof window === \"undefined\") {\n hydrated.current = true;\n return;\n }\n try {\n const raw = window.localStorage.getItem(storageKey);\n const n = raw ? Number(raw) : NaN;\n if (!Number.isNaN(n) && n >= min && n <= max) setWidth(n);\n } catch {\n /* ignore */\n }\n hydrated.current = true;\n }, [min, max, storageKey]);\n\n // Salva quando muda (após hidratação)\n useEffect(() => {\n if (!hydrated.current || !storageKey || typeof window === \"undefined\") return;\n try {\n window.localStorage.setItem(storageKey, String(width));\n } catch {\n /* ignore */\n }\n }, [width, storageKey]);\n\n const onResizeStart = useCallback(\n (e: React.MouseEvent) => {\n if (!enabled) return;\n e.preventDefault();\n const startX = e.clientX;\n const startWidth = width;\n\n const onMove = (ev: MouseEvent) => {\n // side=right (handle left edge): delta < 0 (cursor pra esquerda) AUMENTA width\n // side=left (handle right edge): delta > 0 (cursor pra direita) AUMENTA width\n const delta = side === \"right\" ? startX - ev.clientX : ev.clientX - startX;\n const next = Math.max(min, Math.min(max, startWidth + delta));\n setWidth(next);\n };\n const onUp = () => {\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"\";\n document.body.style.userSelect = \"\";\n };\n document.addEventListener(\"mousemove\", onMove);\n document.addEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"col-resize\";\n document.body.style.userSelect = \"none\";\n },\n [width, min, max, side, enabled],\n );\n\n return { width, onResizeStart };\n}\n","import { useEffect, useId, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { Maximize2, Minimize2, X } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"../Button/button\";\nimport { floatingPanelStyles, FLOATING_PANEL_SIZE_PX } from \"./floating-panel.styles\";\nimport { useFloatingPanelResize } from \"./use-floating-panel-resize\";\nimport type { FloatingPanelProps, FloatingPanelSize } from \"./floating-panel.types\";\n\nfunction resolveInitialWidth(size: FloatingPanelProps[\"size\"]): number {\n if (typeof size === \"number\") return size;\n if (size && size in FLOATING_PANEL_SIZE_PX) {\n return FLOATING_PANEL_SIZE_PX[size as FloatingPanelSize];\n }\n return FLOATING_PANEL_SIZE_PX.md;\n}\n\n/**\n * FloatingPanel — drawer \"card flutuante\" non-modal.\n *\n * Diferente do `<Panel>`, NÃO renderiza backdrop nem trap de foco — a página\n * atrás continua interativa. Útil pra detail panels, side info, configurações\n * secundárias que precisam coexistir com a tela principal.\n *\n * Features:\n * - Resize horizontal (drag handle no edge) com persistência opcional\n * - Maximize toggle (botão no header) — ocupa quase a tela toda\n * - Responsive: vira sheet bottom-up em max-md\n * - ESC fecha (configurável)\n * - Renderizado via portal em document.body (escapa de overflow/transform de ancestrais)\n *\n * Exemplo:\n * ```tsx\n * <FloatingPanel\n * open={open}\n * onOpenChange={setOpen}\n * title=\"Detalhes do cliente\"\n * description=\"ID: CLI-2401\"\n * resizable\n * maximizable\n * headerActions={\n * <>\n * <Button variant=\"soft\" color=\"secondary\" size=\"icon-sm\"><Pencil /></Button>\n * <Button variant=\"soft\" color=\"critical\" size=\"icon-sm\"><Trash2 /></Button>\n * </>\n * }\n * footer={\n * <>\n * <Button variant=\"outline\" color=\"secondary\" onClick={() => setOpen(false)}>Cancelar</Button>\n * <Button variant=\"filled\" color=\"primary\">Salvar</Button>\n * </>\n * }\n * >\n * <DetailContent />\n * </FloatingPanel>\n * ```\n */\nexport function FloatingPanel({\n open,\n onOpenChange,\n side = \"right\",\n size = \"md\",\n title,\n description,\n titleIcon: TitleIcon,\n titleSlot,\n headerActions,\n hideClose,\n footer,\n children,\n resizable = false,\n resizableMinWidth = 320,\n resizableMaxWidth = 800,\n resizableStorageKey,\n maximizable = false,\n defaultMaximized = false,\n closeOnEscape = true,\n className,\n}: FloatingPanelProps) {\n const initialWidth = resolveInitialWidth(size);\n const [maximized, setMaximized] = useState<boolean>(defaultMaximized);\n const [dragging, setDragging] = useState<boolean>(false);\n const titleId = useId();\n const descId = useId();\n const handleRef = useRef<HTMLButtonElement>(null);\n\n const resize = useFloatingPanelResize({\n initial: initialWidth,\n min: resizableMinWidth,\n max: resizableMaxWidth,\n side,\n storageKey: resizableStorageKey,\n enabled: resizable && !maximized,\n });\n\n // ESC fecha (configurável)\n useEffect(() => {\n if (!open || !closeOnEscape) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onOpenChange(false);\n };\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [open, closeOnEscape, onOpenChange]);\n\n // Capture dragging state pro data-dragging do handle (cor brand persiste)\n useEffect(() => {\n if (!dragging) return;\n const onUp = () => setDragging(false);\n document.addEventListener(\"mouseup\", onUp);\n return () => document.removeEventListener(\"mouseup\", onUp);\n }, [dragging]);\n\n // SSR safety + render condicional\n if (typeof window === \"undefined\" || !open) return null;\n\n const s = floatingPanelStyles({ side, maximized });\n\n // Width final aplicado no style (ignora em mobile via CSS max-md:!w-auto)\n const widthValue = resizable ? resize.width : initialWidth;\n\n return createPortal(\n <aside\n role=\"dialog\"\n aria-modal=\"false\"\n aria-labelledby={title ? titleId : undefined}\n aria-describedby={description ? descId : undefined}\n style={maximized ? undefined : { width: widthValue }}\n className={cn(s.root(), className)}\n >\n {/* Resize handle — só quando resizable e !maximized */}\n {resizable && !maximized && (\n <button\n ref={handleRef}\n type=\"button\"\n aria-label=\"Redimensionar panel\"\n data-dragging={dragging || undefined}\n onMouseDown={(e) => {\n setDragging(true);\n resize.onResizeStart(e);\n }}\n className={s.handle()}\n />\n )}\n\n {/* Header — title / description / actions */}\n {(title || description || titleSlot || headerActions || !hideClose || maximizable) && (\n <header className={s.header()}>\n {titleSlot ? (\n <div className=\"flex-1 min-w-0\">{titleSlot}</div>\n ) : (\n <div className={s.headerText()}>\n {title && (\n <h2 id={titleId} className={s.headerTitle()}>\n {TitleIcon && <TitleIcon className={s.headerTitleIcon()} strokeWidth={1.8} />}\n <span className=\"truncate\">{title}</span>\n </h2>\n )}\n {description && (\n <p id={descId} className={s.headerDescription()}>\n {description}\n </p>\n )}\n </div>\n )}\n\n <div className={s.headerActions()}>\n {headerActions}\n {maximizable && (\n <Button\n type=\"button\"\n variant=\"soft\"\n color=\"secondary\"\n size=\"icon-sm\"\n aria-label={maximized ? \"Restaurar tamanho\" : \"Maximizar\"}\n onClick={() => setMaximized((m) => !m)}\n className=\"max-md:hidden\"\n >\n {maximized ? <Minimize2 /> : <Maximize2 />}\n </Button>\n )}\n {!hideClose && (\n <Button\n type=\"button\"\n variant=\"soft\"\n color=\"secondary\"\n size=\"icon-sm\"\n aria-label=\"Fechar\"\n onClick={() => onOpenChange(false)}\n >\n <X />\n </Button>\n )}\n </div>\n </header>\n )}\n\n {/* Body */}\n <div className={s.body()}>{children}</div>\n\n {/* Footer */}\n {footer && <footer className={s.footer()}>{footer}</footer>}\n </aside>,\n document.body,\n );\n}\n","import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\n/**\n * Textarea — alinhado com `.tbl-form-textarea` do design-and-table-v2.\n *\n * Specs:\n * - min-h: 100px, padding: 10px 12px, radius: 10px\n * - bg-input (light) / dark:bg-bg-muted, border-input 1px\n * - font: 13px, line-height: 1.5, resize vertical\n * - focus: border-brand + shadow-sh-ring\n *\n * Features: state prop (default | error | warning | success) pra feedback visual.\n */\n\nexport type TextareaState = \"default\" | \"error\" | \"warning\" | \"success\";\n\nconst textareaVariants = cva(\n [\n \"flex min-h-[100px] w-full resize-y\",\n \"bg-bg-input dark:bg-bg-muted\",\n \"hover:bg-bg-input-hover dark:hover:bg-bg-muted-hover\",\n \"border border-border-input rounded-radius-lg\",\n \"px-pad-xl py-pad-lg\",\n \"text-[13px] leading-[1.5] text-fg-default\",\n \"placeholder:text-fg-muted placeholder:opacity-70\",\n \"transition-[color,box-shadow,background-color,border-color] outline-none\",\n \"disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-bg-input dark:disabled:hover:bg-bg-muted\",\n ],\n {\n variants: {\n state: {\n default: \"focus-visible:border-border-brand focus-visible:shadow-sh-ring\",\n error: \"border-border-danger-muted focus-visible:border-border-danger-muted focus-visible:shadow-sh-ring-danger\",\n warning: \"border-border-warning-muted focus-visible:border-border-warning-muted focus-visible:shadow-sh-ring-warning\",\n success: \"border-border-success-muted focus-visible:border-border-success-muted focus-visible:shadow-sh-ring-success\",\n },\n },\n defaultVariants: {\n state: \"default\",\n },\n }\n);\n\nexport interface TextareaProps\n extends React.ComponentProps<\"textarea\">,\n VariantProps<typeof textareaVariants> {}\n\nconst Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ className, state, ...props }, ref) => {\n return (\n <textarea\n className={cn(textareaVariants({ state }), className)}\n ref={ref}\n {...props}\n />\n )\n }\n)\nTextarea.displayName = \"Textarea\"\n\nexport { Textarea, textareaVariants }\n","import { forwardRef } from \"react\";\nimport { Textarea, type TextareaProps } from \"../../shadcn/textarea\";\nimport { FormField } from \"./form-field\";\nimport type { FormFieldBaseProps } from \"./form-field.types\";\n\n/**\n * FormFieldTextarea — wrapper \"one-shot\" pra um campo multilinha.\n * Compõe FormField + Textarea (mesmo componente do shadcn/), sem reimplementação.\n */\nexport type FormFieldTextareaProps = FormFieldBaseProps &\n Omit<TextareaProps, \"state\" | \"id\">;\n\nexport const FormFieldTextarea = forwardRef<\n HTMLTextAreaElement,\n FormFieldTextareaProps\n>(\n (\n {\n label,\n required,\n helperText,\n state,\n errorMessage,\n warningMessage,\n successMessage,\n className,\n id,\n ...textareaProps\n },\n ref,\n ) => (\n <FormField\n label={label}\n required={required}\n helperText={helperText}\n state={state}\n errorMessage={errorMessage}\n warningMessage={warningMessage}\n successMessage={successMessage}\n className={className}\n id={id}\n disabled={textareaProps.disabled}\n >\n {({ id: fieldId, state: fieldState }) => (\n <Textarea\n ref={ref}\n id={fieldId}\n state={fieldState}\n {...textareaProps}\n />\n )}\n </FormField>\n ),\n);\nFormFieldTextarea.displayName = \"FormFieldTextarea\";\n","import type { ReactNode } from \"react\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n type SelectTriggerState,\n} from \"../../shadcn/select\";\nimport { FormField } from \"./form-field\";\nimport type { FormFieldBaseProps } from \"./form-field.types\";\n\nexport type FormFieldSelectOption = {\n value: string;\n label: ReactNode;\n disabled?: boolean;\n};\n\n/**\n * FormFieldSelect — wrapper \"one-shot\" pra um select dropdown.\n *\n * Compõe FormField + Select (radix) — reutiliza os Select* primitives existentes.\n *\n * Uso simples via `options`:\n * <FormFieldSelect label=\"País\" placeholder=\"Selecione...\" options={[\n * { value: \"br\", label: \"Brasil\" },\n * { value: \"us\", label: \"Estados Unidos\" },\n * ]} />\n *\n * Pra casos avançados (groups, separators), use o Select primitive direto.\n */\nexport type FormFieldSelectProps = FormFieldBaseProps & {\n options: FormFieldSelectOption[];\n placeholder?: string;\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n disabled?: boolean;\n /** className aplicado ao <SelectTrigger>. Pra estilizar o wrapper, use `className` (vai pro FormField root). */\n triggerClassName?: string;\n /** Largura/maxHeight customizada do dropdown */\n contentClassName?: string;\n};\n\nexport function FormFieldSelect({\n label,\n required,\n helperText,\n state,\n errorMessage,\n warningMessage,\n successMessage,\n className,\n id,\n options,\n placeholder,\n value,\n defaultValue,\n onValueChange,\n disabled,\n triggerClassName,\n contentClassName,\n}: FormFieldSelectProps) {\n return (\n <FormField\n label={label}\n required={required}\n helperText={helperText}\n state={state}\n errorMessage={errorMessage}\n warningMessage={warningMessage}\n successMessage={successMessage}\n className={className}\n id={id}\n disabled={disabled}\n >\n {({ id: fieldId, state: fieldState }) => (\n <Select\n value={value}\n defaultValue={defaultValue}\n onValueChange={onValueChange}\n disabled={disabled}\n >\n <SelectTrigger\n id={fieldId}\n state={fieldState as SelectTriggerState}\n className={triggerClassName}\n >\n <SelectValue placeholder={placeholder} />\n </SelectTrigger>\n <SelectContent className={contentClassName}>\n {options.map((opt) => (\n <SelectItem\n key={opt.value}\n value={opt.value}\n disabled={opt.disabled}\n >\n {opt.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n </FormField>\n );\n}\n","import { forwardRef, useId, type ReactNode } from \"react\";\nimport type { ComponentPropsWithoutRef, ElementRef } from \"react\";\nimport * as CheckboxPrimitive from \"@radix-ui/react-checkbox\";\nimport { Checkbox } from \"../../shadcn/checkbox\";\nimport { cn } from \"@/lib/utils\";\nimport {\n formFieldRoot,\n formFieldLabel,\n formFieldRequired,\n formFieldMessage,\n} from \"./form-field.styles\";\nimport type { FormFieldBaseProps, FieldState } from \"./form-field.types\";\n\n/**\n * FormFieldCheckbox — wrapper \"one-shot\" pra checkbox com label inline.\n *\n * Layout (diferente de FormFieldInput/Select):\n * ┌──────────────────────────────────────┐\n * │ [☑] Label texto │\n * │ Helper / error message │\n * └──────────────────────────────────────┘\n *\n * Reaproveita o Checkbox do shadcn. O label fica à direita (não em cima).\n */\nexport type FormFieldCheckboxProps = Omit<FormFieldBaseProps, \"label\"> & {\n /** Texto do label (inline à direita do checkbox) */\n label?: ReactNode;\n /** Props nativas do Radix Checkbox.Root */\n} & Omit<\n ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>,\n \"id\" | \"className\"\n >;\n\nexport const FormFieldCheckbox = forwardRef<\n ElementRef<typeof CheckboxPrimitive.Root>,\n FormFieldCheckboxProps\n>(\n (\n {\n label,\n required,\n helperText,\n state = \"default\",\n errorMessage,\n warningMessage,\n successMessage,\n className,\n id: idProp,\n disabled,\n ...checkboxProps\n },\n ref,\n ) => {\n const autoId = useId();\n const id = idProp ?? autoId;\n\n let message: ReactNode = helperText;\n let messageState: FieldState = \"default\";\n if (state === \"error\" && errorMessage) {\n message = errorMessage;\n messageState = \"error\";\n } else if (state === \"warning\" && warningMessage) {\n message = warningMessage;\n messageState = \"warning\";\n } else if (state === \"success\" && successMessage) {\n message = successMessage;\n messageState = \"success\";\n }\n\n return (\n <div className={cn(formFieldRoot(), \"gap-[5px]\", className)}>\n <div className=\"flex items-center gap-gp-md\">\n <Checkbox\n ref={ref}\n id={id}\n disabled={disabled}\n {...checkboxProps}\n />\n {label && (\n <label\n htmlFor={id}\n className={cn(formFieldLabel({ disabled }), \"cursor-pointer\")}\n >\n {label}\n {required && (\n <span className={formFieldRequired()} aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n </div>\n {message && (\n <p\n className={cn(formFieldMessage({ state: messageState }), \"pl-[26px]\")}\n role={messageState === \"error\" ? \"alert\" : undefined}\n >\n {message}\n </p>\n )}\n </div>\n );\n },\n);\nFormFieldCheckbox.displayName = \"FormFieldCheckbox\";\n","import { forwardRef, useId, type ReactNode } from \"react\";\nimport type { ComponentPropsWithoutRef, ElementRef } from \"react\";\nimport * as SwitchPrimitive from \"@radix-ui/react-switch\";\nimport { Switch } from \"../../shadcn/switch\";\nimport { cn } from \"@/lib/utils\";\nimport {\n formFieldRoot,\n formFieldLabel,\n formFieldRequired,\n formFieldMessage,\n} from \"./form-field.styles\";\nimport type { FormFieldBaseProps, FieldState } from \"./form-field.types\";\n\n/**\n * FormFieldSwitch — wrapper \"one-shot\" pra toggle switch com label inline.\n *\n * Layout: label à ESQUERDA, switch à DIREITA (padrão de toggle):\n * ┌──────────────────────────────────────┐\n * │ Label texto [○──] │\n * │ Helper / error message │\n * └──────────────────────────────────────┘\n *\n * Reaproveita o Switch do shadcn.\n */\nexport type FormFieldSwitchProps = Omit<FormFieldBaseProps, \"label\"> & {\n label?: ReactNode;\n /** Posição do switch — default \"end\" (direita). \"start\" coloca à esquerda do label. */\n switchPosition?: \"start\" | \"end\";\n} & Omit<\n ComponentPropsWithoutRef<typeof SwitchPrimitive.Root>,\n \"id\" | \"className\"\n >;\n\nexport const FormFieldSwitch = forwardRef<\n ElementRef<typeof SwitchPrimitive.Root>,\n FormFieldSwitchProps\n>(\n (\n {\n label,\n required,\n helperText,\n state = \"default\",\n errorMessage,\n warningMessage,\n successMessage,\n className,\n id: idProp,\n disabled,\n switchPosition = \"end\",\n ...switchProps\n },\n ref,\n ) => {\n const autoId = useId();\n const id = idProp ?? autoId;\n\n let message: ReactNode = helperText;\n let messageState: FieldState = \"default\";\n if (state === \"error\" && errorMessage) {\n message = errorMessage;\n messageState = \"error\";\n } else if (state === \"warning\" && warningMessage) {\n message = warningMessage;\n messageState = \"warning\";\n } else if (state === \"success\" && successMessage) {\n message = successMessage;\n messageState = \"success\";\n }\n\n const switchEl = (\n <Switch ref={ref} id={id} disabled={disabled} {...switchProps} />\n );\n const labelEl = label && (\n <label\n htmlFor={id}\n className={cn(formFieldLabel({ disabled }), \"cursor-pointer flex-1\")}\n >\n {label}\n {required && (\n <span className={formFieldRequired()} aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n\n return (\n <div className={cn(formFieldRoot(), \"gap-[5px]\", className)}>\n <div className=\"flex items-center gap-gp-md\">\n {switchPosition === \"start\" ? (\n <>\n {switchEl}\n {labelEl}\n </>\n ) : (\n <>\n {labelEl}\n {switchEl}\n </>\n )}\n </div>\n {message && (\n <p\n className={formFieldMessage({ state: messageState })}\n role={messageState === \"error\" ? \"alert\" : undefined}\n >\n {message}\n </p>\n )}\n </div>\n );\n },\n);\nFormFieldSwitch.displayName = \"FormFieldSwitch\";\n","import * as React from \"react\"\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { X } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Sheet = SheetPrimitive.Root\n\nconst SheetTrigger = SheetPrimitive.Trigger\n\nconst SheetClose = SheetPrimitive.Close\n\nconst SheetPortal = SheetPrimitive.Portal\n\nconst SheetOverlay = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Overlay\n className={cn(\n \"fixed inset-0 z-50 bg-overlay-scrim data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className\n )}\n {...props}\n ref={ref}\n />\n))\nSheetOverlay.displayName = SheetPrimitive.Overlay.displayName\n\nconst sheetVariants = cva(\n \"fixed z-50 bg-bg-surface dark:bg-bg-canvas text-fg-default shadow-sh-2xl ease-[cubic-bezier(0.4,0,0.2,1)] data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-[220ms] data-[state=open]:duration-[220ms] data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0\",\n {\n variants: {\n side: {\n top: \"inset-x-0 top-0 border-b border-border-default data-[state=closed]:slide-out-to-top-12 data-[state=open]:slide-in-from-top-12\",\n bottom:\n \"inset-x-0 bottom-0 border-t border-border-default data-[state=closed]:slide-out-to-bottom-12 data-[state=open]:slide-in-from-bottom-12\",\n left: \"inset-y-0 left-0 h-full w-3/4 border-r border-border-default data-[state=closed]:slide-out-to-left-12 data-[state=open]:slide-in-from-left-12 sm:max-w-sm\",\n right:\n \"inset-y-0 right-0 h-full w-3/4 border-l border-border-default data-[state=closed]:slide-out-to-right-12 data-[state=open]:slide-in-from-right-12 sm:max-w-sm\",\n },\n },\n defaultVariants: {\n side: \"right\",\n },\n }\n)\n\ninterface SheetContentProps\n extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,\n VariantProps<typeof sheetVariants> {\n /** Esconde o botão \"X\" (Close) no canto superior direito. Default: false. */\n hideClose?: boolean\n}\n\nconst SheetContent = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Content>,\n SheetContentProps\n>(({ side = \"right\", className, children, hideClose, ...props }, ref) => (\n <SheetPortal>\n <SheetOverlay />\n <SheetPrimitive.Content\n ref={ref}\n className={cn(sheetVariants({ side }), className)}\n {...props}\n >\n {children}\n {!hideClose && (\n <SheetPrimitive.Close className=\"absolute right-pad-2xl top-pad-2xl rounded-radius-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus-visible:ring-4 focus-visible:ring-ring-secondary disabled:pointer-events-none data-[state=open]:bg-bg-muted text-fg-muted\">\n <X className=\"h-4 w-4\" />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n )}\n </SheetPrimitive.Content>\n </SheetPortal>\n))\nSheetContent.displayName = SheetPrimitive.Content.displayName\n\nconst SheetHeader = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col gap-gp-sm text-left\",\n className\n )}\n {...props}\n />\n)\nSheetHeader.displayName = \"SheetHeader\"\n\nconst SheetFooter = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col-reverse gap-gp-md sm:flex-row sm:justify-end\",\n className\n )}\n {...props}\n />\n)\nSheetFooter.displayName = \"SheetFooter\"\n\nconst SheetTitle = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Title\n ref={ref}\n className={cn(\"text-label-md font-semibold text-fg-default\", className)}\n {...props}\n />\n))\nSheetTitle.displayName = SheetPrimitive.Title.displayName\n\nconst SheetDescription = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Description\n ref={ref}\n className={cn(\"text-paragraph-sm text-fg-muted\", className)}\n {...props}\n />\n))\nSheetDescription.displayName = SheetPrimitive.Description.displayName\n\nexport {\n Sheet,\n SheetPortal,\n SheetOverlay,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n}\n","import { tv } from \"@/utils/tv\";\n\n/**\n * Panel styles — alinhado com `.tbl-form-drawer` do design-and-table-v2.\n *\n * Spec sandbox:\n * - position: fixed top/right/bottom 24px (gutter)\n * - width: 560px (default), max-width: calc(100vw - 48px)\n * - bg-bg-surface (light) / bg-bg-canvas (dark)\n * - border 1px + radius 14px (= radius-xl)\n * - shadow-sh-2xl + halo outline (6px alpha)\n * - flex column, overflow-hidden\n * - Mobile: ocupa quase tudo (gutter reduzido)\n */\n\n/* ── Container (override do SheetContent) ─────────────────────────────────── */\n/**\n * Container \"card flutuante\" estilo iGreen — fica destacado do viewport com\n * gutter de 24px, radius e halo. Responsivo: gutter encolhe no mobile.\n */\nexport const panelContainer = tv({\n base: [\n \"flex flex-col overflow-hidden\",\n \"rounded-radius-xl border border-border-default\",\n // Outline padrão de elementos flutuantes\n \"outline-float\",\n // Altura/largura responde ao side via inset:\n // right/left → inset-y define height, sizeClass define width\n // top/bottom → inset-x define width, height auto\n ],\n variants: {\n side: {\n right: [\n \"inset-y-pad-4xl right-pad-4xl\",\n \"max-md:inset-y-pad-md max-md:right-pad-md max-md:left-pad-md\",\n ],\n left: [\n \"inset-y-pad-4xl left-pad-4xl\",\n \"max-md:inset-y-pad-md max-md:left-pad-md max-md:right-pad-md\",\n ],\n top: [\n \"inset-x-pad-4xl top-pad-4xl\",\n \"max-md:inset-x-pad-md max-md:top-pad-md max-md:bottom-pad-md\",\n ],\n bottom: [\n \"inset-x-pad-4xl bottom-pad-4xl\",\n \"max-md:inset-x-pad-md max-md:bottom-pad-md max-md:top-pad-md\",\n ],\n },\n },\n});\n\n/* ── Header (.tbl-form-drawer-head) ───────────────────────────────────────── */\nexport const panelHeader = tv({\n base: [\n \"flex items-center justify-between gap-gp-xl flex-none\",\n \"px-[20px] py-[18px]\",\n \"border-b border-border-default\",\n ],\n});\n\nexport const panelHeaderText = tv({\n base: \"flex flex-col gap-gp-2xs min-w-0\",\n});\n\nexport const panelTitle = tv({\n base: [\n \"flex items-center gap-gp-md min-w-0\",\n \"text-[16px] font-bold text-fg-default tracking-[-0.01em]\",\n \"truncate\",\n ],\n});\n\nexport const panelTitleIcon = tv({\n base: \"size-[18px] text-fg-brand shrink-0\",\n});\n\nexport const panelDescription = tv({\n base: \"text-paragraph-sm text-fg-muted\",\n});\n\nexport const panelClose = tv({\n base: [\n \"grid place-items-center shrink-0\",\n \"w-form-sm h-form-sm rounded-radius-md\",\n \"bg-transparent border-0 cursor-pointer\",\n \"text-fg-muted opacity-60\",\n \"transition-[background-color,color,opacity] duration-150\",\n \"hover:bg-bg-muted hover:text-fg-default hover:opacity-100\",\n \"focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-ring-secondary focus-visible:opacity-100\",\n \"dark:hover:bg-bg-muted-hover\",\n ],\n});\n\n/* ── Body (.tbl-form-drawer-body) ─────────────────────────────────────────── */\nexport const panelBody = tv({\n base: [\n \"flex-1 overflow-y-auto\",\n \"flex flex-col gap-gp-3xl\", // 20px gap entre form sections\n \"py-pad-4xl px-pad-3xl\", // 24px vertical / 20px horizontal\n \"scrollbar-thin\",\n ],\n});\n\n/* ── Footer (.tbl-form-drawer-foot) ───────────────────────────────────────── */\nexport const panelFooter = tv({\n base: [\n \"flex items-center justify-end gap-gp-lg flex-none\",\n \"px-[20px] py-[14px]\",\n \"border-t border-border-default\",\n ],\n});\n","import { X } from \"lucide-react\";\nimport { SheetClose, SheetTitle, SheetDescription } from \"../../shadcn/sheet\";\nimport { cn } from \"@/lib/utils\";\nimport {\n panelHeader,\n panelHeaderText,\n panelTitle,\n panelTitleIcon,\n panelDescription,\n panelClose,\n} from \"./panel.styles\";\nimport type { LucideIcon } from \"lucide-react\";\n\nexport type PanelHeaderProps = {\n title?: string;\n description?: string;\n titleIcon?: LucideIcon;\n /** Esconde o botão X de fechar */\n hideClose?: boolean;\n /** className do container do header */\n className?: string;\n};\n\nexport function PanelHeader({\n title,\n description,\n titleIcon: TitleIcon,\n hideClose,\n className,\n}: PanelHeaderProps) {\n return (\n <header className={cn(panelHeader(), className)}>\n <div className={panelHeaderText()}>\n {title && (\n <SheetTitle asChild>\n <h2 className={panelTitle()}>\n {TitleIcon && <TitleIcon className={panelTitleIcon()} strokeWidth={1.8} />}\n <span className=\"truncate\">{title}</span>\n </h2>\n </SheetTitle>\n )}\n {description && (\n <SheetDescription asChild>\n <p className={panelDescription()}>{description}</p>\n </SheetDescription>\n )}\n </div>\n {!hideClose && (\n <SheetClose className={panelClose()} aria-label=\"Fechar\">\n <X size={18} strokeWidth={1.7} />\n </SheetClose>\n )}\n </header>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { panelBody } from \"./panel.styles\";\n\nexport type PanelBodyProps = {\n children: ReactNode;\n className?: string;\n};\n\n/**\n * Container do body do panel — scroll interno, gap padrão entre seções.\n */\nexport function PanelBody({ children, className }: PanelBodyProps) {\n return <div className={cn(panelBody(), className)}>{children}</div>;\n}\n","import type { ReactNode } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { panelFooter } from \"./panel.styles\";\n\nexport type PanelFooterProps = {\n children: ReactNode;\n className?: string;\n};\n\n/**\n * Footer do panel — geralmente botões de ação alinhados à direita\n * (Cancelar / Salvar). Padding e border-top já aplicados.\n */\nexport function PanelFooter({ children, className }: PanelFooterProps) {\n return <footer className={cn(panelFooter(), className)}>{children}</footer>;\n}\n","import * as SheetPrimitive from \"@radix-ui/react-dialog\";\nimport { cn } from \"@/lib/utils\";\nimport {\n Sheet,\n SheetTrigger,\n SheetOverlay,\n} from \"../../shadcn/sheet\";\nimport { panelContainer } from \"./panel.styles\";\nimport { PanelHeader } from \"./panel-header\";\nimport { PanelBody } from \"./panel-body\";\nimport { PanelFooter } from \"./panel-footer\";\nimport type { PanelProps, PanelSide, PanelSize } from \"./panel.types\";\n\n/**\n * Width pré-definida por size. `full` ocupa o viewport menos o gutter (24px each side).\n * Aceita também string CSS arbitrária (ex: \"720px\", \"60vw\").\n */\nconst SIZE_MAP: Record<PanelSize, string> = {\n sm: \"w-[320px]\",\n md: \"w-[560px]\",\n lg: \"w-[720px]\",\n xl: \"w-[920px]\",\n full: \"w-[calc(100vw-48px)] max-md:w-[calc(100vw-16px)]\",\n};\n\nfunction resolveSize(size?: PanelSize | string): string {\n if (!size) return SIZE_MAP.md;\n if (size in SIZE_MAP) return SIZE_MAP[size as PanelSize];\n return `w-[${size}]`;\n}\n\n/**\n * Slide-in animations por side. Distância 12 (= 48px ≈ 8% do panel md 560px) +\n * duration 220ms + easing custom (matching .tbl-form-drawer do sandbox).\n */\nfunction slideAnimation(side: PanelSide): string {\n const anim = {\n right: \"data-[state=closed]:slide-out-to-right-12 data-[state=open]:slide-in-from-right-12\",\n left: \"data-[state=closed]:slide-out-to-left-12 data-[state=open]:slide-in-from-left-12\",\n top: \"data-[state=closed]:slide-out-to-top-12 data-[state=open]:slide-in-from-top-12\",\n bottom: \"data-[state=closed]:slide-out-to-bottom-12 data-[state=open]:slide-in-from-bottom-12\",\n }[side];\n return cn(\n \"ease-[cubic-bezier(0.4,0,0.2,1)]\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n \"data-[state=closed]:duration-[220ms] data-[state=open]:duration-[220ms]\",\n \"data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0\",\n anim\n );\n}\n\n/**\n * Panel — drawer \"card flutuante\" estilo iGreen.\n *\n * Alinhado com `.tbl-form-drawer` do design-and-table-v2:\n * - Slide-in lateral (default: right) com gutter de 24px do viewport\n * - Radius 14px + halo outline + shadow-2xl\n * - Header (title + close X) + Body scrollável + Footer (actions)\n * - Mobile-adapt: gutter reduzido, full-width responsivo\n *\n * Construído direto sobre SheetPrimitive.Content pra controle total do\n * positioning (evita conflito com inset-y-0/right-0/h-full do SheetContent).\n */\nexport function Panel({\n open,\n defaultOpen,\n onOpenChange,\n trigger,\n side = \"right\",\n size = \"md\",\n title,\n description,\n titleIcon,\n hideClose,\n footer,\n children,\n className,\n}: PanelProps) {\n const sizeClass = resolveSize(size);\n\n return (\n <Sheet open={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>\n {trigger && <SheetTrigger asChild>{trigger}</SheetTrigger>}\n <SheetPrimitive.Portal>\n <SheetOverlay />\n <SheetPrimitive.Content\n className={cn(\n \"fixed z-50 bg-bg-surface dark:bg-bg-canvas text-fg-default shadow-sh-2xl\",\n sizeClass,\n panelContainer({ side }),\n slideAnimation(side),\n className\n )}\n >\n <PanelHeader\n title={title}\n description={description}\n titleIcon={titleIcon}\n hideClose={hideClose}\n />\n <PanelBody>{children}</PanelBody>\n {footer && <PanelFooter>{footer}</PanelFooter>}\n </SheetPrimitive.Content>\n </SheetPrimitive.Portal>\n </Sheet>\n );\n}\n"],"names":["title","Avatar","generateId","s.board","s.root","s.card","column","s.column","s.columnDropInvalidDimmed","s.columnDropInvalidOver","s.columnDropTarget","s.columnHead","s.columnDot","s.columnTitle","s.columnCount","s.columnActionsSpacer","s.columnBody","s.columnEmpty","s.columnEmptyIcon","card","Fragment","s.columnAdd","s.dropPlaceholder","s.cardDragging","s.cardCheck","s.cardHead","s.cardTitleWrap","s.cardTitle","s.cardSubtitle","s.cardDesc","s.cardMeta","s.cardValue","s.cardFoot","s.cardMenuSlot","toDateMs","dayStart","toDate","toIsoDate","ptBrShort","formatShort","CalendarIcon","toNumber","normalize","LinkIcon","initials","color","VALID_COLORS","resolveChipColor","findOption","toArray","columnTypeRegistry","toggleRow","getFieldValue","STORAGE_PREFIX","storageKey","_","XIcon","value","styles","TableIcon","isFilterValueEmpty","FilterIcon","MoreMenuItemEl"],"mappings":"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"}
|