@upbound/monarch-blocks 0.4.1 → 0.6.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/data-table/cell-contextual-filter.tsx","../src/data-table/column-options.tsx","../src/lib/utils.ts","../src/lib/data-table/utils.ts","../src/data-table/columns.tsx","../src/relative-time.tsx","../src/hooks/use-mounted.ts","../src/data-table/data-table.tsx","../src/cel-filter-bar/cel-filter-bar.tsx","../src/hooks/use-cel-filter-editor-state.ts","../src/lib/cel-filter/constants.ts","../src/lib/cel-filter/date-utils.ts","../src/lib/cel-filter/types.ts","../src/lib/cel-filter/value-utils.ts","../src/lib/cel-filter/compile/escape-cel-string.ts","../src/lib/cel-filter/compile/operators.ts","../src/lib/cel-filter/compile/validate-condition.ts","../src/lib/cel-filter/compile/apply-display-rules.ts","../src/lib/cel-filter/schema-utils.ts","../src/lib/cel-filter/compile/compute-is-emit-ready.ts","../src/lib/cel-filter/compile/compile-cel-filter-tree.ts","../src/lib/cel-filter/tree-utils.ts","../src/lib/data-table/contextual-filters.ts","../src/hooks/use-table-column-resizing.ts","../src/hooks/use-grid-layout.ts","../src/lib/data-table/grid-layout.ts","../src/data-table/empty-view.tsx","../src/data-table/pagination.tsx","../src/data-table/table-primitives.tsx","../src/data-table/view-filter.tsx","../src/filter-bar/filter-bar.tsx","../src/lib/data-table/filter-types.ts","../src/section-header.tsx"],"sourcesContent":["'use client';\n\nimport type { Cell, ColumnFilter, RowData } from '@tanstack/react-table';\n\nimport {\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuSeparator,\n ContextMenuSub,\n ContextMenuSubContent,\n ContextMenuSubTrigger,\n} from '@upbound/monarch-core';\n\n/** A single entry (or nested submenu) in a cell's contextual right-click menu, alongside the built-in \"Filter by this value\" item. */\nexport type ContextualMenuAction<TData extends RowData = RowData, TValue = unknown> = {\n id: string;\n label: React.ReactNode;\n disabled?: boolean | ((cell: Cell<TData, TValue>) => boolean);\n onSelect?: (cell: Cell<TData, TValue>) => void;\n items?: ContextualMenuAction<TData, TValue>[];\n className?: string;\n};\n\nexport type CellContextualFilterProps<TData extends RowData, TValue> = {\n filter?: ColumnFilter;\n globalSearch?: string;\n cell: Cell<TData, TValue>;\n onContextCell: (filter: ColumnFilter, cell: Cell<TData, TValue>) => void;\n onContextSearch?: (searchTerm: string, cell: Cell<TData, TValue>) => void;\n contextualMenuActions?: ContextualMenuAction<TData, TValue>[];\n};\n\n/**\n * The right-click cell menu content: an always-present \"Filter by this value\"\n * item (disabled, never hidden, when nothing is derivable) plus any\n * `contextualMenuActions`. Renders only the `ContextMenuContent` — the\n * `ContextMenu`/`ContextMenuTrigger` wrapping the cell lives in the caller.\n */\nexport function CellContextualFilter<TData extends RowData, TValue>({\n filter,\n globalSearch,\n cell,\n onContextCell,\n onContextSearch,\n contextualMenuActions = [],\n}: CellContextualFilterProps<TData, TValue>) {\n const disabled = !filter && !(globalSearch && onContextSearch);\n\n function handleSelect() {\n if (globalSearch && onContextSearch) {\n onContextSearch(globalSearch, cell);\n return;\n }\n if (!filter) return;\n onContextCell(filter, cell);\n }\n\n function renderAction(action: ContextualMenuAction<TData, TValue>) {\n const actionDisabled = typeof action.disabled === 'function' ? action.disabled(cell) : (action.disabled ?? false);\n\n if (action.items?.length) {\n return (\n <ContextMenuSub key={action.id}>\n <ContextMenuSubTrigger\n disabled={actionDisabled}\n className={action.className}\n onClick={event => event.stopPropagation()}\n >\n {action.label}\n </ContextMenuSubTrigger>\n <ContextMenuSubContent>{action.items.map(renderAction)}</ContextMenuSubContent>\n </ContextMenuSub>\n );\n }\n\n // Radix fires both `onClick` and `onSelect` for a pointer activation but\n // only `onSelect` for keyboard — this flag stops the pointer path from\n // double-invoking `action.onSelect`.\n let handledClick = false;\n\n return (\n <ContextMenuItem\n key={action.id}\n disabled={actionDisabled}\n onClick={event => {\n event.stopPropagation();\n handledClick = true;\n action.onSelect?.(cell);\n }}\n onSelect={() => {\n if (handledClick) {\n handledClick = false;\n return;\n }\n action.onSelect?.(cell);\n }}\n >\n {action.label}\n </ContextMenuItem>\n );\n }\n\n return (\n <ContextMenuContent>\n <ContextMenuItem disabled={disabled} onClick={event => event.stopPropagation()} onSelect={handleSelect}>\n Filter by this value\n </ContextMenuItem>\n {contextualMenuActions.length > 0 && (\n <>\n <ContextMenuSeparator />\n {contextualMenuActions.map(renderAction)}\n </>\n )}\n </ContextMenuContent>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport { flexRender, type Column, type ColumnOrderState, type RowData } from '@tanstack/react-table';\n\nimport { Button } from '@upbound/monarch-core';\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@upbound/monarch-core';\nimport { Icon } from '@upbound/monarch-core';\nimport { cn } from '@/lib/utils';\nimport {\n isFilterOnlyColumn,\n mergeUnpinnedColumnOrder,\n normalizeColumnOrdering,\n splitColumnOrderByPinning,\n} from '@/lib/data-table/utils';\n\n/** Honors both runtime (drag-pinned) and declarative (`meta.pinning`) pin state. */\nfunction getColumnPinning<TData extends RowData>(column: Column<TData, unknown> | undefined): 'left' | 'right' | false {\n if (!column) return false;\n return column.getIsPinned() || column.columnDef.meta?.pinning || false;\n}\n\nfunction ColumnOptionsItem<TData extends RowData>({\n column,\n disableColumnOrdering,\n isDropTarget,\n onDragStart,\n onDrop,\n onDragOver,\n onDragEnd,\n}: {\n column: Column<TData, unknown>;\n disableColumnOrdering?: boolean;\n isDropTarget: boolean;\n onDragStart: (column: Column<TData, unknown>) => (event: React.DragEvent) => void;\n onDrop: (column: Column<TData, unknown>) => (event: React.DragEvent) => void;\n onDragOver: (event: React.DragEvent) => void;\n onDragEnd: (event: React.DragEvent) => void;\n}) {\n const [isDraggedOver, setIsDraggedOver] = React.useState(false);\n const isDraggable = column.getIsPinned() === false && !column.columnDef.meta?.pinning && !disableColumnOrdering;\n const canHide = column.getCanHide();\n\n // Rendering the header outside of an actual header cell — `header`/`table`\n // are unused by ordinary string/label header defs, matching the source.\n const headerContent = React.useMemo(\n () => flexRender(column.columnDef.header, { column, header: null, table: null } as never),\n [column],\n );\n\n const dragProps = {\n draggable: isDraggable,\n onDragStart: isDraggable ? onDragStart(column) : undefined,\n onDrop: isDropTarget\n ? (e: React.DragEvent) => {\n onDrop(column)(e);\n setIsDraggedOver(false);\n }\n : undefined,\n onDragOver: isDropTarget\n ? (e: React.DragEvent) => {\n onDragOver(e);\n setIsDraggedOver(true);\n }\n : undefined,\n onDragLeave: isDropTarget ? () => setIsDraggedOver(false) : undefined,\n onDragEnd: isDraggable ? onDragEnd : undefined,\n className: cn(\n 'relative flex items-center gap-2',\n isDraggedOver && 'before:bg-primary before:absolute before:inset-x-0 before:top-0 before:h-0.5',\n ),\n };\n\n const itemContent = (\n <>\n {isDraggable && <Icon name=\"grip-vertical\" size=\"sm\" className=\"text-muted-foreground cursor-move\" />}\n <span className=\"flex min-w-0 flex-1 items-center gap-2\">{headerContent}</span>\n </>\n );\n\n if (!canHide) {\n return <DropdownMenuItem {...dragProps}>{itemContent}</DropdownMenuItem>;\n }\n\n return (\n <DropdownMenuCheckboxItem\n checked={column.getIsVisible()}\n onCheckedChange={() => column.toggleVisibility()}\n {...dragProps}\n >\n {itemContent}\n </DropdownMenuCheckboxItem>\n );\n}\n\nexport type ColumnOptionsProps<TData extends RowData> = {\n columns: Column<TData, unknown>[];\n columnOrdering: ColumnOrderState;\n onColumnOrderingChange: React.Dispatch<React.SetStateAction<ColumnOrderState>>;\n disableColumnOrdering?: boolean;\n};\n\n/**\n * The \"Columns\" dropdown: per-column visibility toggle + native HTML5\n * drag-and-drop reordering (the source uses the browser's own drag/drop API,\n * not a DnD library). Pinned/actions/filter-only columns are excluded from\n * dragging and from the draggable list respectively; reordering only ever\n * touches the unpinned slots (`mergeUnpinnedColumnOrder`), so pinned columns\n * never jump position.\n */\nexport function ColumnOptions<TData extends RowData>({\n columns: rawColumns,\n columnOrdering,\n onColumnOrderingChange,\n disableColumnOrdering,\n}: ColumnOptionsProps<TData>) {\n const [isDragging, setIsDragging] = React.useState(false);\n const [isLastDropZoneActive, setIsLastDropZoneActive] = React.useState(false);\n\n const columns = React.useMemo(\n () => rawColumns.filter(col => !isFilterOnlyColumn(col) && col.columnDef.meta?.actions !== true),\n [rawColumns],\n );\n const allColumnById = React.useMemo(() => new Map(rawColumns.map(col => [col.id, col])), [rawColumns]);\n const columnById = React.useMemo(() => new Map(columns.map(col => [col.id, col])), [columns]);\n const fullColumnOrder = React.useMemo(\n () =>\n normalizeColumnOrdering(\n columnOrdering,\n rawColumns.map(col => col.id),\n ),\n [columnOrdering, rawColumns],\n );\n\n const getColumnPinningFor = React.useCallback(\n (columnId: string) => getColumnPinning(allColumnById.get(columnId)),\n [allColumnById],\n );\n\n const { leftPinnedColumns, unpinnedColumns, rightPinnedColumns } = splitColumnOrderByPinning(\n fullColumnOrder,\n getColumnPinningFor,\n );\n\n function handleDragStart(column: Column<TData, unknown>) {\n return (event: React.DragEvent) => {\n event.dataTransfer.setData('text/plain', column.id);\n event.dataTransfer.dropEffect = 'move';\n event.dataTransfer.effectAllowed = 'move';\n setIsDragging(true);\n };\n }\n\n function handleDrop(targetColumn: Column<TData, unknown>) {\n return (event: React.DragEvent) => {\n event.preventDefault();\n event.stopPropagation();\n\n const draggedColumnId = event.dataTransfer.getData('text/plain');\n const targetColumnId = targetColumn.id;\n if (!draggedColumnId || !targetColumnId || draggedColumnId === targetColumnId) {\n setIsDragging(false);\n return;\n }\n\n const draggedIndex = unpinnedColumns.indexOf(draggedColumnId);\n if (draggedIndex === -1) {\n setIsDragging(false);\n return;\n }\n\n const newOrder = [...unpinnedColumns];\n const [removed] = newOrder.splice(draggedIndex, 1);\n const targetIndex = newOrder.indexOf(targetColumnId);\n if (targetIndex === -1) {\n setIsDragging(false);\n return;\n }\n newOrder.splice(targetIndex, 0, removed);\n\n onColumnOrderingChange(mergeUnpinnedColumnOrder(fullColumnOrder, newOrder, getColumnPinningFor));\n setIsDragging(false);\n };\n }\n\n function handleDropAtEnd(event: React.DragEvent) {\n event.preventDefault();\n event.stopPropagation();\n setIsLastDropZoneActive(false);\n\n const draggedColumnId = event.dataTransfer.getData('text/plain');\n if (!draggedColumnId) {\n setIsDragging(false);\n return;\n }\n\n const draggedIndex = unpinnedColumns.indexOf(draggedColumnId);\n if (draggedIndex === -1) {\n setIsDragging(false);\n return;\n }\n\n const newOrder = [...unpinnedColumns];\n const [removed] = newOrder.splice(draggedIndex, 1);\n newOrder.push(removed);\n\n onColumnOrderingChange(mergeUnpinnedColumnOrder(fullColumnOrder, newOrder, getColumnPinningFor));\n setIsDragging(false);\n }\n\n function handleDragOver(event: React.DragEvent) {\n event.preventDefault();\n }\n\n function handleDragEnd() {\n setIsDragging(false);\n setIsLastDropZoneActive(false);\n }\n\n function orderedColumns(ids: string[]) {\n return ids.map(id => columnById.get(id)).filter((c): c is Column<TData, unknown> => !!c && !c.getIsGrouped?.());\n }\n\n function canDropOnColumn(column: Column<TData, unknown>) {\n return column.getIsPinned() === false && !column.columnDef.meta?.pinning;\n }\n\n const leftPinned = orderedColumns(leftPinnedColumns);\n const unpinned = orderedColumns(unpinnedColumns);\n const rightPinned = orderedColumns(rightPinnedColumns);\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" className=\"shrink-0\">\n <Icon name=\"table-columns\" data-icon=\"inline-start\" />\n Columns\n <Icon name=\"chevron-down\" data-icon=\"inline-end\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"w-58 p-0\">\n <div className=\"p-1\">\n {[...leftPinned, ...unpinned].map(column => (\n <ColumnOptionsItem\n key={column.id}\n column={column}\n disableColumnOrdering={disableColumnOrdering}\n isDropTarget={canDropOnColumn(column)}\n onDragStart={handleDragStart}\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n onDragEnd={handleDragEnd}\n />\n ))}\n {!disableColumnOrdering && (\n <div\n onDrop={handleDropAtEnd}\n onDragOver={e => {\n e.preventDefault();\n setIsLastDropZoneActive(true);\n }}\n onDragLeave={() => setIsLastDropZoneActive(false)}\n className={cn(\n 'relative w-full transition-colors',\n isDragging && 'h-3',\n isLastDropZoneActive &&\n 'bg-muted before:bg-primary before:absolute before:inset-x-0 before:top-0 before:h-0.5',\n )}\n />\n )}\n {rightPinned.map(column => (\n <ColumnOptionsItem\n key={column.id}\n column={column}\n disableColumnOrdering={disableColumnOrdering}\n isDropTarget={canDropOnColumn(column)}\n onDragStart={handleDragStart}\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n onDragEnd={handleDragEnd}\n />\n ))}\n </div>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n","import { clsx, type ClassValue } from 'clsx';\nimport { extendTailwindMerge } from 'tailwind-merge';\n\nconst twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n 'font-size': [\n {\n text: [\n 'display-hero',\n 'display-kpi-sm',\n 'display-kpi',\n 'display-kpi-lg',\n 'display-feature',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'body-lg',\n 'body',\n 'body-sm',\n 'caption',\n 'eyebrow',\n ],\n },\n ],\n },\n },\n});\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import type { Column, ColumnOrderState, FilterFn, Row, RowData } from '@tanstack/react-table';\n\nimport './table-meta';\nimport type { DateRangeColumnFilterValue } from './filter-types';\n\nconst TO_EACH_SIDE = 2;\n\ntype ColumnPinningPosition = 'left' | 'right' | false;\n\n/**\n * Reconciles a persisted column order against the table's actual columns:\n * drops stale/duplicate ids and appends any column missing from the\n * persisted order (in `allColumnIds` order).\n */\nexport function normalizeColumnOrdering(columnOrdering: ColumnOrderState, allColumnIds: string[]): ColumnOrderState {\n const validIds = new Set(allColumnIds);\n const seenIds = new Set<string>();\n\n const trackedColumnIds = columnOrdering.filter(columnId => {\n if (!validIds.has(columnId) || seenIds.has(columnId)) return false;\n seenIds.add(columnId);\n return true;\n });\n\n return [...trackedColumnIds, ...allColumnIds.filter(columnId => !seenIds.has(columnId))];\n}\n\nexport function isSameColumnOrdering(left: ColumnOrderState, right: ColumnOrderState): boolean {\n return left.length === right.length && left.every((columnId, index) => columnId === right[index]);\n}\n\n/** Splits a full column order into left-pinned / unpinned / right-pinned buckets, preserving relative order within each. */\nexport function splitColumnOrderByPinning(\n fullColumnOrder: string[],\n getColumnPinning: (columnId: string) => ColumnPinningPosition,\n) {\n return {\n leftPinnedColumns: fullColumnOrder.filter(columnId => getColumnPinning(columnId) === 'left'),\n unpinnedColumns: fullColumnOrder.filter(columnId => getColumnPinning(columnId) === false),\n rightPinnedColumns: fullColumnOrder.filter(columnId => getColumnPinning(columnId) === 'right'),\n };\n}\n\n/**\n * Refills only the unpinned slots of `fullColumnOrder` from `nextUnpinnedOrder`,\n * in order — pinned columns keep their exact index. This is what keeps\n * drag-reordering from relocating pinned/actions columns to the array edges.\n */\nexport function mergeUnpinnedColumnOrder(\n fullColumnOrder: string[],\n nextUnpinnedOrder: string[],\n getColumnPinning: (columnId: string) => ColumnPinningPosition,\n): ColumnOrderState {\n const nextUnpinnedIterator = nextUnpinnedOrder[Symbol.iterator]();\n\n return fullColumnOrder.map(columnId =>\n getColumnPinning(columnId) === false ? (nextUnpinnedIterator.next().value ?? columnId) : columnId,\n );\n}\n\nexport type PaginationInfo = {\n visiblePages: (number | undefined)[];\n pageCount: number;\n itemStart: number;\n itemEnd: number;\n};\n\n/** Computes the pagination footer's visible page numbers (with ellipsis markers), page count, and item range. */\nexport function getPaginationInfo(pageIndex: number, totalRows: number, pageSize: number): PaginationInfo {\n const currentPage = pageIndex + 1;\n const pageCount = Math.ceil(totalRows / pageSize);\n\n function getPages(): (number | undefined)[] {\n if (pageCount === 0) return [];\n if (pageCount === 1) return [1];\n if (pageCount === 2) return [1, 2];\n\n const runStart = Math.max(currentPage - TO_EACH_SIDE, 2);\n const runEnd = Math.min(currentPage + TO_EACH_SIDE, pageCount - 1);\n const hasBeginningEllipsis = runStart > 2;\n const hasEndingEllipsis = currentPage + 3 < pageCount;\n\n return [\n 1,\n ...(hasBeginningEllipsis ? [undefined] : []),\n ...Array.from({ length: runEnd - runStart + 1 }).map((_, i) => i + runStart),\n ...(hasEndingEllipsis ? [undefined] : []),\n pageCount,\n ];\n }\n\n return {\n pageCount,\n visiblePages: getPages(),\n itemStart: totalRows === 0 ? 0 : pageIndex * pageSize + 1,\n itemEnd: Math.min(currentPage * pageSize, totalRows),\n };\n}\n\n/** Ascending date sort; invalid dates sort first (treated as `-Infinity`). */\nexport function sortColumnByDate<T>(rowA: Row<T>, rowB: Row<T>, columnId: string): number {\n const dateA = new Date(rowA.getValue(columnId) as string | number | Date).getTime();\n const dateB = new Date(rowB.getValue(columnId) as string | number | Date).getTime();\n\n const dateNumA = isNaN(dateA) ? -Infinity : dateA;\n const dateNumB = isNaN(dateB) ? -Infinity : dateB;\n\n return dateNumA - dateNumB;\n}\n\nfunction isDateValid(date: Date): boolean {\n return !isNaN(date.getTime());\n}\n\n/** An invalid/missing filter range passes every row (filter inactive); an invalid row date fails (excluded). */\nexport const filterColumnByDateRange: FilterFn<RowData> = (\n row: Row<RowData>,\n columnId: string,\n filterValue: NonNullable<DateRangeColumnFilterValue>,\n) => {\n const { startDate, endDate } = filterValue;\n if (!startDate || !isDateValid(startDate) || !endDate || !isDateValid(endDate)) return true;\n\n const date = new Date(row.getValue(columnId) as string | number | Date);\n if (!isDateValid(date)) return false;\n\n return date >= startDate && date <= endDate;\n};\n\n/**\n * @deprecated Prefer TanStack's built-in `arrIncludesSome` filter fn — kept\n * only for the case-insensitive matching it does that `arrIncludesSome`\n * doesn't; a straight swap changes behavior for mixed-case data.\n */\nexport const filterColumnByArrayValues: FilterFn<RowData> = (\n row: Row<RowData>,\n columnId: string,\n arrayOfValues: string[],\n) => {\n if (arrayOfValues.length) {\n const rowValue = row.getValue(columnId) as string;\n return arrayOfValues.filter(val => val?.toLowerCase() === rowValue?.toLowerCase()).length > 0;\n }\n return true;\n};\n\n/** Sorts by `secondaryColumnId` when the primary column's values are equal. Never returns 0 (always a definite order). */\nexport function secondarySortByColumn(\n secondaryColumnId: string,\n): (rowA: Row<RowData>, rowB: Row<RowData>, columnId: string) => number {\n return (rowA: Row<RowData>, rowB: Row<RowData>, columnId: string): number => {\n const rowAPrimaryColumnValue = rowA.getValue(columnId) as string;\n const rowBPrimaryColumnValue = rowB.getValue(columnId) as string;\n const rowASecondaryColumnValue = rowA.getValue(secondaryColumnId) as string;\n const rowBSecondaryColumnValue = rowB.getValue(secondaryColumnId) as string;\n\n if (rowAPrimaryColumnValue === rowBPrimaryColumnValue) {\n return rowASecondaryColumnValue > rowBSecondaryColumnValue ? 1 : -1;\n }\n return rowAPrimaryColumnValue > rowBPrimaryColumnValue ? 1 : -1;\n };\n}\n\nexport function isFilterOnlyColumn<T>(column: Column<T, unknown>): boolean {\n return column.columnDef.meta?.filterOnly === true;\n}\n\nexport type TableDataState = 'empty' | 'loading' | 'error' | 'success';\n\n/** Strict precedence: error > loading > empty > success. `loading` still renders table content (skeleton rows). */\nexport function getTableState({\n error,\n loading,\n rowCount,\n}: {\n error: boolean;\n loading: boolean;\n rowCount: number;\n}): TableDataState {\n if (error) return 'error';\n if (loading) return 'loading';\n return rowCount === 0 ? 'empty' : 'success';\n}\n","'use client';\n\nimport * as React from 'react';\nimport type { CellContext, ColumnDef, Row, RowData } from '@tanstack/react-table';\n\nimport { Button } from '@upbound/monarch-core';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@upbound/monarch-core';\nimport { Icon } from '@upbound/monarch-core';\nimport { RelativeTime } from '@/relative-time';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@upbound/monarch-core';\nimport { cn } from '@/lib/utils';\n\n// ── Row actions menu ────────────────────────────────────\n// Built on Monarch's DropdownMenu (Radix), not legacy's Popover + <ul>/<li> —\n// Radix's menu already closes on item select, so there's no `closePopover`\n// render-prop to thread through; consumers just pass `DropdownMenuItem`s.\n\nexport function RowActions({\n align = 'end',\n children,\n contentClassName,\n}: {\n align?: 'start' | 'end';\n children: React.ReactNode;\n contentClassName?: string;\n}) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"icon-xs\" aria-label=\"Row actions\" onClick={e => e.stopPropagation()}>\n <Icon name=\"ellipsis-vertical\" size=\"sm\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align={align} className={contentClassName} onClick={event => event.stopPropagation()}>\n {children}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n\nexport function RowActionItem({\n disabled,\n className,\n tooltip,\n children,\n onClick,\n}: {\n disabled?: boolean;\n className?: string;\n tooltip?: string;\n children: React.ReactNode;\n onClick?: React.ComponentProps<typeof DropdownMenuItem>['onClick'];\n}) {\n const item = (\n <DropdownMenuItem disabled={disabled} className={className} onClick={onClick}>\n {children}\n </DropdownMenuItem>\n );\n\n if (!tooltip) return item;\n\n // Trigger wraps the item in a plain span (not `asChild` onto the item\n // itself) so hover still reaches the tooltip even when the item is\n // disabled — a disabled DropdownMenuItem has `pointer-events-none`.\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"block\">{item}</span>\n </TooltipTrigger>\n <TooltipContent>{tooltip}</TooltipContent>\n </Tooltip>\n );\n}\n\n/** A ready-made right-pinned, non-sortable/filterable/hideable \"Actions\" column. */\nexport function getActionsColumnDefinition<TData extends RowData, TValue = unknown>({\n cell,\n}: Pick<ColumnDef<TData, TValue>, 'cell'>): ColumnDef<TData, TValue> {\n return {\n id: 'actions',\n header: 'Actions',\n size: 80,\n enableColumnFilter: false,\n enableGlobalFilter: false,\n enableSorting: false,\n enableHiding: false,\n meta: { pinning: 'right', actions: true },\n cell,\n };\n}\n\n// ── Row expansion ───────────────────────────────────────\n\nexport function ExpandButton<TData extends RowData>({ row }: { row: Row<TData> }) {\n if (!row.getCanExpand()) return null;\n const isExpanded = row.getIsExpanded();\n\n return (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n aria-label={isExpanded ? 'Collapse row' : 'Expand row'}\n onClick={e => {\n e.stopPropagation();\n row.getToggleExpandedHandler()();\n }}\n >\n <Icon name={isExpanded ? 'chevron-up' : 'chevron-down'} size=\"sm\" />\n </Button>\n );\n}\n\n/** A ready-made right-pinned, fixed-width (28px) \"Expand\" column. Defaults to an `ExpandButton` cell. */\nexport function getExpandColumnDefinition<TData extends RowData, TValue = unknown>(options?: {\n cell?: (context: CellContext<TData, TValue>) => React.ReactNode;\n}): ColumnDef<TData, TValue> {\n return {\n id: 'expand',\n header: '',\n size: 28,\n minSize: 28,\n maxSize: 28,\n enableColumnFilter: false,\n enableGlobalFilter: false,\n enableSorting: false,\n enableHiding: false,\n meta: { pinning: 'right', actions: true },\n cell: options?.cell ?? (({ row }) => <ExpandButton row={row} />),\n };\n}\n\n// ── Value cell ───────────────────────────────────────────\n\nexport type DataTableValueCellProps = {\n content?: React.ReactNode;\n /** Shown as a tooltip; also becomes the link's native title when `href` is set. */\n title?: string;\n className?: string;\n href?: string;\n onClick?: () => void;\n};\n\n/**\n * A generic cell renderer: a link (when `href` is set), a dashed-underline\n * value with a hover tooltip (when `title` is set), or plain content — with\n * an em-dash placeholder when `content` is empty. Legacy injected its router\n * `Link` via a DI hook (`useLink()`); Monarch has no such layer, so the link\n * branch renders a plain `<a>`.\n */\nexport function DataTableValueCell({ content, title, className, href, onClick }: DataTableValueCellProps) {\n const baseClassName = cn('text-body truncate', className);\n\n if (href) {\n return (\n <p className={baseClassName}>\n <a href={href} title={title} className=\"underline hover:no-underline\" onClick={onClick}>\n {content}\n </a>\n </p>\n );\n }\n\n if (title) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n className={cn(\n baseClassName,\n 'focus-visible:ring-ring/30 cursor-help underline decoration-dashed underline-offset-2 focus-visible:ring-2',\n )}\n onClick={onClick}\n >\n {content}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">{title}</TooltipContent>\n </Tooltip>\n );\n }\n\n return <p className={baseClassName}>{content ? <span>{content}</span> : <span>&mdash;</span>}</p>;\n}\n\n/** A timestamp cell — relative time in the cell, absolute time on hover (via Monarch's `RelativeTime`); an em-dash when absent. */\nexport function TimestampCell({ timestamp }: { timestamp?: Date | string | number }) {\n if (!timestamp) return <DataTableValueCell content=\"—\" />;\n return <RelativeTime date={timestamp} className=\"block\" />;\n}\n","'use client';\n\nimport * as React from 'react';\nimport { cn } from '@/lib/utils';\nimport { useMounted } from '@/hooks/use-mounted';\n\n// ── Format helpers ─────────────────────────────────────────────────────────────\n//\n// `locale` is `undefined` (browser/runtime default — the viewer's actual\n// locale, per Monarch's \"use locale-aware formatting\" content principle) once\n// mounted client-side, and a fixed `'en-US'` for the server-rendered/first-\n// paint value — the server can't know the viewer's locale ahead of time, and\n// passing a locale that differs between server and client render would\n// hydration-mismatch. Callers gate this via `useMounted()` below, so the\n// locale-aware value replaces the fixed one right after mount (see\n// RelativeTime/AbsoluteTimestamp).\n\n/** Returns a human-readable relative label for `date` vs now. */\nfunction formatRelativeDefault(date: Date, locale: string | undefined): string {\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n\n // Future dates\n if (diffMs < 0) {\n const abs = Math.abs(diffMs);\n const mins = Math.floor(abs / 60000);\n const hrs = Math.floor(mins / 60);\n const days = Math.floor(hrs / 24);\n if (abs < 60000) return 'just now';\n if (mins < 60) return `in ${mins} minute${mins === 1 ? '' : 's'}`;\n if (hrs < 24) return `in ${hrs} hour${hrs === 1 ? '' : 's'}`;\n if (days < 7) return `in ${days} day${days === 1 ? '' : 's'}`;\n if (days < 30) return `in ${Math.floor(days / 7)} week${Math.floor(days / 7) === 1 ? '' : 's'}`;\n return `on ${date.toLocaleDateString(locale, {\n month: 'short',\n day: 'numeric',\n ...(date.getFullYear() !== now.getFullYear() ? { year: 'numeric' } : {}),\n })}`;\n }\n\n // Past dates\n const secs = Math.floor(diffMs / 1000);\n const mins = Math.floor(secs / 60);\n const hrs = Math.floor(mins / 60);\n const days = Math.floor(hrs / 24);\n\n if (secs < 60) return 'just now';\n if (mins < 60) return `${mins} minute${mins === 1 ? '' : 's'} ago`;\n if (hrs < 24) return `${hrs} hour${hrs === 1 ? '' : 's'} ago`;\n if (days === 1) return 'yesterday';\n if (days < 7) return `${days} days ago`;\n if (days < 14) return 'last week';\n if (days < 30) return `${Math.floor(days / 7)} weeks ago`;\n\n // > 30 days: fall back to absolute date\n return `on ${date.toLocaleDateString(locale, {\n month: 'short',\n day: 'numeric',\n ...(date.getFullYear() !== now.getFullYear() ? { year: 'numeric' } : {}),\n })}`;\n}\n\n/**\n * Compact relative label — abbreviates units for tight horizontal space\n * (tables, KPI cards). Preserves \"ago\", \"in\", \"on\", and \"just now\" so\n * directionality and reference points stay legible at a glance.\n */\nfunction formatRelativeCompact(date: Date, locale: string | undefined): string {\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n\n // Future dates\n if (diffMs < 0) {\n const abs = Math.abs(diffMs);\n const mins = Math.floor(abs / 60000);\n const hrs = Math.floor(mins / 60);\n const days = Math.floor(hrs / 24);\n if (abs < 60000) return 'just now';\n if (mins < 60) return `in ${mins}m`;\n if (hrs < 24) return `in ${hrs}h`;\n if (days < 7) return `in ${days}d`;\n if (days < 30) return `in ${Math.floor(days / 7)}w`;\n return `on ${date.toLocaleDateString(locale, {\n month: 'short',\n day: 'numeric',\n ...(date.getFullYear() !== now.getFullYear() ? { year: 'numeric' } : {}),\n })}`;\n }\n\n // Past dates\n const secs = Math.floor(diffMs / 1000);\n const mins = Math.floor(secs / 60);\n const hrs = Math.floor(mins / 60);\n const days = Math.floor(hrs / 24);\n\n if (secs < 60) return 'just now';\n if (mins < 60) return `${mins}m ago`;\n if (hrs < 24) return `${hrs}h ago`;\n if (days < 7) return `${days}d ago`;\n if (days < 30) return `${Math.floor(days / 7)}w ago`;\n\n return `on ${date.toLocaleDateString(locale, {\n month: 'short',\n day: 'numeric',\n ...(date.getFullYear() !== now.getFullYear() ? { year: 'numeric' } : {}),\n })}`;\n}\n\nfunction formatRelative(date: Date, variant: 'default' | 'compact', locale: string | undefined): string {\n return variant === 'compact' ? formatRelativeCompact(date, locale) : formatRelativeDefault(date, locale);\n}\n\n/** Returns the update interval in ms appropriate for the current age. */\nfunction updateInterval(date: Date): number {\n const diffMs = Math.abs(Date.now() - date.getTime());\n const diffMin = diffMs / 60000;\n if (diffMin < 60) return 60_000; // update every minute while < 1 hour old\n if (diffMin < 1440) return 300_000; // every 5 min while < 1 day old\n return 3_600_000; // every hour otherwise\n}\n\n/** Formats an absolute tooltip title. */\nfunction absoluteTitle(date: Date, locale: string | undefined): string {\n return date.toLocaleString(locale, {\n weekday: 'long',\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n timeZoneName: 'short',\n });\n}\n\n// ── Component ──────────────────────────────────────────────────────────────────\n\nexport interface RelativeTimeProps extends Omit<React.TimeHTMLAttributes<HTMLTimeElement>, 'dateTime' | 'title'> {\n /**\n * The timestamp to display. Accepts a `Date`, ISO string, or unix milliseconds.\n */\n date: Date | string | number;\n /**\n * Format variant. `default` produces full-word output (\"5 minutes ago\",\n * \"yesterday\"). `compact` abbreviates units (\"5m ago\", \"1d ago\") for tight\n * horizontal space like tables, KPI cards, or inline metadata.\n */\n variant?: 'default' | 'compact';\n /**\n * Override the tooltip shown on hover. Defaults to the full localized\n * absolute date-time string (e.g. \"Monday, January 20, 2025 at 3:22 PM PST\").\n */\n title?: string;\n}\n\n/**\n * Displays a timestamp as a live-updating relative string (\"5 minutes ago\",\n * \"yesterday\", \"on Nov 18\") with the absolute date in the native tooltip.\n *\n * Falls back to an absolute \"on [Month Day]\" format for dates older than 30 days\n * so that stale timestamps remain legible at a glance.\n *\n * @see https://design.upbound.io/components/date-and-time\n */\nexport function RelativeTime({ date, variant = 'default', title, className, ...props }: RelativeTimeProps) {\n const d = React.useMemo(() => new Date(date), [date]);\n const mounted = useMounted();\n // Fixed locale for the server-rendered/first-paint value (the server can't\n // know the viewer's locale); the viewer's actual locale once mounted.\n const locale = mounted ? undefined : 'en-US';\n\n const [label, setLabel] = React.useState<string>(() => formatRelative(d, variant, locale));\n\n React.useEffect(() => {\n // Re-compute immediately on mount (picks up the viewer's real locale, and\n // avoids the relative label going stale)\n setLabel(formatRelative(d, variant, locale));\n\n const schedule = () => {\n const id = window.setInterval(() => {\n setLabel(formatRelative(d, variant, locale));\n }, updateInterval(d));\n return id;\n };\n const id = schedule();\n return () => window.clearInterval(id);\n }, [d, variant, locale]);\n\n return (\n <time\n dateTime={d.toISOString()}\n title={title ?? absoluteTitle(d, locale)}\n className={cn('tabular-nums', className)}\n {...props}\n >\n {label}\n </time>\n );\n}\n\n// ── Absolute Timestamp ────────────────────────────────────────────────────────\n\n/** Formats am/pm per Content Principles: lowercase, space before, no periods. */\nfunction formatAmPm(date: Date, options: Intl.DateTimeFormatOptions, locale: string | undefined): string {\n const parts = new Intl.DateTimeFormat(locale, options).formatToParts(date);\n let result = '';\n for (const part of parts) {\n if (part.type === 'dayPeriod') {\n result += part.value.toLowerCase().replace(/\\./g, '');\n } else {\n result += part.value;\n }\n }\n return result;\n}\n\nfunction formatAbsolute(date: Date, variant: string, end: Date | undefined, locale: string | undefined): string {\n switch (variant) {\n case 'deadline': {\n const weekday = date.toLocaleDateString(locale, { weekday: 'short' });\n const datePart = date.toLocaleDateString(locale, { month: 'short', day: 'numeric', year: 'numeric' });\n const timePart = formatAmPm(date, { hour: 'numeric', minute: '2-digit' }, locale);\n const tz = date.toLocaleTimeString(locale, { timeZoneName: 'short' }).split(' ').pop() ?? '';\n return `${weekday}, ${datePart} \\u00b7 ${timePart} ${tz}`;\n }\n case 'log': {\n const datePart = date.toLocaleDateString(locale, { month: 'short', day: 'numeric', year: 'numeric' });\n const timePart = formatAmPm(date, { hour: 'numeric', minute: '2-digit' }, locale);\n const tz = date.toLocaleTimeString(locale, { timeZoneName: 'short' }).split(' ').pop() ?? '';\n return `${datePart}, ${timePart} ${tz}`;\n }\n case 'range': {\n if (!end) return date.toLocaleDateString(locale, { month: 'short', day: 'numeric', year: 'numeric' });\n const startYear = date.getFullYear();\n const endYear = end.getFullYear();\n if (startYear === endYear) {\n const start = date.toLocaleDateString(locale, { month: 'short', day: 'numeric' });\n const endStr = end.toLocaleDateString(locale, { month: 'short', day: 'numeric', year: 'numeric' });\n return `${start} \\u2013 ${endStr}`;\n }\n const start = date.toLocaleDateString(locale, { month: 'short', day: 'numeric', year: 'numeric' });\n const endStr = end.toLocaleDateString(locale, { month: 'short', day: 'numeric', year: 'numeric' });\n return `${start} \\u2013 ${endStr}`;\n }\n case 'date':\n default:\n return date.toLocaleDateString(locale, { month: 'short', day: 'numeric', year: 'numeric' });\n }\n}\n\nexport interface AbsoluteTimestampProps extends Omit<React.TimeHTMLAttributes<HTMLTimeElement>, 'dateTime'> {\n /** The timestamp to display. */\n date: Date | string | number;\n /** Format variant matching the Content Principles absolute timestamp table. */\n variant?: 'deadline' | 'log' | 'date' | 'range';\n /** End date for range variant. */\n end?: Date | string | number;\n}\n\n/**\n * Formats a date as an absolute timestamp following the Content Principles.\n * Use for deadlines, certificate expiry, audit logs, and date-only displays.\n */\nexport function AbsoluteTimestamp({ date, variant = 'date', end, className, ...props }: AbsoluteTimestampProps) {\n const d = React.useMemo(() => new Date(date), [date]);\n const e = React.useMemo(() => (end ? new Date(end) : undefined), [end]);\n const mounted = useMounted();\n // Fixed locale for the server-rendered/first-paint value (the server can't\n // know the viewer's locale); the viewer's actual locale once mounted.\n const locale = mounted ? undefined : 'en-US';\n\n return (\n <time\n dateTime={d.toISOString()}\n title={absoluteTitle(d, locale)}\n className={cn('tabular-nums', className)}\n {...props}\n >\n {formatAbsolute(d, variant, e, locale)}\n </time>\n );\n}\n\n// ── Elapsed Time ──────────────────────────────────────────────────────────────\n\nfunction formatElapsed(totalSeconds: number, variant: string): string {\n const days = Math.floor(totalSeconds / 86400);\n const hours = Math.floor((totalSeconds % 86400) / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = Math.floor(totalSeconds % 60);\n\n switch (variant) {\n case 'expanded': {\n const parts: string[] = [];\n if (days > 0) parts.push(`${days} day${days === 1 ? '' : 's'}`);\n if (hours > 0) parts.push(`${hours} hour${hours === 1 ? '' : 's'}`);\n if (minutes > 0) parts.push(`${minutes} minute${minutes === 1 ? '' : 's'}`);\n if (seconds > 0 || parts.length === 0) parts.push(`${seconds} second${seconds === 1 ? '' : 's'}`);\n return parts.join(', ');\n }\n case 'long': {\n if (days > 0) return `${days}d ${hours}h`;\n if (hours > 0) return `${hours}h ${minutes}m`;\n return `${minutes}m`;\n }\n case 'compact':\n default: {\n if (days > 0) return `${days}d ${hours}h`;\n if (hours > 0) return `${hours}h ${minutes}m ${seconds}s`;\n if (minutes > 0) return `${minutes}m ${seconds}s`;\n return `${seconds}s`;\n }\n }\n}\n\nexport interface ElapsedTimeProps extends Omit<React.TimeHTMLAttributes<HTMLTimeElement>, 'dateTime'> {\n /** Total elapsed seconds. Ignored if startedAt is provided. */\n seconds?: number;\n /** Format variant matching the Content Principles elapsed time table. */\n variant?: 'compact' | 'expanded' | 'long';\n /** Live-tick every second for active operations. */\n live?: boolean;\n /** Compute elapsed from a start time instead of a fixed seconds value. */\n startedAt?: Date | string | number;\n}\n\n/**\n * Formats a duration as elapsed time following the Content Principles.\n * Use for reconciliation loops, build jobs, health checks, and running operations.\n */\nexport function ElapsedTime({\n seconds: secondsProp,\n variant = 'compact',\n live = false,\n startedAt,\n className,\n ...props\n}: ElapsedTimeProps) {\n const startDate = React.useMemo(() => (startedAt ? new Date(startedAt) : undefined), [startedAt]);\n\n const computeSeconds = React.useCallback(() => {\n if (startDate) return Math.floor((Date.now() - startDate.getTime()) / 1000);\n return secondsProp ?? 0;\n }, [startDate, secondsProp]);\n\n const [elapsed, setElapsed] = React.useState(computeSeconds);\n\n React.useEffect(() => {\n setElapsed(computeSeconds());\n\n if (!live && !startDate) return;\n\n const id = window.setInterval(() => {\n setElapsed(computeSeconds());\n }, 1000);\n return () => window.clearInterval(id);\n }, [live, startDate, computeSeconds]);\n\n const iso = `PT${elapsed}S`;\n\n return (\n <time dateTime={iso} className={cn('tabular-nums', className)} {...props}>\n {formatElapsed(elapsed, variant)}\n </time>\n );\n}\n","import { useSyncExternalStore } from 'react';\n\nfunction subscribe() {\n return () => {};\n}\n\n/**\n * Returns `false` on the server and during initial client hydration, then\n * `true` once mounted — for values that are only valid client-side (e.g. the\n * viewer's actual `Intl` locale, vs. a fixed locale used for the server-\n * rendered/first-paint value) without a hydration mismatch. Implemented via\n * `useSyncExternalStore` rather than `useEffect` + `setState` — the latter\n * works, but re-derives the same \"true\" value on every mount and trips\n * `react-hooks/set-state-in-effect` since there's no actual subscription.\n */\nexport function useMounted() {\n return useSyncExternalStore(\n subscribe,\n () => true,\n () => false,\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport {\n getCoreRowModel,\n getExpandedRowModel,\n getFacetedRowModel,\n getFacetedUniqueValues,\n getFilteredRowModel,\n getGroupedRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n noop,\n useReactTable,\n type Cell,\n type ColumnFilter,\n type ColumnFiltersState,\n type ColumnOrderState,\n type ColumnPinningState,\n type ExpandedState,\n type PaginationState,\n type RowData,\n type SortingState,\n type VisibilityState,\n} from '@tanstack/react-table';\n\nimport { CelFilterBar } from '@/cel-filter-bar';\nimport { Icon } from '@upbound/monarch-core';\nimport { InputGroup, InputGroupAddon, InputGroupInput } from '@upbound/monarch-core';\nimport { createEmptyCelFilterTree } from '@/lib/cel-filter';\nimport {\n columnFilterValueToStrings,\n getColumnFilterCount,\n mergeColumnFilter,\n} from '@/lib/data-table/contextual-filters';\nimport {\n getTableState,\n isFilterOnlyColumn,\n isSameColumnOrdering,\n normalizeColumnOrdering,\n} from '@/lib/data-table/utils';\nimport { cn } from '@/lib/utils';\nimport { RESIZE_MAX_UNBOUNDED, useTableColumnResizing } from '@/hooks/use-table-column-resizing';\nimport { useGridLayout } from '@/hooks/use-grid-layout';\n\nimport { ColumnOptions } from './column-options';\nimport type { DataTableProps } from './data-table-types';\nimport { DataTableEmptyView } from './empty-view';\nimport { DataTablePagination } from './pagination';\nimport { DataTableBody, DataTableHeader, DataTableRoot } from './table-primitives';\nimport { ViewFilter } from './view-filter';\nimport { SectionHeader, SectionHeaderContent, SectionHeaderDescription, SectionHeaderTitle } from '../section-header';\n\nconst DEFAULT_PAGE_SIZE = 20;\n\n/**\n * Full port of legacy `TableWrapper` — same prop surface\n * (`DataTableProps<T>` mirrors `TableWrapperProps<T>` name-for-name), same\n * controlled/uncontrolled state merges, same behavior. The only intended\n * difference is that columns, headers, rows, cells, and menus render through\n * Monarch's own primitives instead of legacy's hand-rolled ones.\n */\nexport function DataTable<TData extends RowData>({\n id,\n config,\n\n title,\n description,\n emptyView,\n showError,\n className,\n fitContent = false,\n loading = false,\n renderSkeletonCell,\n serverSidePagination = false,\n ActionsComponent: Actions,\n onRowRender,\n renderExpandedRow,\n expanded: parentExpanded,\n onExpandedChange: parentOnExpandedChange,\n\n disableSearch = false,\n disableFilters = false,\n disableSorting = false,\n paginationConfig = true,\n disableColumnReordering = false,\n disableColumnVisibility = false,\n disableColumnResizing = false,\n disableColumnPinning = false,\n\n searchTerm: parentGlobalFilter,\n onSearchTermChange: parentSetGlobalFilter,\n\n filters: parentColumnFilters,\n onFiltersChange: parentSetColumnFilters,\n\n pagination: parentPagination,\n onPaginationChange: parentSetPagination,\n\n sorting: parentSorting,\n onSortingChange: parentSetSorting,\n\n columnOrdering: parentColumnOrdering,\n onColumnOrderingChange: parentSetColumnOrdering,\n\n columnVisibility: parentColumnVisibility,\n onColumnVisibilityChange: parentSetColumnVisibility,\n\n columnPinning: parentColumnPinning,\n onColumnPinningChange: parentSetColumnPinning,\n\n grouping: parentGrouping,\n onGroupingChange: parentSetGrouping,\n\n celFilterClassName,\n showContextualFilter = false,\n onContextCell,\n contextualMenuActions,\n\n layout = 'auto',\n\n initialColumnSizing,\n onColumnSizingPersist,\n\n stickyHeader = false,\n\n celFilterConfig,\n}: DataTableProps<TData>) {\n const isGrid = layout === 'grid';\n const tableBodyScrollRef = React.useRef<HTMLDivElement>(null);\n\n const [innerGlobalFilter, setInnerGlobalFilter] = React.useState('');\n const [innerColumnOrdering, setInnerColumnOrdering] = React.useState<ColumnOrderState>([]);\n const [innerColumnFilters, setInnerColumnFilters] = React.useState<ColumnFiltersState>([]);\n const [innerSorting, setInnerSorting] = React.useState<SortingState>(config.state?.sorting || []);\n const [innerColumnPinning, setInnerColumnPinning] = React.useState<ColumnPinningState>({ left: [], right: [] });\n\n const [innerPagination, setInnerPagination] = React.useState<PaginationState>({\n pageIndex: config.state?.pagination?.pageIndex || 0,\n pageSize: config.state?.pagination?.pageSize || DEFAULT_PAGE_SIZE,\n });\n\n const [innerGrouping, setInnerGrouping] = React.useState<string[]>([]);\n const [innerColumnVisibility, setInnerColumnVisibility] = React.useState<VisibilityState>({});\n const [innerExpanded, setInnerExpanded] = React.useState<ExpandedState>({});\n\n const {\n columnSizing,\n handleColumnSizingChange,\n handleAutosizeAll: rawHandleAutosizeAll,\n handleAutosizeColumn: rawHandleAutosizeColumn,\n handleResetColumnSize: rawHandleResetColumnSize,\n } = useTableColumnResizing({\n initialSizing: initialColumnSizing,\n onColumnSizingPersist,\n maxSize: isGrid ? RESIZE_MAX_UNBOUNDED : undefined,\n });\n\n const globalFilter = parentGlobalFilter ?? innerGlobalFilter;\n const applyGlobalFilter = parentSetGlobalFilter ?? setInnerGlobalFilter;\n\n const columnFilters = parentColumnFilters || innerColumnFilters;\n const applyColumnFilters = parentSetColumnFilters ?? setInnerColumnFilters;\n\n const pagination = parentPagination || innerPagination;\n const setPagination = parentSetPagination ?? setInnerPagination;\n const shouldDisablePagination = paginationConfig === false;\n\n // In server-side pagination mode a search/filter change must return to the\n // first page — the active page often doesn't exist for the new result set.\n // We do this at the moment of the change rather than from a state-diff\n // effect: filters that arrive via props (deep-link / lens hydration) must\n // NOT reset the page, only edits the user routes through these setters.\n const resetPageIndexOnFilterChange = React.useCallback(() => {\n if (!serverSidePagination || pagination.pageIndex === 0) return;\n setPagination(prev => ({ ...prev, pageIndex: 0 }));\n }, [serverSidePagination, pagination.pageIndex, setPagination]);\n\n const setGlobalFilter = React.useCallback<React.Dispatch<React.SetStateAction<string>>>(\n value => {\n applyGlobalFilter(value);\n resetPageIndexOnFilterChange();\n },\n [applyGlobalFilter, resetPageIndexOnFilterChange],\n );\n\n const setColumnFilters = React.useCallback<React.Dispatch<React.SetStateAction<ColumnFiltersState>>>(\n value => {\n applyColumnFilters(value);\n resetPageIndexOnFilterChange();\n },\n [applyColumnFilters, resetPageIndexOnFilterChange],\n );\n\n React.useLayoutEffect(() => {\n if (shouldDisablePagination) return;\n tableBodyScrollRef.current?.scrollTo({ top: 0 });\n }, [shouldDisablePagination, pagination.pageIndex]);\n\n const sorting = parentSorting || innerSorting;\n const setSorting = parentSetSorting ?? setInnerSorting;\n\n const columnOrdering = parentColumnOrdering || innerColumnOrdering;\n const setColumnOrdering = parentSetColumnOrdering ?? setInnerColumnOrdering;\n\n const columnVisibility = parentColumnVisibility ?? innerColumnVisibility;\n const setColumnVisibility = parentSetColumnVisibility ?? setInnerColumnVisibility;\n\n const expanded = parentExpanded ?? innerExpanded;\n const setExpanded = parentOnExpandedChange ?? setInnerExpanded;\n\n const columnPinning = parentColumnPinning ?? innerColumnPinning;\n const setColumnPinning = parentSetColumnPinning ?? setInnerColumnPinning;\n\n const grouping = parentGrouping ?? innerGrouping;\n const setGrouping = parentSetGrouping ?? setInnerGrouping;\n\n const hasGrouping = grouping.length > 0;\n\n const hasExternalSearch = parentGlobalFilter !== undefined;\n const hasExternalFilters = parentColumnFilters !== undefined;\n const shouldDisableFiltersModels = !!disableFilters && !!disableSearch && !hasExternalSearch && !hasExternalFilters;\n\n // eslint-disable-next-line react-hooks/incompatible-library\n const table = useReactTable<TData>({\n ...config,\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: !disableSorting ? getSortedRowModel() : undefined,\n getPaginationRowModel: !shouldDisablePagination ? getPaginationRowModel() : undefined,\n getFilteredRowModel: !shouldDisableFiltersModels ? getFilteredRowModel() : undefined,\n getFacetedRowModel: !shouldDisableFiltersModels ? getFacetedRowModel() : undefined,\n getFacetedUniqueValues: !shouldDisableFiltersModels ? getFacetedUniqueValues() : undefined,\n ...(!!renderExpandedRow && {\n getExpandedRowModel: getExpandedRowModel(),\n getRowCanExpand: () => true,\n paginateExpandedRows: false,\n }),\n getGroupedRowModel: hasGrouping ? getGroupedRowModel() : undefined,\n getExpandedRowModel: hasGrouping ? getExpandedRowModel() : undefined,\n groupedColumnMode: hasGrouping ? 'reorder' : undefined,\n enableFilters: !shouldDisableFiltersModels,\n enableGlobalFilter: !shouldDisableFiltersModels,\n enableColumnFilters: !shouldDisableFiltersModels,\n enableColumnResizing: !disableColumnResizing,\n enableColumnPinning: !disableColumnPinning,\n enableHiding: !disableColumnVisibility,\n columnResizeMode: disableColumnResizing ? undefined : isGrid ? 'onEnd' : 'onChange',\n defaultColumn: {\n size: 150,\n minSize: 40,\n maxSize: isGrid ? RESIZE_MAX_UNBOUNDED : 500,\n },\n state: {\n sorting: disableSorting ? [] : sorting,\n globalFilter: shouldDisableFiltersModels ? '' : globalFilter,\n columnFilters: shouldDisableFiltersModels ? [] : columnFilters,\n pagination: shouldDisablePagination ? undefined : pagination,\n columnOrder: disableColumnReordering ? [] : columnOrdering,\n columnVisibility: disableColumnVisibility ? {} : columnVisibility,\n columnSizing: disableColumnResizing ? {} : columnSizing,\n columnPinning: disableColumnPinning ? { left: [], right: [] } : columnPinning,\n ...(!!renderExpandedRow && { expanded }),\n grouping,\n ...(hasGrouping && { expanded: true as const }),\n },\n manualSorting: serverSidePagination,\n manualFiltering: serverSidePagination,\n manualPagination: serverSidePagination,\n onSortingChange: disableSorting ? noop : setSorting,\n onColumnFiltersChange: shouldDisableFiltersModels ? noop : setColumnFilters,\n onGlobalFilterChange: shouldDisableFiltersModels ? noop : setGlobalFilter,\n onPaginationChange: shouldDisablePagination ? noop : setPagination,\n onColumnOrderChange: disableColumnReordering ? noop : setColumnOrdering,\n onColumnVisibilityChange: disableColumnVisibility ? noop : setColumnVisibility,\n onColumnSizingChange: disableColumnResizing ? noop : handleColumnSizingChange,\n onColumnPinningChange: disableColumnPinning ? noop : setColumnPinning,\n ...(!!renderExpandedRow && {\n onExpandedChange: (updater: ExpandedState | ((prev: ExpandedState) => ExpandedState)) =>\n setExpanded(prev => (typeof updater === 'function' ? updater(prev) : updater)),\n }),\n onGroupingChange: setGrouping,\n });\n\n const headerGroups = table.getHeaderGroups();\n const tableRows = table.getRowModel().rows;\n const rowCount = table.getRowCount();\n\n const flatColumns = table.getAllFlatColumns();\n const displayableColumns = flatColumns.filter(col => !isFilterOnlyColumn(col));\n\n const orderedVisibleColumns = table.getVisibleLeafColumns().filter(col => !isFilterOnlyColumn(col));\n\n const [gridMeasuredMins, setGridMeasuredMins] = React.useState<Record<string, number>>({});\n const { gridTemplateColumns, gridRootRef, handleAutosizeAll, handleAutosizeColumn, handleResetColumnSize } =\n useGridLayout<TData>({\n layout,\n table,\n tableBodyScrollRef,\n displayableColumns,\n columnOrdering,\n gridMeasuredMins,\n setGridMeasuredMins,\n handleColumnSizingChange,\n rawHandleAutosizeAll,\n rawHandleAutosizeColumn,\n rawHandleResetColumnSize,\n });\n\n const handleContextCell = React.useCallback(\n (filter: ColumnFilter, cell: Cell<TData, unknown>) => {\n if (celFilterConfig?.onContextualFilter) {\n celFilterConfig.onContextualFilter({\n columnId: filter.id,\n values: columnFilterValueToStrings(filter.value),\n cell,\n });\n return;\n }\n\n const filterDefinition = table.getColumn(filter.id)?.columnDef.meta?.filter;\n setColumnFilters(prev => mergeColumnFilter(prev, filter, filterDefinition));\n onContextCell?.(filter, cell);\n },\n [celFilterConfig, onContextCell, setColumnFilters, table],\n );\n\n const handleContextSearch = React.useCallback(\n (searchTerm: string) => {\n setGlobalFilter(searchTerm);\n },\n [setGlobalFilter],\n );\n\n const totalTableWidth = React.useMemo(() => {\n if (isGrid) return 0;\n const firstGroup = headerGroups[0];\n if (!firstGroup) return 0;\n\n const displayableIds = new Set(displayableColumns.map(c => c.id));\n return firstGroup.headers\n .filter(h => displayableIds.has(h.column.id))\n .reduce((sum, h) => sum + h.column.getSize(), 0);\n }, [isGrid, headerGroups, displayableColumns]);\n\n const filterCount = celFilterConfig\n ? celFilterConfig.activeFilterCount\n : table\n .getState()\n .columnFilters.map(({ id: columnFilterId, value }) =>\n getColumnFilterCount(value, table.getColumn(columnFilterId)?.columnDef.meta?.filter),\n )\n .reduce((prev, curr) => prev + curr, 0);\n\n const tableState = getTableState({ error: !!showError, loading, rowCount });\n\n const shouldDisable = tableState === 'error';\n const shouldRenderTableContent = tableState !== 'error' && tableState !== 'empty';\n\n const resetFilters = () => {\n if (celFilterConfig) {\n celFilterConfig.onTreeChange(createEmptyCelFilterTree());\n } else {\n table.resetColumnFilters();\n }\n setGlobalFilter('');\n };\n\n React.useEffect(() => {\n // Sync the inner mirror when the parent-supplied searchTerm changes (e.g. switching views).\n if (parentGlobalFilter !== undefined) {\n setInnerGlobalFilter(parentGlobalFilter);\n }\n }, [parentGlobalFilter]);\n\n React.useEffect(() => {\n if (disableColumnReordering) return;\n\n const allColumnIds = flatColumns.map(col => col.id);\n const normalizedColumnOrdering = normalizeColumnOrdering(columnOrdering, allColumnIds);\n\n if (!isSameColumnOrdering(columnOrdering, normalizedColumnOrdering)) {\n setColumnOrdering(normalizedColumnOrdering);\n }\n }, [columnOrdering, disableColumnReordering, flatColumns, setColumnOrdering]);\n\n const showViewHeader = !!title || !!Actions;\n const showColumnOptions = !disableColumnReordering || !disableColumnVisibility;\n\n const toolbarSearch = !disableSearch && (\n <InputGroup className=\"w-70\">\n <InputGroupAddon align=\"inline-start\">\n <Icon name=\"magnifying-glass\" />\n </InputGroupAddon>\n <InputGroupInput\n aria-label=\"Search\"\n placeholder=\"Search…\"\n disabled={shouldDisable}\n value={globalFilter}\n onChange={e => setGlobalFilter(e.target.value)}\n />\n </InputGroup>\n );\n\n const toolbarColumns = !!showColumnOptions && (\n <ColumnOptions\n columns={flatColumns}\n columnOrdering={columnOrdering}\n onColumnOrderingChange={setColumnOrdering}\n disableColumnOrdering={disableColumnReordering}\n />\n );\n\n return (\n <div\n id={`table-${id}`}\n data-testid={`table-${id}`}\n className={cn(\n 'flex w-full flex-col',\n !fitContent && (shouldRenderTableContent ? 'h-full min-h-0' : 'h-screen max-h-[calc(100vh-100px)]'),\n className,\n )}\n >\n {showViewHeader && (\n <SectionHeader className=\"mb-4 flex w-full gap-2\">\n <SectionHeaderContent>\n {!!title && <SectionHeaderTitle>{title}</SectionHeaderTitle>}\n {!!description && <SectionHeaderDescription>{description}</SectionHeaderDescription>}\n </SectionHeaderContent>\n </SectionHeader>\n )}\n\n <div className=\"mb-4 flex flex-row gap-2\">\n {toolbarSearch}\n <div className=\"ml-auto flex items-center gap-2\">\n {!!Actions && <Actions state={tableState} />}\n {toolbarColumns}\n </div>\n </div>\n\n {!disableFilters && (\n <div className=\"flex w-full\">\n {celFilterConfig ? (\n <div className={cn('mr-2 mb-4 min-w-0 flex-1', celFilterClassName)}>\n <CelFilterBar\n schema={celFilterConfig.schema}\n tree={celFilterConfig.tree}\n onChange={celFilterConfig.onTreeChange}\n onCompileResultChange={celFilterConfig.onCompileResultChange}\n onRestrictedOptionSelect={celFilterConfig.onRestrictedOptionSelect}\n showClearButton={celFilterConfig.showClearButton}\n />\n </div>\n ) : (\n <ViewFilter\n columns={flatColumns}\n columnFilters={columnFilters}\n onColumnFiltersChange={setColumnFilters}\n className=\"data-[visible-filters=true]:mb-4\"\n />\n )}\n </div>\n )}\n\n {shouldRenderTableContent ? (\n <>\n <div className=\"flex min-h-0 flex-1 flex-col\" data-testid=\"table-main\">\n <div\n ref={tableBodyScrollRef}\n className={cn(\n 'min-h-0 flex-1 overflow-auto rounded-lg border **:data-[slot=table-container]:overflow-visible',\n !!stickyHeader && 'max-h-[calc(100svh-250px)]',\n )}\n >\n <DataTableRoot\n layout={layout}\n gridTemplateColumns={gridTemplateColumns}\n gridRootRef={gridRootRef}\n style={\n isGrid\n ? { width: '100%' }\n : totalTableWidth > 0\n ? { width: `max(100%, ${totalTableWidth}px)`, minWidth: '100%' }\n : { width: '100%' }\n }\n >\n <DataTableHeader\n headerGroups={headerGroups}\n onAutosizeAll={handleAutosizeAll}\n onAutosizeColumn={handleAutosizeColumn}\n onResetColumnSize={handleResetColumnSize}\n stickyHeader={stickyHeader}\n layout={layout}\n />\n <DataTableBody\n tableRows={tableRows}\n tableState={tableState}\n columns={orderedVisibleColumns}\n skeletonRowCount={pagination.pageSize}\n renderSkeletonCell={renderSkeletonCell}\n onRowRender={onRowRender}\n renderExpandedRow={renderExpandedRow}\n showContextualFilter={showContextualFilter}\n onContextCell={handleContextCell}\n onContextSearch={handleContextSearch}\n contextualMenuActions={contextualMenuActions}\n layout={layout}\n />\n </DataTableRoot>\n </div>\n </div>\n\n {!shouldDisablePagination && !!pagination && (\n <DataTablePagination\n rowCount={rowCount}\n rowCountRelation={config.rowCountRelation ?? 'eq'}\n paginationConfig={paginationConfig}\n pageSize={pagination.pageSize}\n pageIndex={pagination.pageIndex}\n onPageChange={p => table.setPageIndex(p - 1)}\n onPageSizeChange={nextPageSize =>\n setPagination(prev => ({ ...(prev || pagination), pageIndex: 0, pageSize: nextPageSize }))\n }\n />\n )}\n </>\n ) : (\n <DataTableEmptyView\n emptyView={emptyView}\n tableState={tableState}\n filterCount={filterCount + (!!globalFilter.trim() ? 1 : 0)}\n resetFilters={resetFilters}\n />\n )}\n </div>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport { Icon } from '@upbound/monarch-core';\nimport { type DateRange } from 'react-day-picker';\n\nimport { cn } from '@/lib/utils';\nimport { useMounted } from '@/hooks/use-mounted';\nimport { Badge } from '@upbound/monarch-core';\nimport { Button } from '@upbound/monarch-core';\nimport { ButtonGroup, ButtonGroupText } from '@upbound/monarch-core';\nimport { Calendar } from '@upbound/monarch-core';\nimport {\n Combobox,\n ComboboxChip,\n ComboboxClearAll,\n ComboboxCollection,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxGroup,\n ComboboxInput,\n ComboboxItem,\n ComboboxLabel,\n ComboboxList,\n ComboboxSelectedChips,\n ComboboxSeparator,\n ComboboxTrigger,\n ComboboxValue,\n} from '@upbound/monarch-core';\nimport { Input } from '@upbound/monarch-core';\nimport { InputGroup, InputGroupAddon, InputGroupInput, InputGroupText } from '@upbound/monarch-core';\nimport { Label } from '@upbound/monarch-core';\nimport { Popover, PopoverContent, PopoverTrigger } from '@upbound/monarch-core';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@upbound/monarch-core';\n\nimport { useCelFilterEditorState, type CelConditionEditorController } from '@/hooks/use-cel-filter-editor-state';\nimport {\n allowsMultipleConditions,\n appendCondition,\n applyDisplayRules,\n applyOperatorChange,\n calendarDayStartInstant,\n compileCelFilterTree,\n computeIsEmitReady,\n createDefaultCondition,\n dateBoundaryForOperator,\n formatCalendarDateUtc,\n formatInstantLabel,\n getAllowedOperators,\n getOperatorLabel,\n getQuantifierLabel,\n isCelFilterCondition,\n isCheckboxCelValue,\n isDateRangeOperator,\n isDateRelativeOperator,\n isDateWindowOperator,\n isRelativeDateCelValue,\n parseCalendarDate,\n readDateCelValue,\n readMapKeyCelValue,\n readMultiTextCelValue,\n readTimeOfDay,\n RELATIVE_DURATION_PRESET_VALUES,\n removeConditionById,\n replaceCondition,\n resolveColumnDefinition,\n resolveFilterShape,\n withTimeOfDay,\n type CelColumnDefinition,\n type CelColumnOption,\n type CelFilterBarProps,\n type CelFilterCondition,\n type CelOperator,\n type CompileResult,\n type DateCelValue,\n type MapKeyCelValue,\n type MultiTextCelValue,\n type RelativeDurationPreset,\n} from '@/lib/cel-filter';\n\nconst RELATIVE_PRESET_LABELS: Record<RelativeDurationPreset, string> = {\n '24h': 'Last 24 hours',\n '168h': 'Last 7 days',\n '720h': 'Last 30 days',\n};\n\n// Neutralizes Select's default purple focus ring/border and matches the\n// plain grey hover/focus background the rest of a pill's segments (value\n// trigger, remove button — both Button variant=\"outline\") use, so every\n// Select-based segment reads as part of one continuous control. `!` is\n// required on the hover border: Select's own hover border is a compound\n// variant (hover:not-disabled:not-aria-invalid:border-ring/50) that a plain\n// hover:border-input doesn't win against via class order alone.\nconst SEGMENT_SELECT_TRIGGER_CLASSNAME =\n 'hover:border-input! focus-visible:border-input focus-visible:ring-0 hover:bg-muted focus-visible:bg-muted aria-expanded:bg-muted';\n\n// ── CelFilterBar ──────────────────────────────────────\n\nfunction CelFilterBar({\n tree,\n onChange,\n schema,\n onCompileResultChange,\n onRestrictedOptionSelect,\n showClearButton = false,\n className,\n}: CelFilterBarProps) {\n const editor = useCelFilterEditorState();\n const onCompileResultChangeRef = React.useRef(onCompileResultChange);\n React.useEffect(() => {\n onCompileResultChangeRef.current = onCompileResultChange;\n });\n\n const rawResult = React.useMemo(() => compileCelFilterTree(tree, schema), [tree, schema]);\n const displayResult = React.useMemo(\n () =>\n applyDisplayRules(rawResult, {\n editingConditionId: editor.editingConditionId,\n committedConditionIds: editor.committedConditionIds,\n }),\n [rawResult, editor.editingConditionId, editor.committedConditionIds],\n );\n const isEmitReady = React.useMemo(\n () =>\n computeIsEmitReady(rawResult, editor.editingConditionId, schema, tree, {\n activeSurface: editor.activeSurface,\n committedConditionIds: editor.committedConditionIds,\n }),\n [rawResult, editor.editingConditionId, editor.activeSurface, editor.committedConditionIds, schema, tree],\n );\n\n React.useEffect(() => {\n onCompileResultChangeRef.current?.({ ...displayResult, isEmitReady });\n }, [displayResult, isEmitReady]);\n\n const conditions = tree.root.children.filter(isCelFilterCondition);\n\n function handleAddFilter(columnId: string) {\n const condition = createDefaultCondition({ schema, columnId });\n onChange(appendCondition(tree, condition));\n editor.beginEditing(condition.id);\n editor.suppressDismissFor(condition.id);\n }\n\n function handleRemove(conditionId: string) {\n onChange(removeConditionById(tree, conditionId));\n editor.removeCondition(conditionId);\n }\n\n function handleClearAll() {\n onChange({ root: { ...tree.root, children: [] } });\n editor.clearSuppress();\n }\n\n return (\n <div data-slot=\"cel-filter-bar\" className={cn('flex flex-wrap items-center gap-2', className)}>\n <CelAddFilterButton schema={schema} conditions={conditions} onSelect={handleAddFilter} />\n\n {conditions.map(condition => {\n const columnDef = resolveColumnDefinition(condition, schema);\n if (!columnDef) return null;\n return (\n <CelFilterPill\n key={condition.id}\n condition={condition}\n columnDef={columnDef}\n schema={schema}\n tree={tree}\n onChange={onChange}\n controller={editor.getController(condition.id)}\n issues={displayResult.issues.filter(issue => issue.nodeId === condition.id)}\n onRemove={() => handleRemove(condition.id)}\n onRestrictedOptionSelect={onRestrictedOptionSelect}\n />\n );\n })}\n\n {showClearButton && conditions.length > 0 && (\n <Button variant=\"ghost\" size=\"sm\" onClick={handleClearAll}>\n Clear all\n </Button>\n )}\n </div>\n );\n}\n\n// ── Add filter menu ───────────────────────────────────\n\ntype CelAddFilterGroup = { value: string; items: CelColumnDefinition[] };\n\nfunction CelAddFilterButton({\n schema,\n conditions,\n onSelect,\n}: {\n schema: CelFilterBarProps['schema'];\n conditions: CelFilterCondition[];\n onSelect: (columnId: string) => void;\n}) {\n const usedSingleInstanceColumnIds = new Set(\n conditions\n .map(condition => resolveColumnDefinition(condition, schema))\n .filter(\n (columnDef): columnDef is CelColumnDefinition => !!columnDef && !allowsMultipleConditions(columnDef.filterType),\n )\n .map(columnDef => columnDef.id),\n );\n const availableColumns = schema.columns.filter(column => !usedSingleInstanceColumnIds.has(column.id));\n\n const groupMap = new Map<string, CelColumnDefinition[]>();\n for (const column of availableColumns) {\n const key = column.group ?? '';\n const list = groupMap.get(key) ?? [];\n list.push(column);\n groupMap.set(key, list);\n }\n const groups: CelAddFilterGroup[] = Array.from(groupMap.entries()).map(([value, items]) => ({ value, items }));\n\n return (\n <Combobox\n items={groups}\n itemToStringValue={(item: CelColumnDefinition) => item.title}\n itemToStringLabel={(item: CelColumnDefinition) => item.title}\n onValueChange={(column: CelColumnDefinition | null) => {\n if (column) onSelect(column.id);\n }}\n >\n {/* role=\"combobox\" doesn't pick up child text as its accessible name the\n way a plain button would — an explicit aria-label is required, not\n just a nicety. */}\n <ComboboxTrigger aria-label=\"Add filter\" render={<Button variant=\"outline\" />}>\n <Icon name=\"plus\" data-icon=\"inline-start\" />\n Add filter\n </ComboboxTrigger>\n <ComboboxContent align=\"start\" className=\"w-64\">\n <ComboboxInput showTrigger={false} placeholder=\"Search filters…\" />\n <ComboboxEmpty>No filters found.</ComboboxEmpty>\n <ComboboxList>\n {(group: CelAddFilterGroup) => (\n <ComboboxGroup key={group.value} items={group.items}>\n {group.value && <ComboboxLabel>{group.value}</ComboboxLabel>}\n <ComboboxCollection>\n {(column: CelColumnDefinition) => (\n <ComboboxItem key={column.id} value={column}>\n {column.title}\n </ComboboxItem>\n )}\n </ComboboxCollection>\n </ComboboxGroup>\n )}\n </ComboboxList>\n </ComboboxContent>\n </Combobox>\n );\n}\n\n// ── Filter pill ────────────────────────────────────────\n\nfunction formatConditionSummary(\n condition: CelFilterCondition,\n columnDef: CelColumnDefinition,\n locale?: string,\n): string {\n const shape = columnDef.filterType === 'keyValue' ? 'map' : columnDef.filterType;\n\n switch (shape) {\n case 'checkbox': {\n const value = isCheckboxCelValue(condition.value) ? condition.value : [];\n if (value.length === 0) return 'Any';\n if (value.length === 1) {\n return columnDef.options?.find(opt => opt.value === value[0])?.label ?? value[0];\n }\n return `${value.length} ${columnDef.pluralTitle}`;\n }\n case 'radio':\n case 'static': {\n const value = typeof condition.value === 'string' ? condition.value : '';\n if (!value) return 'Any';\n return columnDef.options?.find(opt => opt.value === value)?.label ?? value;\n }\n case 'text':\n return typeof condition.value === 'string' && condition.value ? condition.value : 'Any';\n case 'multiText': {\n const value = readMultiTextCelValue(condition.value);\n if (value.tokens.length === 0) return 'Any';\n if (value.tokens.length === 1) return value.tokens[0];\n return `${value.tokens.length} values`;\n }\n case 'date': {\n const value = readDateCelValue(condition.value);\n if (isRelativeDateCelValue(value)) return value.preset ? RELATIVE_PRESET_LABELS[value.preset] : 'Any';\n if (value.range)\n return `${formatInstantLabel(value.range.start, { locale })} – ${formatInstantLabel(value.range.end, { locale })}`;\n if (value.instant) return formatInstantLabel(value.instant, { withTime: value.hasTime, locale });\n return 'Any';\n }\n case 'map': {\n const value = readMapKeyCelValue(condition.value);\n if (!value.key) return 'Any';\n return value.value ? `${value.key}=${value.value}` : value.key;\n }\n default:\n return 'Any';\n }\n}\n\nfunction CelFilterPill({\n condition,\n columnDef,\n schema,\n tree,\n onChange,\n controller,\n issues,\n onRemove,\n onRestrictedOptionSelect,\n}: {\n condition: CelFilterCondition;\n columnDef: CelColumnDefinition;\n schema: CelFilterBarProps['schema'];\n tree: CelFilterBarProps['tree'];\n onChange: CelFilterBarProps['onChange'];\n controller: CelConditionEditorController;\n issues: CompileResult['issues'];\n onRemove: () => void;\n onRestrictedOptionSelect: CelFilterBarProps['onRestrictedOptionSelect'];\n}) {\n const shape = resolveFilterShape(condition, schema) ?? columnDef.filterType;\n const mounted = useMounted();\n // Fixed locale for the server-rendered/first-paint value (the server can't\n // know the viewer's locale); the viewer's actual locale once mounted. Only\n // the 'date' shape's summary is locale-sensitive, but computed unconditionally\n // since hooks can't run after the early returns below.\n const locale = mounted ? undefined : 'en-US';\n\n // checkbox/radio always compose Combobox for their value editor (own trigger\n // + popup, per Monarch's standing directive for multi/single-select pickers)\n // rather than sharing the generic Popover the other shapes use below.\n if (shape === 'checkbox') {\n return (\n <CelCheckboxComboboxPill\n condition={condition}\n columnDef={columnDef}\n tree={tree}\n onChange={onChange}\n controller={controller}\n issues={issues}\n onRemove={onRemove}\n onRestrictedOptionSelect={onRestrictedOptionSelect}\n />\n );\n }\n if (shape === 'radio') {\n return (\n <CelRadioComboboxPill\n condition={condition}\n columnDef={columnDef}\n tree={tree}\n onChange={onChange}\n controller={controller}\n issues={issues}\n onRemove={onRemove}\n onRestrictedOptionSelect={onRestrictedOptionSelect}\n />\n );\n }\n\n function updateValue(value: CelFilterCondition['value']) {\n onChange(replaceCondition(tree, condition.id, c => ({ ...c, value })));\n }\n\n function updateOperator(operator: CelOperator) {\n const hadValue = condition.value !== undefined;\n const next = applyOperatorChange(condition, operator, shape);\n onChange(replaceCondition(tree, condition.id, () => next));\n // Switching operators can clear an incompatible value (e.g. an instant when\n // moving to a range operator) — reopen the value popover so the user isn't\n // left with a silently invalid pill they have to notice and click back into.\n if (hadValue && next.value === undefined) controller.beginEditing();\n }\n\n const allowedOperators = getAllowedOperators(columnDef);\n\n return (\n <Popover\n open={controller.popoverVisible}\n onOpenChange={open => {\n if (open) controller.beginEditing();\n else if (!controller.isDismissSuppressed()) controller.handlePopoverDismiss();\n }}\n >\n <ButtonGroup>\n <ButtonGroupText>{columnDef.title}</ButtonGroupText>\n <CelOperatorSegment\n columnTitle={columnDef.title}\n operator={condition.operator}\n allowedOperators={allowedOperators}\n hideOnSingleOperator={columnDef.hideOnSingleOperator}\n onChangeOperator={updateOperator}\n />\n {shape === 'multiText' && (\n <CelQuantifierSegment\n columnTitle={columnDef.title}\n value={readMultiTextCelValue(condition.value)}\n onChangeValue={updateValue}\n />\n )}\n <PopoverTrigger asChild>\n <Button variant=\"outline\" className=\"gap-1 font-normal\">\n <span className={cn(issues.length > 0 && 'text-destructive')}>\n {formatConditionSummary(condition, columnDef, locale)}\n </span>\n <Icon name=\"chevron-down\" size=\"sm\" className=\"text-muted-foreground\" />\n </Button>\n </PopoverTrigger>\n <Button variant=\"outline\" size=\"icon\" aria-label={`Remove ${columnDef.title} filter`} onClick={onRemove}>\n <Icon name=\"xmark\" />\n </Button>\n </ButtonGroup>\n <PopoverContent align=\"start\" className={shape === 'date' ? 'w-fit' : 'w-72'}>\n {shape === 'text' && (\n <CelTextValueEditor condition={condition} onChangeValue={updateValue} onCommit={controller.commit} />\n )}\n {shape === 'multiText' && <CelMultiTextValueEditor condition={condition} onChangeValue={updateValue} />}\n {shape === 'date' && <CelDateValueEditor condition={condition} onChangeValue={updateValue} />}\n {shape === 'map' && (\n <CelKeyValueValueEditor condition={condition} onChangeValue={updateValue} onCommit={controller.commit} />\n )}\n\n {issues.length > 0 && (\n <p className=\"text-body-sm text-destructive\">{issues.map(issue => issue.message).join(' ')}</p>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n\n// ── Operator segment ───────────────────────────────────\n// Shared between the Popover-based pill (text/multiText/date/map) and the\n// two Combobox-based pills below — always its own ButtonGroup segment,\n// never hidden inside the value editor.\n\nfunction CelOperatorSegment({\n columnTitle,\n operator,\n allowedOperators,\n hideOnSingleOperator,\n onChangeOperator,\n}: {\n columnTitle: string;\n operator: CelOperator;\n allowedOperators: CelOperator[];\n hideOnSingleOperator?: boolean;\n onChangeOperator: (operator: CelOperator) => void;\n}) {\n if (allowedOperators.length > 1) {\n return (\n <Select value={operator} onValueChange={value => onChangeOperator(value as CelOperator)}>\n {/* role=\"combobox\" doesn't pick up child text as its accessible name\n the way a plain button would — an explicit aria-label is required,\n not just a nicety. */}\n <SelectTrigger aria-label={`${columnTitle} operator`} className={SEGMENT_SELECT_TRIGGER_CLASSNAME}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent position=\"popper\">\n <SelectGroup>\n {allowedOperators.map(op => (\n <SelectItem key={op} value={op}>\n {getOperatorLabel(op)}\n </SelectItem>\n ))}\n </SelectGroup>\n </SelectContent>\n </Select>\n );\n }\n if (allowedOperators.length === 1 && !hideOnSingleOperator) {\n return (\n <ButtonGroupText className=\"text-muted-foreground font-normal\">\n {getOperatorLabel(allowedOperators[0])}\n </ButtonGroupText>\n );\n }\n return null;\n}\n\n// ── Quantifier segment ─────────────────────────────────\n// multiText-only: \"any of\" / \"all of\" across a condition's tokens. Its own\n// plain Select segment appended right after the operator — not a switcher\n// living inside the value popover — with no search (only two options).\n// Hidden until there's more than one token, since quantifier is meaningless\n// (and unvalidated) for zero or one.\n\nfunction CelQuantifierSegment({\n columnTitle,\n value,\n onChangeValue,\n}: {\n columnTitle: string;\n value: MultiTextCelValue;\n onChangeValue: (value: MultiTextCelValue) => void;\n}) {\n if (value.tokens.length <= 1) return null;\n\n return (\n <Select\n value={value.quantifier ?? 'any'}\n onValueChange={next => {\n if (next === 'any' || next === 'all') onChangeValue({ ...value, quantifier: next });\n }}\n >\n {/* role=\"combobox\" doesn't pick up child text as its accessible name\n the way a plain button would — an explicit aria-label is required,\n not just a nicety. */}\n <SelectTrigger aria-label={`${columnTitle} quantifier`} className={SEGMENT_SELECT_TRIGGER_CLASSNAME}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent position=\"popper\">\n <SelectGroup>\n <SelectItem value=\"any\">{getQuantifierLabel('any')}</SelectItem>\n <SelectItem value=\"all\">{getQuantifierLabel('all')}</SelectItem>\n </SelectGroup>\n </SelectContent>\n </Select>\n );\n}\n\n// ── Checkbox pill (Combobox, multi-select) ────────────\n// Same Combobox composition as FilterChip's searchable branch in\n// filter-bar.tsx — Monarch's standing pattern for multi-select pickers.\n// A restricted (disabled) option is never blocked at the primitive level\n// (Base UI's own `disabled` would silently swallow the click, same failure\n// mode Radix's Checkbox has); instead every selection change is diffed\n// against the previous value and a newly-picked disabled option is reverted\n// and redirected to `onRestrictedOptionSelect`.\n\nfunction CelCheckboxComboboxPill({\n condition,\n columnDef,\n tree,\n onChange,\n controller,\n issues,\n onRemove,\n onRestrictedOptionSelect,\n}: {\n condition: CelFilterCondition;\n columnDef: CelColumnDefinition;\n tree: CelFilterBarProps['tree'];\n onChange: CelFilterBarProps['onChange'];\n controller: CelConditionEditorController;\n issues: CompileResult['issues'];\n onRemove: () => void;\n onRestrictedOptionSelect: CelFilterBarProps['onRestrictedOptionSelect'];\n}) {\n const options = columnDef.options ?? [];\n const value = isCheckboxCelValue(condition.value) ? condition.value : [];\n const selected = options.filter(option => value.includes(option.value));\n const allowedOperators = getAllowedOperators(columnDef);\n\n function updateOperator(operator: CelOperator) {\n onChange(replaceCondition(tree, condition.id, c => applyOperatorChange(c, operator, 'checkbox')));\n }\n\n function applySelection(nextSelected: CelColumnOption[]) {\n const current = new Set(value);\n const nextValues = new Set(nextSelected.map(option => option.value));\n for (const option of nextSelected) {\n if (!current.has(option.value) && option.disabled) {\n onRestrictedOptionSelect?.({ columnId: columnDef.id, value: option.value, label: option.label });\n nextValues.delete(option.value);\n }\n }\n onChange(replaceCondition(tree, condition.id, c => ({ ...c, value: Array.from(nextValues) })));\n const added = nextSelected.find(option => !current.has(option.value) && !option.disabled && option.operator);\n if (added?.operator) updateOperator(added.operator);\n }\n\n return (\n <Combobox\n items={options}\n itemToStringValue={(item: CelColumnOption) => item.label}\n multiple\n value={selected}\n onValueChange={(next: CelColumnOption[]) => applySelection(next)}\n open={controller.popoverVisible}\n onOpenChange={open => {\n if (open) controller.beginEditing();\n else if (!controller.isDismissSuppressed()) controller.handlePopoverDismiss();\n }}\n >\n <ButtonGroup>\n <ButtonGroupText>{columnDef.title}</ButtonGroupText>\n <CelOperatorSegment\n columnTitle={columnDef.title}\n operator={condition.operator}\n allowedOperators={allowedOperators}\n hideOnSingleOperator={columnDef.hideOnSingleOperator}\n onChangeOperator={updateOperator}\n />\n {/* role=\"combobox\" doesn't pick up child text as its accessible name\n the way a plain button would — an explicit aria-label is required,\n not just a nicety. */}\n <ComboboxTrigger\n aria-label={`${columnDef.title} value`}\n render={<Button variant=\"outline\" className=\"gap-1 font-normal [&>svg:last-child]:size-(--icon-sm)\" />}\n >\n <span className={cn(issues.length > 0 && 'text-destructive')}>\n {formatConditionSummary(condition, columnDef)}\n </span>\n </ComboboxTrigger>\n <Button variant=\"outline\" size=\"icon\" aria-label={`Remove ${columnDef.title} filter`} onClick={onRemove}>\n <Icon name=\"xmark\" />\n </Button>\n </ButtonGroup>\n <ComboboxContent className=\"min-w-64\" collisionAvoidance={{ side: 'none', align: 'shift' }}>\n <ComboboxInput showTrigger={false} placeholder={`Search ${columnDef.title.toLowerCase()}…`} />\n {selected.length > 0 && (\n <>\n <ComboboxSelectedChips>\n <ComboboxValue>\n {(items: CelColumnOption[]) => (\n <>\n {items.map(item => (\n <ComboboxChip key={item.value}>{item.label}</ComboboxChip>\n ))}\n </>\n )}\n </ComboboxValue>\n <ComboboxClearAll onClick={() => applySelection([])} />\n </ComboboxSelectedChips>\n <ComboboxSeparator />\n </>\n )}\n <ComboboxEmpty>No {columnDef.title.toLowerCase()} found.</ComboboxEmpty>\n <ComboboxList>\n {(item: CelColumnOption) => (\n <ComboboxItem key={item.value} value={item} className={cn(item.disabled && 'text-muted-foreground')}>\n {item.label}\n </ComboboxItem>\n )}\n </ComboboxList>\n {issues.length > 0 && (\n <p className=\"text-body-sm text-destructive\">{issues.map(issue => issue.message).join(' ')}</p>\n )}\n </ComboboxContent>\n </Combobox>\n );\n}\n\n// ── Radio pill (Combobox, single-select) ──────────────\n// Same primitive as the checkbox pill above, constrained to one selection by\n// omitting `multiple` — no chip strip (nothing to show but the one value,\n// already in the trigger), and a valid pick auto-commits (closes) like the\n// legacy RadioGroup did.\n\nfunction CelRadioComboboxPill({\n condition,\n columnDef,\n tree,\n onChange,\n controller,\n issues,\n onRemove,\n onRestrictedOptionSelect,\n}: {\n condition: CelFilterCondition;\n columnDef: CelColumnDefinition;\n tree: CelFilterBarProps['tree'];\n onChange: CelFilterBarProps['onChange'];\n controller: CelConditionEditorController;\n issues: CompileResult['issues'];\n onRemove: () => void;\n onRestrictedOptionSelect: CelFilterBarProps['onRestrictedOptionSelect'];\n}) {\n const options = columnDef.options ?? [];\n const value = typeof condition.value === 'string' ? condition.value : '';\n const selected = options.find(option => option.value === value) ?? null;\n const allowedOperators = getAllowedOperators(columnDef);\n\n function updateOperator(operator: CelOperator) {\n onChange(replaceCondition(tree, condition.id, c => applyOperatorChange(c, operator, 'radio')));\n }\n\n function applySelection(option: CelColumnOption | null) {\n if (!option) return;\n if (option.disabled) {\n onRestrictedOptionSelect?.({ columnId: columnDef.id, value: option.value, label: option.label });\n return;\n }\n onChange(replaceCondition(tree, condition.id, c => ({ ...c, value: option.value })));\n if (option.operator) updateOperator(option.operator);\n controller.commit();\n }\n\n return (\n <Combobox\n items={options}\n itemToStringValue={(item: CelColumnOption) => item.label}\n value={selected}\n onValueChange={(next: CelColumnOption | null) => applySelection(next)}\n open={controller.popoverVisible}\n onOpenChange={open => {\n if (open) controller.beginEditing();\n else if (!controller.isDismissSuppressed()) controller.handlePopoverDismiss();\n }}\n >\n <ButtonGroup>\n <ButtonGroupText>{columnDef.title}</ButtonGroupText>\n <CelOperatorSegment\n columnTitle={columnDef.title}\n operator={condition.operator}\n allowedOperators={allowedOperators}\n hideOnSingleOperator={columnDef.hideOnSingleOperator}\n onChangeOperator={updateOperator}\n />\n {/* role=\"combobox\" doesn't pick up child text as its accessible name\n the way a plain button would — an explicit aria-label is required,\n not just a nicety. */}\n <ComboboxTrigger\n aria-label={`${columnDef.title} value`}\n render={<Button variant=\"outline\" className=\"gap-1 font-normal [&>svg:last-child]:size-(--icon-sm)\" />}\n >\n <span className={cn(issues.length > 0 && 'text-destructive')}>\n {formatConditionSummary(condition, columnDef)}\n </span>\n </ComboboxTrigger>\n <Button variant=\"outline\" size=\"icon\" aria-label={`Remove ${columnDef.title} filter`} onClick={onRemove}>\n <Icon name=\"xmark\" />\n </Button>\n </ButtonGroup>\n <ComboboxContent className=\"min-w-64\" collisionAvoidance={{ side: 'none', align: 'shift' }}>\n <ComboboxInput showTrigger={false} placeholder={`Search ${columnDef.title.toLowerCase()}…`} />\n <ComboboxEmpty>No {columnDef.title.toLowerCase()} found.</ComboboxEmpty>\n <ComboboxList>\n {(item: CelColumnOption) => (\n <ComboboxItem key={item.value} value={item} className={cn(item.disabled && 'text-muted-foreground')}>\n {item.label}\n </ComboboxItem>\n )}\n </ComboboxList>\n {issues.length > 0 && (\n <p className=\"text-body-sm text-destructive\">{issues.map(issue => issue.message).join(' ')}</p>\n )}\n </ComboboxContent>\n </Combobox>\n );\n}\n\n// ── Text value editor ─────────────────────────────────\n\nfunction CelTextValueEditor({\n condition,\n onChangeValue,\n onCommit,\n}: {\n condition: CelFilterCondition;\n onChangeValue: (value: string) => void;\n onCommit: () => void;\n}) {\n const value = typeof condition.value === 'string' ? condition.value : '';\n\n return (\n <Input\n autoFocus\n value={value}\n placeholder=\"Enter a value…\"\n onChange={e => onChangeValue(e.target.value)}\n onKeyDown={e => {\n if (e.key === 'Enter') onCommit();\n }}\n />\n );\n}\n\n// ── MultiText value editor ────────────────────────────\n\nfunction CelMultiTextValueEditor({\n condition,\n onChangeValue,\n}: {\n condition: CelFilterCondition;\n onChangeValue: (value: MultiTextCelValue) => void;\n}) {\n const value = readMultiTextCelValue(condition.value);\n const [draft, setDraft] = React.useState('');\n\n function addToken() {\n const token = draft.trim();\n if (!token || value.tokens.includes(token)) {\n setDraft('');\n return;\n }\n const nextTokens = [...value.tokens, token];\n // Write an explicit quantifier the moment it first becomes relevant\n // (2nd token). CelQuantifierSegment's Select displays `quantifier ?? 'any'`\n // as its value, so if the user's first pick were \"any of\" — the same as\n // that visual default — Radix would see no change and never fire\n // onValueChange, leaving quantifier stuck undefined and the\n // missing_quantifier issue stuck showing despite the pill saying \"any of\".\n const quantifier = nextTokens.length > 1 ? (value.quantifier ?? 'any') : value.quantifier;\n onChangeValue({ ...value, tokens: nextTokens, quantifier });\n setDraft('');\n }\n\n function removeToken(token: string) {\n onChangeValue({ ...value, tokens: value.tokens.filter(t => t !== token) });\n }\n\n return (\n <div className=\"flex flex-col gap-2\">\n {value.tokens.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {value.tokens.map(token => (\n <Badge key={token} variant=\"secondary\" className=\"gap-1\">\n {token}\n <button\n type=\"button\"\n aria-label={`Remove ${token}`}\n onClick={() => removeToken(token)}\n className=\"cursor-pointer\"\n >\n <Icon name=\"xmark\" size=\"xs\" />\n </button>\n </Badge>\n ))}\n </div>\n )}\n <Input\n autoFocus\n value={draft}\n placeholder=\"Type a value, press Enter…\"\n onChange={e => setDraft(e.target.value)}\n onKeyDown={e => {\n if (e.key === 'Enter') {\n e.preventDefault();\n addToken();\n } else if (e.key === 'Backspace' && draft === '' && value.tokens.length > 0) {\n removeToken(value.tokens[value.tokens.length - 1]);\n }\n }}\n />\n </div>\n );\n}\n\n// ── KeyValue value editor ─────────────────────────────\n\nfunction CelKeyValueValueEditor({\n condition,\n onChangeValue,\n onCommit,\n}: {\n condition: CelFilterCondition;\n onChangeValue: (value: MapKeyCelValue) => void;\n onCommit: () => void;\n}) {\n const value = readMapKeyCelValue(condition.value);\n const needsValue = condition.operator === 'has_value' || condition.operator === 'does_not_have_value';\n\n return (\n <div className=\"flex flex-col gap-2\">\n <InputGroup>\n <InputGroupAddon>\n <InputGroupText>Key</InputGroupText>\n </InputGroupAddon>\n <InputGroupInput\n autoFocus\n value={value.key}\n onChange={e => onChangeValue({ ...value, key: e.target.value })}\n onKeyDown={e => {\n if (e.key === 'Enter' && !needsValue) onCommit();\n }}\n />\n </InputGroup>\n {needsValue && (\n <InputGroup>\n <InputGroupAddon>\n <InputGroupText>Value</InputGroupText>\n </InputGroupAddon>\n <InputGroupInput\n value={value.value ?? ''}\n onChange={e => onChangeValue({ ...value, value: e.target.value })}\n onKeyDown={e => {\n if (e.key === 'Enter') onCommit();\n }}\n />\n </InputGroup>\n )}\n </div>\n );\n}\n\n// ── Date value editor ──────────────────────────────────\n\nfunction CelDateValueEditor({\n condition,\n onChangeValue,\n}: {\n condition: CelFilterCondition;\n onChangeValue: (value: DateCelValue) => void;\n}) {\n const value = readDateCelValue(condition.value);\n const operator = condition.operator;\n const relativeCapable = isDateRelativeOperator(operator);\n const isRange = isDateRangeOperator(operator);\n const showTime = !isDateWindowOperator(operator) && !isRange;\n const isRelative = isRelativeDateCelValue(value);\n\n function pickInstant(date: Date | undefined) {\n if (!date) return;\n const boundary = dateBoundaryForOperator(operator);\n const instant = formatCalendarDateUtc(date, showTime ? boundary : 'start');\n onChangeValue({ instant });\n }\n\n function pickRange(range: DateRange | undefined) {\n if (!range?.from) return;\n const start = calendarDayStartInstant(formatCalendarDateUtc(range.from, 'start'));\n const end = range.to ? formatCalendarDateUtc(range.to, 'end') : formatCalendarDateUtc(range.from, 'end');\n onChangeValue({ range: { start, end } });\n }\n\n function pickTime(timeOfDay: string) {\n if (!value.instant) return;\n onChangeValue({ instant: withTimeOfDay(value.instant, timeOfDay), hasTime: true });\n }\n\n return (\n <div className=\"flex flex-col gap-2\">\n {/* No wrapping border here — PopoverContent already supplies the pill's\n single outer border/ring. A second border on this row would double\n up against it. `border-r` on the sidebar alone gives the divider. */}\n <div className=\"flex\">\n {relativeCapable && (\n <div className=\"flex flex-col gap-1 border-r pr-2\">\n <p className=\"text-body-sm text-muted-foreground px-2 font-medium\">Quick select</p>\n {RELATIVE_DURATION_PRESET_VALUES.map(preset => (\n <Button\n key={preset}\n type=\"button\"\n variant={isRelative && value.preset === preset ? 'secondary' : 'ghost'}\n size=\"sm\"\n className=\"justify-start\"\n onClick={() => onChangeValue({ preset })}\n >\n {RELATIVE_PRESET_LABELS[preset]}\n </Button>\n ))}\n </div>\n )}\n {isRange ? (\n <Calendar\n mode=\"range\"\n selected={\n value.range\n ? { from: parseCalendarDate(value.range.start), to: parseCalendarDate(value.range.end) }\n : undefined\n }\n onSelect={pickRange}\n />\n ) : (\n <Calendar\n mode=\"single\"\n selected={isRelative ? undefined : parseCalendarDate(value.instant)}\n onSelect={pickInstant}\n />\n )}\n </div>\n {showTime && !isRelative && (\n <div className=\"flex w-full items-center gap-2\">\n <Label htmlFor=\"cel-date-time\" className=\"text-body-sm text-muted-foreground shrink-0\">\n Time (UTC)\n </Label>\n <Input\n id=\"cel-date-time\"\n type=\"time\"\n className=\"w-full\"\n value={readTimeOfDay(value.instant)}\n onChange={e => pickTime(e.target.value)}\n disabled={!value.instant}\n />\n </div>\n )}\n </div>\n );\n}\n\nexport { CelFilterBar };\n","import { useCallback, useRef, useState } from 'react';\n\nimport { ADD_FILTER_POPOVER_SUPPRESS_MS } from '@/lib/cel-filter/constants';\nimport type { PillActiveSurface } from '@/lib/cel-filter/types';\n\nexport type CelConditionEditorController = {\n isDraft: boolean;\n activeSurface: PillActiveSurface | null;\n popoverVisible: boolean;\n isDismissSuppressed: () => boolean;\n\n beginEditing: () => void;\n openSurface: (surface: PillActiveSurface) => void;\n closeSurface: () => void;\n commit: () => void;\n handlePopoverDismiss: () => void;\n toggleSurface: (surface: PillActiveSurface) => void;\n};\n\nexport type UseCelFilterEditorStateResult = {\n editingConditionId: string | null;\n activeSurface: PillActiveSurface | null;\n committedConditionIds: Set<string>;\n getController: (conditionId: string) => CelConditionEditorController;\n beginEditing: (id: string, surface?: PillActiveSurface) => void;\n suppressDismissFor: (id: string, ms?: number) => void;\n removeCondition: (id: string) => void;\n clearSuppress: () => void;\n};\n\n/**\n * Single source of truth for CEL filter draft/commit, active pill segment,\n * and Radix dismiss-suppression (post-add guard + segment switches).\n */\nexport function useCelFilterEditorState(initialCommittedIds: string[] = []): UseCelFilterEditorStateResult {\n const [editingConditionId, setEditingConditionId] = useState<string | null>(null);\n const [committedConditionIds, setCommittedConditionIds] = useState<Set<string>>(() => new Set(initialCommittedIds));\n const [activeSurface, setActiveSurface] = useState<PillActiveSurface | null>(null);\n\n const suppressCloseUntilRef = useRef<{ id: string; until: number } | null>(null);\n const segmentSwitchRef = useRef(false);\n\n const isDismissSuppressed = useCallback((id: string) => {\n const entry = suppressCloseUntilRef.current;\n return entry !== null && entry.id === id && Date.now() < entry.until;\n }, []);\n\n const commitCondition = useCallback((id: string) => {\n setCommittedConditionIds(prev => {\n if (prev.has(id)) {\n return prev;\n }\n const next = new Set(prev);\n next.add(id);\n return next;\n });\n setEditingConditionId(current => (current === id ? null : current));\n setActiveSurface(null);\n segmentSwitchRef.current = false;\n }, []);\n\n const beginEditing = useCallback((id: string, surface: PillActiveSurface = 'value') => {\n setEditingConditionId(id);\n setActiveSurface(surface);\n }, []);\n\n const openSurface = useCallback(\n (id: string, surface: PillActiveSurface) => {\n if (editingConditionId !== id) {\n beginEditing(id, surface);\n return;\n }\n setActiveSurface(surface);\n },\n [beginEditing, editingConditionId],\n );\n\n const closeSurface = useCallback(\n (id: string) => {\n if (editingConditionId === id) {\n setActiveSurface(null);\n }\n },\n [editingConditionId],\n );\n\n const handlePopoverDismiss = useCallback(\n (id: string) => {\n if (segmentSwitchRef.current) {\n segmentSwitchRef.current = false;\n return;\n }\n if (isDismissSuppressed(id)) {\n return;\n }\n suppressCloseUntilRef.current = null;\n commitCondition(id);\n },\n [commitCondition, isDismissSuppressed],\n );\n\n const toggleSurface = useCallback(\n (id: string, surface: PillActiveSurface) => {\n const isDraft = editingConditionId === id;\n const popoverVisible = isDraft && activeSurface !== null;\n\n if (isDraft && activeSurface === surface && popoverVisible) {\n closeSurface(id);\n return;\n }\n if (popoverVisible && activeSurface !== surface) {\n segmentSwitchRef.current = true;\n }\n openSurface(id, surface);\n },\n [activeSurface, closeSurface, editingConditionId, openSurface],\n );\n\n const suppressDismissFor = useCallback((id: string, ms = ADD_FILTER_POPOVER_SUPPRESS_MS) => {\n suppressCloseUntilRef.current = {\n id,\n until: Date.now() + ms,\n };\n }, []);\n\n const removeCondition = useCallback(\n (id: string) => {\n if (suppressCloseUntilRef.current?.id === id) {\n suppressCloseUntilRef.current = null;\n }\n setCommittedConditionIds(prev => {\n if (!prev.has(id)) {\n return prev;\n }\n const next = new Set(prev);\n next.delete(id);\n return next;\n });\n setEditingConditionId(current => (current === id ? null : current));\n if (editingConditionId === id) {\n setActiveSurface(null);\n segmentSwitchRef.current = false;\n }\n },\n [editingConditionId],\n );\n\n const clearSuppress = useCallback(() => {\n suppressCloseUntilRef.current = null;\n }, []);\n\n const getController = useCallback(\n (conditionId: string): CelConditionEditorController => {\n const isDraft = editingConditionId === conditionId;\n const surface = isDraft ? activeSurface : null;\n\n return {\n isDraft,\n activeSurface: surface,\n popoverVisible: isDraft && activeSurface !== null,\n isDismissSuppressed: () => isDismissSuppressed(conditionId),\n beginEditing: () => beginEditing(conditionId),\n openSurface: s => openSurface(conditionId, s),\n closeSurface: () => closeSurface(conditionId),\n commit: () => {\n suppressCloseUntilRef.current = null;\n commitCondition(conditionId);\n },\n handlePopoverDismiss: () => handlePopoverDismiss(conditionId),\n toggleSurface: s => toggleSurface(conditionId, s),\n };\n },\n [\n activeSurface,\n beginEditing,\n closeSurface,\n commitCondition,\n editingConditionId,\n handlePopoverDismiss,\n isDismissSuppressed,\n openSurface,\n toggleSurface,\n ],\n );\n\n return {\n editingConditionId,\n activeSurface,\n committedConditionIds,\n getController,\n beginEditing,\n suppressDismissFor,\n removeCondition,\n clearSuppress,\n };\n}\n","/**\n * Shared limits and defaults for the CEL filter builder. Values mirror the API\n * constraints (`maxNestingDepth = 50`, `maxRegexLen = 1000`).\n */\nimport type { RelativeDurationPreset } from './types';\n\n/**\n * Trusted relative date presets emitted as fixed `duration(...)` literals in\n * compiled CEL. Hours only — `duration()` rejects a `d` unit.\n */\nexport const RELATIVE_DURATION_PRESET_VALUES = [\n '24h',\n '168h',\n '720h',\n] as const satisfies readonly RelativeDurationPreset[];\n\nexport const RELATIVE_DURATION_PRESETS = new Set<string>(RELATIVE_DURATION_PRESET_VALUES);\n\nexport function isRelativeDurationPreset(value: string): value is RelativeDurationPreset {\n return RELATIVE_DURATION_PRESETS.has(value);\n}\n\n/** API recursion depth limit for nested parentheses. v1 UI is flat; the compiler enforces this defensively. */\nexport const MAX_NESTING_DEPTH = 50;\n\n/** Maximum length of a `matches` regex pattern accepted by the API. */\nexport const MAX_REGEX_LEN = 1000;\n\n/** Debounce for inline free-text (regex) validation inside an open popover. */\nexport const CEL_VALIDATION_DEBOUNCE_MS = 300;\n\n/** Default quantifier when a multiText condition has more than one token. */\nexport const DEFAULT_MULTI_TEXT_QUANTIFIER = 'any' as const;\n\n/**\n * After adding a filter from the dropdown, ignore outside-dismiss on the new\n * pill popover for this long. Covers the menu closing plus immediate pointer\n * movement that Radix treats as an outside interaction.\n */\nexport const ADD_FILTER_POPOVER_SUPPRESS_MS = 500;\n\n/** Keys handled by searchable CEL dropdown listboxes; others stop propagation from the search input. */\nexport const CEL_DROPDOWN_NAV_KEYS = [\n 'ArrowUp',\n 'ArrowDown',\n 'ArrowLeft',\n 'ArrowRight',\n 'Enter',\n 'Escape',\n 'Tab',\n] as const;\n","/**\n * Instant helpers for the CEL date filter.\n *\n * Stored values are RFC3339 UTC strings, and everything here manipulates them as\n * text rather than through `Date`, so a filter can never drift into the viewer's\n * local timezone. Tables render timestamps in UTC, so a UTC filter is what\n * agrees with the times shown in the table.\n */\n\n/** Which end of a day/minute an instant represents. */\nexport type DateBoundary = 'start' | 'end';\n\n/** How much of the instant the user has committed to: a calendar day, or a wall-clock minute. */\nexport type DateInstantGranularity = 'day' | 'minute';\n\n/** Time an `input[type=\"time\"]` shows for a boundary the user has not edited. */\nexport const BOUNDARY_TIME_OF_DAY: Record<DateBoundary, string> = {\n start: '00:00',\n end: '23:59',\n};\n\nconst CALENDAR_DAY_PATTERN = /^(\\d{4}-\\d{2}-\\d{2})/;\nconst MINUTE_PATTERN = /^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2})/;\nconst TIME_OF_DAY_PATTERN = /^\\d{4}-\\d{2}-\\d{2}T(\\d{2}:\\d{2})/;\n\nexport function calendarDayStartInstant(instant: string): string {\n const match = CALENDAR_DAY_PATTERN.exec(instant);\n return match ? `${match[1]}T00:00:00.000Z` : instant;\n}\n\n/**\n * Derives the inclusive upper bound of a stored instant. An upper bound covers\n * the whole unit the user selected: a day runs through 23:59:59.999, a minute\n * through :59.999 — the same rule, one unit finer.\n */\nexport function inclusiveEndInstant(instant: string, granularity: DateInstantGranularity): string {\n if (granularity === 'minute') {\n const minuteMatch = MINUTE_PATTERN.exec(instant);\n return minuteMatch ? `${minuteMatch[1]}:59.999Z` : instant;\n }\n const match = CALENDAR_DAY_PATTERN.exec(instant);\n return match ? `${match[1]}T23:59:59.999Z` : instant;\n}\n\n/** Derives inclusive end-of-day RFC3339 from a stored start instant. */\nexport function calendarDayEndInstant(startInstant: string): string {\n return inclusiveEndInstant(startInstant, 'day');\n}\n\nexport function startInstantFromEndOfDay(endInstant: string): string {\n const match = CALENDAR_DAY_PATTERN.exec(endInstant);\n return match ? `${match[1]}T00:00:00Z` : endInstant;\n}\n\n/** Strips the `:59.999` an inclusive minute bound was expanded with. */\nexport function startInstantFromEndOfMinute(endInstant: string): string {\n const match = MINUTE_PATTERN.exec(endInstant);\n return match ? `${match[1]}:00.000Z` : endInstant;\n}\n\nexport function isEndOfDayTimestamp(instant: string): boolean {\n return /T23:59:59(\\.\\d+)?Z$/.test(instant);\n}\n\nexport function isStartOfDayTimestamp(instant: string): boolean {\n return /T00:00:00(\\.0+)?Z$/.test(instant);\n}\n\n/**\n * True for an instant expanded to the end of its minute. End-of-day is also\n * end-of-minute, so callers that distinguish the two must test for day first.\n */\nexport function isEndOfMinuteTimestamp(instant: string): boolean {\n return /T\\d{2}:\\d{2}:59(\\.\\d+)?Z$/.test(instant);\n}\n\n/**\n * True when the date portion names a day that exists. `Date` rolls impossible\n * days over silently — Feb 31 becomes Mar 3 rather than failing — so a\n * round-trip through UTC is what separates a real day from a rolled-over one.\n */\nexport function isRealCalendarDay(instant: string): boolean {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(instant);\n if (!match) {\n return false;\n }\n const [year, month, day] = [Number(match[1]), Number(match[2]), Number(match[3])];\n const date = new Date(Date.UTC(year, month - 1, day));\n return date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day;\n}\n\n/** Reads the `HH:mm` an `input[type=\"time\"]` displays for a stored instant. */\nexport function readTimeOfDay(instant: string | undefined): string {\n if (!instant) {\n return '';\n }\n const match = TIME_OF_DAY_PATTERN.exec(instant);\n return match ? match[1] : '';\n}\n\n/** Replaces the time portion of an instant. Seconds are zeroed — the input is minute-granular. */\nexport function withTimeOfDay(instant: string, timeOfDay: string): string {\n const day = CALENDAR_DAY_PATTERN.exec(instant);\n const time = /^(\\d{2}):(\\d{2})/.exec(timeOfDay);\n if (!day || !time) {\n return instant;\n }\n return `${day[1]}T${time[1]}:${time[2]}:00.000Z`;\n}\n\n/**\n * Stamps a picked calendar day as a UTC instant. The picker hands back a local\n * `Date` whose Y/M/D is the day that was clicked; that day is stored as the\n * matching UTC day so the filter lines up with the UTC timestamps in the table.\n */\nexport function formatCalendarDateUtc(date: Date, boundary: DateBoundary): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const time = boundary === 'end' ? 'T23:59:59.999Z' : 'T00:00:00.000Z';\n return `${year}-${month}-${day}${time}`;\n}\n\n/** Parses a stored RFC3339 string back into a local Date carrying the calendar day. */\nexport function parseCalendarDate(value: string | undefined): Date | undefined {\n if (!value) {\n return undefined;\n }\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(value);\n if (!match) {\n return undefined;\n }\n return new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3]));\n}\n\n/**\n * Locale date for display, plus the UTC time when the instant carries a\n * user-picked one. `locale` defaults to the runtime's own locale (matching\n * plain `toLocaleDateString()`) — callers rendered during SSR should pass a\n * fixed locale explicitly (see `cel-filter-bar.tsx`'s `useMounted()` gating)\n * so the server-rendered/first-paint value doesn't hydration-mismatch against\n * the viewer's actual browser locale.\n */\nexport function formatInstantLabel(\n instant: string | undefined,\n { withTime = false, locale }: { withTime?: boolean; locale?: string } = {},\n): string {\n const date = parseCalendarDate(instant);\n if (!date) {\n return '';\n }\n const dateLabel = date.toLocaleDateString(locale);\n const timeOfDay = withTime ? readTimeOfDay(instant) : '';\n return timeOfDay ? `${dateLabel} ${timeOfDay} UTC` : dateLabel;\n}\n","/** Stable operator ids used in code and tests. UI labels come from `getOperatorLabel`. */\nexport type CelOperator =\n | 'is'\n | 'is_not'\n | 'contains'\n | 'does_not_contain'\n | 'starts_with'\n | 'ends_with'\n | 'matches'\n | 'is_before'\n | 'is_after'\n | 'is_on_or_before'\n | 'is_on_or_after'\n | 'is_between'\n | 'is_not_between'\n | 'key_exists'\n | 'key_does_not_exist'\n | 'has_value'\n | 'does_not_have_value';\n\nexport type CelFilterType = 'checkbox' | 'radio' | 'text' | 'multiText' | 'date' | 'keyValue' | 'static';\n\n/** When a valid compiled expression may be emitted to consumers (API, URL, etc.). */\nexport type CelEmitOn = 'change' | 'commit';\n\n/**\n * Resolved shape used by the compiler / dispatcher to pick a value variant and\n * operator set. Columns map to their `filterType`; map fields resolve to `map`.\n */\nexport type CelFilterShape = CelFilterType | 'map';\n\nexport type CelColumnOption = {\n /** Human-readable text shown in the UI and collapsed pill display. Never compiled into CEL. */\n label: string;\n /** Canonical CEL literal stored on the condition and emitted in compiled CEL. */\n value: string;\n /** When set, selecting this option also sets the condition operator (e.g. `'is_not'` for a negated choice). */\n operator?: CelOperator;\n /** When true, the option cannot be toggled; hosts may handle the click via `onRestrictedOptionSelect`. */\n disabled?: boolean;\n};\n\n/** Payload for clicks on disabled checkbox/radio options. */\nexport type CelRestrictedOptionSelectPayload = {\n columnId: string;\n value: string;\n label: string;\n};\n\nexport type CelColumnDefinition = {\n /** Must match the API column id when targeting server-side resources. */\n id: string;\n /** Display name in the add-filter menu. */\n title: string;\n /**\n * Section heading this column is listed under in the add-filter menu. Sections appear in the\n * order each group name first occurs in `columns`; columns without a group are listed last\n * under no heading. Omit on every column to get a single flat alphabetical list.\n *\n * Group names are searchable: a phrase matching one keeps that entire section, on top of any\n * columns matched by title.\n */\n group?: string;\n /** Lowercase natural plural for consolidated multi-value pill copy (e.g. \"2 control planes\"). */\n pluralTitle: string;\n filterType: CelFilterType;\n /** Enum columns (checkbox / radio); static options only in v1. */\n options?: CelColumnOption[];\n /** Optional override; defaults from `filterType`. */\n allowedOperators?: CelOperator[];\n /** When true, hides the operator UI when only one operator is allowed. Defaults to `false`. */\n hideOnSingleOperator?: boolean;\n /** Pre-fill value when the condition is first added. Skips the initial \"pick a value\" step. */\n defaultValue?: CelConditionValue;\n /** When a valid compiled expression may be emitted. Defaults by `filterType`. */\n emitOn?: CelEmitOn;\n};\n\n/** Host-provided schema describing which columns are filterable for a given filter bar. */\nexport type CelFilterSchema = {\n columns: CelColumnDefinition[];\n};\n\n// --- Value shapes -----------------------------------------------------------\n\nexport type CheckboxCelValue = string[];\n\nexport type RadioCelValue = string;\n\nexport type TextCelValue = string;\n\nexport type MultiTextCelValue = {\n tokens: string[];\n /** Required when `tokens.length > 1`; defaults to `any` in the UI when omitted. */\n quantifier?: 'any' | 'all';\n};\n\n/** Trusted preset durations emitted as fixed literals in compiled CEL. */\nexport type RelativeDurationPreset = '24h' | '168h' | '720h';\n\nexport type DateCelValue = {\n /** RFC3339 UTC; required for single-point comparators. Mutually exclusive with `preset`. */\n instant?: string;\n /** Required for the range operators (`is_between` / `is_not_between`). Mutually exclusive with `preset`. */\n range?: {\n start: string;\n end: string;\n };\n /** Relative duration preset; mutually exclusive with `instant` / `range`. */\n preset?: RelativeDurationPreset;\n /**\n * True once the user edits a boundary time. While false the operator's default\n * day boundary applies, so an untouched condition compiles exactly as it did\n * before times were selectable. Never set without `instant` / `range` — the\n * `isDateCelValue` guard keys off those fields. Never compiled into CEL; a\n * future parser would need to re-derive it from the instants in the expression.\n */\n hasTime?: boolean;\n};\n\nexport type MapKeyCelValue = {\n key: string;\n /** Required when operator is `has_value` / `does_not_have_value`. */\n value?: string;\n};\n\n/**\n * Union of all condition value shapes. The active variant is determined by the\n * condition's `columnId` + schema `filterType`, not a discriminant on the value.\n */\nexport type CelConditionValue =\n CheckboxCelValue | RadioCelValue | TextCelValue | MultiTextCelValue | DateCelValue | MapKeyCelValue;\n\n// --- Tree nodes -------------------------------------------------------------\n\n/**\n * v1 always `and`; the shape is forward-compatible with `or` and nesting.\n * See `CelFilterGroup.children`, kept recursive so a future nested/OR-group UI\n * is additive rather than a breaking type change.\n */\nexport type CelCombinator = 'and';\n\nexport type CelFilterGroup = {\n id: string;\n type: 'group';\n combinator: CelCombinator;\n /** Root group is `0`. */\n depth: number;\n children: CelFilterNode[];\n};\n\nexport type CelFilterCondition = {\n id: string;\n type: 'condition';\n columnId: string;\n operator: CelOperator;\n /** Undefined on a newly added row until the user edits. */\n value?: CelConditionValue;\n};\n\nexport type CelFilterNode = CelFilterGroup | CelFilterCondition;\n\nexport type CelFilterTree = {\n root: CelFilterGroup;\n};\n\n// --- Validation -------------------------------------------------------------\n\n/** Closed union — `validateCondition` and `compileCelFilterTree` emit only these codes. */\nexport type ValidationIssueCode =\n // incomplete\n | 'missing_column'\n | 'missing_value'\n | 'missing_key'\n | 'missing_tokens'\n | 'missing_quantifier'\n | 'missing_instant'\n | 'missing_range'\n | 'missing_duration'\n // invalid\n | 'unknown_column'\n | 'illegal_operator'\n | 'invalid_date_mode'\n | 'regex_too_long'\n | 'invalid_timestamp'\n | 'invalid_date_range'\n | 'nesting_depth_exceeded';\n\nexport type ValidationSeverity = 'incomplete' | 'invalid';\n\nexport type ValidationIssue = {\n code: ValidationIssueCode;\n message: string;\n severity: ValidationSeverity;\n nodeId: string;\n nodeType: 'condition' | 'group';\n /** Sub-target within the condition (e.g. `value`, `key`, `instant`). */\n field?: string;\n};\n\nexport type CompileStatus = 'valid' | 'incomplete' | 'invalid';\n\nexport type CompileResult = {\n status: CompileStatus;\n /** Present when `status === 'valid'` (may be `\"\"`). */\n expression?: string;\n issues: ValidationIssue[];\n /** True iff the raw compile status is `valid`; the API / parent emission gate. */\n isEmitReady: boolean;\n};\n\n// --- Validation meta (draft / commit tracking) ------------------------------\n\nexport type CelValidationMeta = {\n editingConditionId: string | null;\n committedConditionIds: Set<string>;\n};\n\n/** Which pill sub-surface is open: operator picker, multiText quantifier, or the value editor. */\nexport type PillActiveSurface = 'operator' | 'quantifier' | 'value';\n\n// --- Public builder API -----------------------------------------------------\n\nexport type CelFilterBarProps = {\n tree: CelFilterTree;\n onChange: (tree: CelFilterTree) => void;\n schema: CelFilterSchema;\n onCompileResultChange?: (result: CompileResult) => void;\n /** Invoked when the user clicks a disabled option (instead of toggling the filter value). */\n onRestrictedOptionSelect?: (payload: CelRestrictedOptionSelectPayload) => void;\n /** Default `false`. */\n showClearButton?: boolean;\n className?: string;\n};\n\n// --- Type guards ------------------------------------------------------------\n\nexport const isCelFilterGroup = (node: CelFilterNode): node is CelFilterGroup => node.type === 'group';\n\nexport const isCelFilterCondition = (node: CelFilterNode): node is CelFilterCondition => node.type === 'condition';\n\n/** Checkbox values are arrays of option value strings. */\nexport const isCheckboxCelValue = (value: unknown): value is CheckboxCelValue =>\n Array.isArray(value) && value.every(item => typeof item === 'string');\n\n/** Radio / text values are bare strings. */\nexport const isStringCelValue = (value: unknown): value is string => typeof value === 'string';\n\nexport const isMultiTextCelValue = (value: unknown): value is MultiTextCelValue =>\n typeof value === 'object' && value !== null && 'tokens' in value;\n\nexport const isDateCelValue = (value: unknown): value is DateCelValue => {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n if ('tokens' in value || 'key' in value) {\n return false;\n }\n return 'preset' in value || 'instant' in value || 'range' in value || Object.keys(value).length === 0;\n};\n\nexport const isMapKeyCelValue = (value: unknown): value is MapKeyCelValue =>\n typeof value === 'object' && value !== null && 'key' in value;\n","import {\n type DateCelValue,\n isDateCelValue,\n isMapKeyCelValue,\n isMultiTextCelValue,\n type MapKeyCelValue,\n type MultiTextCelValue,\n} from './types';\n\n/** Relative when a preset is set; preset and absolute fields are mutually exclusive. */\nexport function isRelativeDateCelValue(value: DateCelValue): boolean {\n return value.preset != null;\n}\n\nexport function readDateCelValue(value: unknown): DateCelValue {\n return isDateCelValue(value) ? value : {};\n}\n\nexport function readMapKeyCelValue(value: unknown): MapKeyCelValue {\n return isMapKeyCelValue(value) ? value : { key: '' };\n}\n\nexport function readMultiTextCelValue(value: unknown): MultiTextCelValue {\n return isMultiTextCelValue(value) ? value : { tokens: [] };\n}\n","/**\n * Escapes a user-provided string literal for safe embedding inside a CEL\n * double-quoted string. Callers wrap the result in `\"...\"` at the use site\n * (e.g. `column == \"${escapeCelString(value)}\"`).\n *\n * CEL generated output uses double-quoted strings only, so single quotes are\n * left untouched.\n */\nexport function escapeCelString(input: string): string {\n let out = '';\n\n for (const char of input) {\n switch (char) {\n case '\\\\':\n out += '\\\\\\\\';\n break;\n case '\"':\n out += '\\\\\"';\n break;\n case '\\n':\n out += '\\\\n';\n break;\n case '\\r':\n out += '\\\\r';\n break;\n case '\\t':\n out += '\\\\t';\n break;\n case '\\f':\n out += '\\\\f';\n break;\n case '\\v':\n out += '\\\\v';\n break;\n case '\\b':\n out += '\\\\b';\n break;\n case '\\0':\n out += '\\\\0';\n break;\n default:\n out += char;\n }\n }\n\n return out;\n}\n\n/** Convenience helper that escapes and wraps a value in double quotes. */\nexport function celStringLiteral(input: string): string {\n return `\"${escapeCelString(input)}\"`;\n}\n","/**\n * Operator metadata and CEL fragment generation.\n *\n * This is the single place that knows how `condition.operator` + value map to CEL\n * output. UI components never hand-write CEL — they read/write tree state and the\n * compiler walks it through here.\n */\nimport { type DateBoundary, inclusiveEndInstant } from '../date-utils';\nimport {\n type CelColumnDefinition,\n type CelFilterCondition,\n type CelFilterSchema,\n type CelFilterShape,\n type CelFilterType,\n type CelOperator,\n type DateCelValue,\n isDateCelValue,\n isMapKeyCelValue,\n type MapKeyCelValue,\n type MultiTextCelValue,\n} from '../types';\nimport { isRelativeDateCelValue } from '../value-utils';\nimport { celStringLiteral } from './escape-cel-string';\n\n/** Schema column ids that collide with CEL reserved words (in the CEL library leveraged), mapped to safe CEL identifiers. */\nconst RESERVED_COLUMN_CEL_IDENTIFIERS: Record<string, string> = {\n namespace: '__namespace__',\n};\n\nconst CEL_IDENTIFIER_TO_COLUMN_ID = Object.fromEntries(\n Object.entries(RESERVED_COLUMN_CEL_IDENTIFIERS).map(([columnId, celIdentifier]) => [celIdentifier, columnId]),\n);\n\nconst RESERVED_FIELD_OPERATOR_PATTERN = '(?=\\\\s*(?:in\\\\b|==|!=|<=|>=|<|>|\\\\.))';\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n// --- Allowed operator sets --------------------------------------------------\n\nconst ENUM_OPERATORS: CelOperator[] = ['is', 'is_not'];\nconst TEXT_OPERATORS: CelOperator[] = [\n 'is',\n 'is_not',\n 'contains',\n 'does_not_contain',\n 'starts_with',\n 'ends_with',\n 'matches',\n];\nconst DATE_OPERATORS: CelOperator[] = [\n 'is',\n 'is_not',\n 'is_before',\n 'is_after',\n 'is_on_or_before',\n 'is_on_or_after',\n 'is_between',\n 'is_not_between',\n];\nconst MAP_OPERATORS: CelOperator[] = ['key_exists', 'key_does_not_exist', 'has_value', 'does_not_have_value'];\n\n/** Date comparators legal with a relative preset. */\nconst DATE_RELATIVE_OPERATORS: CelOperator[] = ['is_before', 'is_after', 'is_on_or_before', 'is_on_or_after'];\n\n/** Date operators that span a whole calendar day rather than compare against one instant. */\nconst DATE_WINDOW_OPERATORS: CelOperator[] = ['is', 'is_not'];\n\n/** Date operators that take a start/end range instead of a single instant. */\nconst DATE_RANGE_OPERATORS: CelOperator[] = ['is_between', 'is_not_between'];\n\n/**\n * Comparators whose bound sits at the end of the selected day/minute: \"on or\n * before Jul 23\" runs through 23:59:59.999, and \"after Jul 23\" starts once that\n * same instant has passed.\n */\nconst DATE_END_BOUNDARY_OPERATORS: CelOperator[] = ['is_on_or_before', 'is_after'];\n\nconst MAP_VALUE_OPERATORS: CelOperator[] = ['has_value', 'does_not_have_value'];\n\n/** Returns the operators allowed for a resolved filter shape. */\nexport function getAllowedOperatorsForShape(shape: CelFilterShape): CelOperator[] {\n switch (shape) {\n case 'checkbox':\n case 'radio':\n case 'static':\n return ENUM_OPERATORS;\n case 'text':\n case 'multiText':\n return TEXT_OPERATORS;\n case 'date':\n return DATE_OPERATORS;\n case 'map':\n return MAP_OPERATORS;\n default:\n return [];\n }\n}\n\n/**\n * Returns the operators allowed for a column. `allowedOperators` on a column\n * definition overrides the default set derived from its filter type.\n */\nexport function getAllowedOperators(columnDef?: CelColumnDefinition): CelOperator[] {\n if (!columnDef) {\n return [];\n }\n if (columnDef.allowedOperators) {\n return columnDef.allowedOperators;\n }\n const shape = columnDef.filterType === 'keyValue' ? 'map' : columnDef.filterType;\n return getAllowedOperatorsForShape(shape);\n}\n\nexport function isDateRelativeOperator(operator: CelOperator): boolean {\n return DATE_RELATIVE_OPERATORS.includes(operator);\n}\n\n/** True for the date operators that match a whole calendar day and so take no time. */\nexport function isDateWindowOperator(operator: CelOperator): boolean {\n return DATE_WINDOW_OPERATORS.includes(operator);\n}\n\n/** True for the date operators whose value is a `range` rather than an `instant`. */\nexport function isDateRangeOperator(operator: CelOperator): boolean {\n return DATE_RANGE_OPERATORS.includes(operator);\n}\n\n/**\n * Which day boundary a date comparator compares against, and therefore the time\n * its input prefills with until the user edits it.\n */\nexport function dateBoundaryForOperator(operator: CelOperator): DateBoundary {\n return DATE_END_BOUNDARY_OPERATORS.includes(operator) ? 'end' : 'start';\n}\n\n// --- Schema resolution helpers ---------------------------------------------\n\nexport function resolveColumnDefinition(\n condition: Pick<CelFilterCondition, 'columnId'>,\n schema: CelFilterSchema,\n): CelColumnDefinition | undefined {\n if (!condition.columnId) {\n return undefined;\n }\n return schema.columns.find(column => column.id === condition.columnId);\n}\n\n/** Resolves the value/operator shape for a condition, or `undefined` for an unknown column. */\nexport function resolveFilterShape(\n condition: Pick<CelFilterCondition, 'columnId' | 'value'>,\n schema: CelFilterSchema,\n): CelFilterShape | undefined {\n const columnDef = resolveColumnDefinition(condition, schema);\n if (!columnDef) {\n return undefined;\n }\n if (columnDef.filterType === 'keyValue') {\n return 'map';\n }\n if (columnDef.filterType === 'static') {\n return Array.isArray(condition.value) ? 'checkbox' : 'radio';\n }\n return columnDef.filterType;\n}\n\n// --- Operator labels --------------------------------------------------------\n\nconst OPERATOR_LABELS: Record<CelOperator, string> = {\n is: 'is',\n is_not: 'is not',\n contains: 'contains',\n does_not_contain: 'does not contain',\n starts_with: 'starts with',\n ends_with: 'ends with',\n matches: 'matches',\n is_before: 'is before',\n is_after: 'is after',\n is_on_or_before: 'is on or before',\n is_on_or_after: 'is on or after',\n is_between: 'is between',\n is_not_between: 'is not between',\n key_exists: 'key exists',\n key_does_not_exist: 'key does not exist',\n has_value: 'has value',\n does_not_have_value: 'does not have value',\n};\n\nexport function getOperatorLabel(operator: CelOperator): string {\n return OPERATOR_LABELS[operator];\n}\n\nexport function getQuantifierLabel(quantifier: 'any' | 'all'): string {\n return quantifier === 'all' ? 'all of' : 'any of';\n}\n\n// --- Multi-instance ---------------------------------------------------------\n\nconst SINGLE_INSTANCE_FILTER_TYPES: Set<CelFilterType> = new Set(['checkbox', 'radio', 'static']);\n\nexport function allowsMultipleConditions(filterType: CelFilterType): boolean {\n return !SINGLE_INSTANCE_FILTER_TYPES.has(filterType);\n}\n\n// --- Default operator on add -----------------------------------------------\n\nexport function getDefaultOperator(filterType: CelFilterType): CelOperator {\n switch (filterType) {\n case 'checkbox':\n case 'radio':\n case 'text':\n case 'static':\n return 'is';\n case 'multiText':\n return 'contains';\n case 'date':\n return 'is';\n case 'keyValue':\n return 'key_exists';\n default:\n return 'is';\n }\n}\n\n// --- Operator change value retention ----------------------------------------\n\n/**\n * Applies the minimal value-retention rules when the operator changes on an\n * existing condition. Returns a new condition; does not mutate the input.\n *\n * For dates, the clearing rules here are the enforcement half of the date state\n * machine the date editor implements: clear when the value shape changes (range\n * operators vs single-instant ones), or when a relative value would become\n * illegal under `is`/`is_not`, and drop a picked time when moving to a\n * whole-day operator. Keep both in sync.\n */\nexport function applyOperatorChange(\n condition: CelFilterCondition,\n newOperator: CelOperator,\n shape: CelFilterShape | undefined,\n): CelFilterCondition {\n const next: CelFilterCondition = { ...condition, operator: newOperator };\n const oldOperator = condition.operator;\n\n if (shape === 'date') {\n const value = condition.value;\n const isRelative = isDateCelValue(value) && isRelativeDateCelValue(value);\n // `is_between` ↔ `is_not_between` keep the range; swapping between a range\n // operator and a single-instant one cannot reuse the value.\n const changesValueShape = isDateRangeOperator(oldOperator) !== isDateRangeOperator(newOperator);\n const relativeNeedsClear = isRelative && (newOperator === 'is' || newOperator === 'is_not');\n\n if (changesValueShape || relativeNeedsClear) {\n next.value = undefined;\n return next;\n }\n if (isDateCelValue(value) && value.hasTime && isDateWindowOperator(newOperator)) {\n const { hasTime: _hasTime, ...dayOnly } = value;\n next.value = dayOnly;\n }\n return next;\n }\n\n if (shape === 'map') {\n const value = condition.value;\n if (!isMapKeyCelValue(value)) {\n return next;\n }\n const bothValueOps = MAP_VALUE_OPERATORS.includes(oldOperator) && MAP_VALUE_OPERATORS.includes(newOperator);\n next.value = bothValueOps ? { key: value.key, value: value.value } : { key: value.key };\n return next;\n }\n\n // checkbox / radio / text / multiText: every operator uses the same value shape.\n return next;\n}\n\n// --- CEL fragment generation ------------------------------------------------\n\nexport type ConditionExpression = {\n /** Raw CEL fragment without any outer grouping parentheses. */\n expression: string;\n /** True when the fragment has a bare top-level `||` and must be parenthesized to join under `&&`. */\n needsGrouping: boolean;\n};\n\nconst atomic = (expression: string): ConditionExpression => ({ expression, needsGrouping: false });\n\n/**\n * Builds the CEL fragment for a single condition. Assumes the condition has\n * already passed validation; callers must not pass incomplete/invalid conditions.\n */\nexport function buildConditionExpression(\n condition: CelFilterCondition,\n shape: CelFilterShape,\n columnDef?: CelColumnDefinition,\n): ConditionExpression {\n if (shape === 'map') {\n return buildMapExpression(condition.columnId, condition.operator, condition.value as MapKeyCelValue);\n }\n\n const columnId = columnDef?.id ?? condition.columnId ?? '';\n const column = RESERVED_COLUMN_CEL_IDENTIFIERS[columnId] ?? columnId;\n\n switch (shape) {\n case 'checkbox':\n return buildCheckboxExpression(column, condition.operator, (condition.value as string[]) ?? []);\n case 'radio':\n return buildRadioExpression(column, condition.operator, String(condition.value ?? ''));\n case 'text':\n return atomic(buildTextTokenFragment(column, condition.operator, String(condition.value ?? '')));\n case 'multiText':\n return buildMultiTextExpression(column, condition.operator, condition.value as MultiTextCelValue);\n case 'date':\n return atomic(buildDateExpression(column, condition.operator, condition.value as DateCelValue));\n default:\n return atomic('');\n }\n}\n\nfunction buildCheckboxExpression(column: string, operator: CelOperator, values: string[]): ConditionExpression {\n const list = `${column} in [${values.map(celStringLiteral).join(', ')}]`;\n return atomic(operator === 'is_not' ? `!(${list})` : list);\n}\n\nfunction buildRadioExpression(column: string, operator: CelOperator, value: string): ConditionExpression {\n const literal = celStringLiteral(value);\n return atomic(operator === 'is_not' ? `${column} != ${literal}` : `${column} == ${literal}`);\n}\n\n/**\n * Builds the CEL fragment for a single text token. Single source of truth for\n * the text operator → CEL template mapping.\n *\n * `forcePositive` controls how the two negated operators (`is_not`,\n * `does_not_contain`) render:\n * - `false` (default): native negation (`col != \"x\"`, `!col.contains(\"x\")`).\n * Used for a lone token, where the negation lives on the token itself.\n * - `true`: the positive form (`col == \"x\"`, `col.contains(\"x\")`). Used when\n * composing multiple tokens, where the caller wraps the whole joined\n * expression in a single `!( … )` instead (see `buildMultiTextExpression`).\n */\nfunction buildTextTokenFragment(column: string, operator: CelOperator, value: string, forcePositive = false): string {\n const literal = celStringLiteral(value);\n switch (operator) {\n case 'is':\n return `${column} == ${literal}`;\n case 'is_not':\n return forcePositive ? `${column} == ${literal}` : `${column} != ${literal}`;\n case 'contains':\n return `${column}.contains(${literal})`;\n case 'does_not_contain':\n return forcePositive ? `${column}.contains(${literal})` : `!${column}.contains(${literal})`;\n case 'starts_with':\n return `${column}.startsWith(${literal})`;\n case 'ends_with':\n return `${column}.endsWith(${literal})`;\n case 'matches':\n return `${column}.matches(${literal})`;\n default:\n return '';\n }\n}\n\nfunction isNegatedTextOperator(operator: CelOperator): boolean {\n return operator === 'is_not' || operator === 'does_not_contain';\n}\n\nfunction buildMultiTextExpression(\n column: string,\n operator: CelOperator,\n value: MultiTextCelValue,\n): ConditionExpression {\n const tokens = value.tokens;\n\n if (tokens.length === 1) {\n return atomic(buildTextTokenFragment(column, operator, tokens[0]));\n }\n\n const connective = value.quantifier === 'all' ? ' && ' : ' || ';\n const joined = tokens.map(token => buildTextTokenFragment(column, operator, token, true)).join(connective);\n\n if (isNegatedTextOperator(operator)) {\n return atomic(`!(${joined})`);\n }\n\n // A bare top-level `||` (any quantifier) must be parenthesized when joined under `&&`.\n return { expression: joined, needsGrouping: value.quantifier !== 'all' };\n}\n\nconst DATE_RELATIVE_COMPARATOR_SYMBOLS: Partial<Record<CelOperator, string>> = {\n is_before: '<',\n is_after: '>',\n is_on_or_before: '<=',\n is_on_or_after: '>=',\n};\n\nfunction buildCalendarDayRange(column: string, startInstant: string, endInstant: string): string {\n const start = `timestamp(${celStringLiteral(startInstant)})`;\n const end = `timestamp(${celStringLiteral(endInstant)})`;\n return `${column} >= ${start} && ${column} <= ${end}`;\n}\n\nfunction buildDateExpression(column: string, operator: CelOperator, value: DateCelValue): string {\n if (isRelativeDateCelValue(value)) {\n const durationStr = value.preset ?? '';\n if (!durationStr) {\n return '';\n }\n const relativeSymbol = DATE_RELATIVE_COMPARATOR_SYMBOLS[operator] ?? '>';\n return `${column} ${relativeSymbol} now() - duration(${celStringLiteral(durationStr)})`;\n }\n\n if (isDateRangeOperator(operator) && value.range) {\n const range = buildCalendarDayRange(column, value.range.start, value.range.end);\n return operator === 'is_not_between' ? `!(${range})` : range;\n }\n\n const startInstant = value.instant ?? '';\n // `is` / `is_not` span a whole calendar day whatever the instant carries; the\n // comparators bound the minute the user picked once they have picked one.\n const granularity = value.hasTime && !isDateWindowOperator(operator) ? 'minute' : 'day';\n const endInstant = inclusiveEndInstant(startInstant, granularity);\n const startTimestamp = `timestamp(${celStringLiteral(startInstant)})`;\n const endTimestamp = `timestamp(${celStringLiteral(endInstant)})`;\n\n switch (operator) {\n case 'is':\n return buildCalendarDayRange(column, startInstant, endInstant);\n case 'is_not':\n return `!(${buildCalendarDayRange(column, startInstant, endInstant)})`;\n case 'is_before':\n return `${column} < ${startTimestamp}`;\n case 'is_on_or_before':\n return `${column} <= ${endTimestamp}`;\n case 'is_after':\n return `${column} > ${endTimestamp}`;\n case 'is_on_or_after':\n return `${column} >= ${startTimestamp}`;\n default:\n return `${column} == ${startTimestamp}`;\n }\n}\n\nfunction buildMapExpression(columnId: string, operator: CelOperator, value: MapKeyCelValue): ConditionExpression {\n const column = RESERVED_COLUMN_CEL_IDENTIFIERS[columnId] ?? columnId;\n const keyLiteral = celStringLiteral(value.key);\n\n switch (operator) {\n case 'key_exists':\n return atomic(`${keyLiteral} in ${column}`);\n case 'key_does_not_exist':\n return atomic(`!(${keyLiteral} in ${column})`);\n case 'has_value':\n return atomic(`${column}[${keyLiteral}] == ${celStringLiteral(value.value ?? '')}`);\n case 'does_not_have_value':\n return atomic(`${column}[${keyLiteral}] != ${celStringLiteral(value.value ?? '')}`);\n default:\n return atomic('');\n }\n}\n\n/** Maps parsed CEL aliases back to schema column ids when building the filter tree. */\nexport function denormalizeColumnIdWithReservedNames(columnId: string): string {\n return CEL_IDENTIFIER_TO_COLUMN_ID[columnId] ?? columnId;\n}\n\n/** Rewrites reserved schema column references in a CEL expression before parsing. */\nexport function normalizeColumnsWithReservedNames(expression: string): string {\n return Object.entries(RESERVED_COLUMN_CEL_IDENTIFIERS).reduce(\n (normalized, [columnId, celIdentifier]) =>\n normalized.replace(\n new RegExp(`\\\\b${escapeRegExp(columnId)}\\\\b${RESERVED_FIELD_OPERATOR_PATTERN}`, 'g'),\n celIdentifier,\n ),\n expression,\n );\n}\n\n/** Rewrites CEL aliases back to schema column names for API requests and external consumers. */\nexport function denormalizeColumnsWithReservedNames(expression: string): string {\n return Object.entries(RESERVED_COLUMN_CEL_IDENTIFIERS).reduce(\n (denormalized, [columnId, celIdentifier]) =>\n denormalized.replace(\n new RegExp(`\\\\b${escapeRegExp(celIdentifier)}\\\\b${RESERVED_FIELD_OPERATOR_PATTERN}`, 'g'),\n columnId,\n ),\n expression,\n );\n}\n","import { MAX_REGEX_LEN } from '../constants';\nimport { isRealCalendarDay } from '../date-utils';\nimport {\n type CelColumnDefinition,\n type CelFilterCondition,\n type CelFilterSchema,\n type CompileStatus,\n type DateCelValue,\n isDateCelValue,\n isMapKeyCelValue,\n isMultiTextCelValue,\n type MapKeyCelValue,\n type MultiTextCelValue,\n type ValidationIssue,\n type ValidationIssueCode,\n type ValidationSeverity,\n} from '../types';\nimport { isRelativeDateCelValue } from '../value-utils';\nimport { getAllowedOperators, isDateRangeOperator, isDateRelativeOperator, resolveColumnDefinition } from './operators';\n\n/** Derives the overall compile status from a set of issues (invalid beats incomplete beats valid). */\nexport function statusFromIssues(issues: ValidationIssue[]): CompileStatus {\n if (issues.some(issue => issue.severity === 'invalid')) {\n return 'invalid';\n }\n if (issues.some(issue => issue.severity === 'incomplete')) {\n return 'incomplete';\n }\n return 'valid';\n}\n\nconst SEVERITY_BY_CODE: Record<ValidationIssueCode, ValidationSeverity> = {\n missing_column: 'incomplete',\n missing_value: 'incomplete',\n missing_key: 'incomplete',\n missing_tokens: 'incomplete',\n missing_quantifier: 'incomplete',\n missing_instant: 'incomplete',\n missing_range: 'incomplete',\n missing_duration: 'incomplete',\n unknown_column: 'invalid',\n illegal_operator: 'invalid',\n invalid_date_mode: 'invalid',\n regex_too_long: 'invalid',\n invalid_timestamp: 'invalid',\n invalid_date_range: 'invalid',\n nesting_depth_exceeded: 'invalid',\n};\n\nconst MESSAGES: Record<ValidationIssueCode, string> = {\n missing_column: 'Select a column for this filter.',\n missing_value: 'Enter a value for this filter.',\n missing_key: 'Enter a key for this filter.',\n missing_tokens: 'Enter at least one value for this filter.',\n missing_quantifier: 'Choose whether to match any or all values.',\n missing_instant: 'Select a date for this filter.',\n missing_range: 'Select a start and end date for this filter.',\n missing_duration: 'Select a duration for this filter.',\n unknown_column: 'This column is not available for filtering.',\n illegal_operator: 'This operator is not allowed for this filter.',\n invalid_date_mode: 'This operator cannot be used with this date mode.',\n regex_too_long: `Pattern exceeds the maximum length of ${MAX_REGEX_LEN} characters.`,\n invalid_timestamp: 'Enter a valid date.',\n invalid_date_range: 'The start must be on or before the end.',\n nesting_depth_exceeded: 'This filter is nested too deeply.',\n};\n\n/** RFC3339 timestamp (date + time + Z or numeric offset). */\nconst RFC3339_RE = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})$/;\n\nfunction isValidRfc3339(value: string): boolean {\n return RFC3339_RE.test(value) && !Number.isNaN(Date.parse(value)) && isRealCalendarDay(value);\n}\n\ntype IssueInput = {\n condition: CelFilterCondition;\n code: ValidationIssueCode;\n field?: string;\n};\n\nfunction makeIssue({ condition, code, field }: IssueInput): ValidationIssue {\n return {\n code,\n message: MESSAGES[code],\n severity: SEVERITY_BY_CODE[code],\n nodeId: condition.id,\n nodeType: 'condition',\n field,\n };\n}\n\n/**\n * Validates a single condition against the provided schema. Returns an empty\n * array when the condition is complete and compilable.\n */\nexport function validateCondition(condition: CelFilterCondition, schema: CelFilterSchema): ValidationIssue[] {\n if (!condition.columnId) {\n return [makeIssue({ condition, code: 'missing_column', field: 'columnId' })];\n }\n const columnDef = resolveColumnDefinition(condition, schema);\n if (!columnDef) {\n return [makeIssue({ condition, code: 'unknown_column', field: 'columnId' })];\n }\n return validateColumnCondition(condition, columnDef);\n}\n\nfunction validateColumnCondition(condition: CelFilterCondition, columnDef: CelColumnDefinition): ValidationIssue[] {\n const allowed = getAllowedOperators(columnDef);\n\n if (!allowed.includes(condition.operator)) {\n return [makeIssue({ condition, code: 'illegal_operator', field: 'operator' })];\n }\n\n switch (columnDef.filterType) {\n case 'checkbox':\n case 'static':\n return validateCheckbox(condition);\n case 'radio':\n case 'text':\n return validateSingleString(condition, columnDef.filterType);\n case 'multiText':\n return validateMultiText(condition);\n case 'date':\n return validateDate(condition);\n case 'keyValue':\n return validateMapCondition(condition);\n default:\n return [];\n }\n}\n\nfunction validateCheckbox(condition: CelFilterCondition): ValidationIssue[] {\n const value = condition.value;\n if (!Array.isArray(value) || value.length === 0) {\n return [makeIssue({ condition, code: 'missing_value', field: 'value' })];\n }\n return [];\n}\n\nfunction validateSingleString(condition: CelFilterCondition, filterType: 'radio' | 'text'): ValidationIssue[] {\n const value = condition.value;\n if (typeof value !== 'string' || value === '') {\n return [makeIssue({ condition, code: 'missing_value', field: 'value' })];\n }\n if (filterType === 'text' && condition.operator === 'matches' && value.length > MAX_REGEX_LEN) {\n return [makeIssue({ condition, code: 'regex_too_long', field: 'pattern' })];\n }\n return [];\n}\n\nfunction validateMultiText(condition: CelFilterCondition): ValidationIssue[] {\n const value = condition.value;\n if (!isMultiTextCelValue(value) || value.tokens.length === 0) {\n return [makeIssue({ condition, code: 'missing_tokens', field: 'tokens' })];\n }\n\n const issues: ValidationIssue[] = [];\n const multi = value as MultiTextCelValue;\n\n if (multi.tokens.length > 1 && !multi.quantifier) {\n issues.push(makeIssue({ condition, code: 'missing_quantifier', field: 'quantifier' }));\n }\n\n if (condition.operator === 'matches' && multi.tokens.some(token => token.length > MAX_REGEX_LEN)) {\n issues.push(makeIssue({ condition, code: 'regex_too_long', field: 'pattern' }));\n }\n\n return issues;\n}\n\nfunction validateDate(condition: CelFilterCondition): ValidationIssue[] {\n const value = condition.value;\n\n if (!isDateCelValue(value)) {\n // Freshly added / undefined date condition — treat as a missing single-point instant.\n return [makeIssue({ condition, code: 'missing_instant', field: 'instant' })];\n }\n\n const date = value as DateCelValue;\n\n if (isRelativeDateCelValue(date)) {\n return validateRelativeDate(condition, date);\n }\n return validateAbsoluteDate(condition, date);\n}\n\nfunction validateAbsoluteDate(condition: CelFilterCondition, value: DateCelValue): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n\n if (isDateRangeOperator(condition.operator)) {\n const range = value.range;\n if (!range || !range.start || !range.end) {\n issues.push(makeIssue({ condition, code: 'missing_range', field: 'range' }));\n return issues;\n }\n if (!isValidRfc3339(range.start)) {\n issues.push(makeIssue({ condition, code: 'invalid_timestamp', field: 'start' }));\n }\n if (!isValidRfc3339(range.end)) {\n issues.push(makeIssue({ condition, code: 'invalid_timestamp', field: 'end' }));\n }\n if (issues.length === 0 && Date.parse(range.start) > Date.parse(range.end)) {\n issues.push(makeIssue({ condition, code: 'invalid_date_range', field: 'range' }));\n }\n return issues;\n }\n\n if (!value.instant) {\n issues.push(makeIssue({ condition, code: 'missing_instant', field: 'instant' }));\n return issues;\n }\n if (!isValidRfc3339(value.instant)) {\n issues.push(makeIssue({ condition, code: 'invalid_timestamp', field: 'instant' }));\n }\n return issues;\n}\n\nfunction validateRelativeDate(condition: CelFilterCondition, value: DateCelValue): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n\n if (!isDateRelativeOperator(condition.operator)) {\n issues.push(makeIssue({ condition, code: 'invalid_date_mode', field: 'value' }));\n return issues;\n }\n\n if (!value.preset) {\n issues.push(makeIssue({ condition, code: 'missing_duration', field: 'preset' }));\n }\n return issues;\n}\n\nfunction validateMapCondition(condition: CelFilterCondition): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n\n const value = isMapKeyCelValue(condition.value) ? (condition.value as MapKeyCelValue) : undefined;\n\n if (!value || value.key === '') {\n issues.push(makeIssue({ condition, code: 'missing_key', field: 'key' }));\n }\n\n const requiresValue = condition.operator === 'has_value' || condition.operator === 'does_not_have_value';\n if (requiresValue && (!value || !value.value)) {\n issues.push(makeIssue({ condition, code: 'missing_value', field: 'value' }));\n }\n\n return issues;\n}\n","/**\n * Applies draft/commit display rules to a raw compile result.\n *\n * Validation timing: a condition's issues are surfaced on its pill and in the\n * global panel only once it has been committed (popover closed) and is not\n * currently being edited. Group-level issues (e.g. nesting depth) always show.\n *\n * `isEmitReady` on the returned object is always `false` here — it is a\n * placeholder that `CelFilterBar` overrides via `computeIsEmitReady` before\n * calling `onCompileResultChange`. This is the single source of truth for the gate.\n */\nimport { type CelValidationMeta, type CompileResult } from '../types';\nimport { statusFromIssues } from './validate-condition';\n\nexport function applyDisplayRules(raw: CompileResult, meta: CelValidationMeta): CompileResult {\n const issues = raw.issues.filter(issue => {\n if (issue.nodeType === 'group') {\n return true;\n }\n if (issue.nodeId === meta.editingConditionId) {\n return false;\n }\n return meta.committedConditionIds.has(issue.nodeId);\n });\n\n const status = statusFromIssues(issues);\n const expression = status === 'valid' ? raw.expression : undefined;\n\n return {\n status,\n expression,\n issues,\n isEmitReady: false,\n };\n}\n","import { resolveFilterShape } from './compile/operators';\nimport type { CelColumnDefinition, CelEmitOn, CelFilterCondition, CelFilterSchema } from './types';\nimport { readMapKeyCelValue } from './value-utils';\n\nconst COMMIT_FILTER_TYPES = new Set<CelColumnDefinition['filterType']>(['text', 'multiText', 'keyValue', 'date']);\n\nexport function isMultiTextColumn(columnId: string, schema: CelFilterSchema): boolean {\n return schema.columns.find(column => column.id === columnId)?.filterType === 'multiText';\n}\n\n/** Returns when a column's valid value may be emitted; explicit `emitOn` overrides filterType defaults. */\nexport function getColumnEmitOn(columnDef: CelColumnDefinition): CelEmitOn {\n if (columnDef.emitOn) {\n return columnDef.emitOn;\n }\n return COMMIT_FILTER_TYPES.has(columnDef.filterType) ? 'commit' : 'change';\n}\n\n/** After operator change, keyValue may need the value field before the condition is complete. */\nexport function shouldOpenValueSurfaceAfterOperatorChange(\n condition: CelFilterCondition,\n schema: CelFilterSchema,\n): boolean {\n if (resolveFilterShape(condition, schema) !== 'map') {\n return false;\n }\n const requiresValue = condition.operator === 'has_value' || condition.operator === 'does_not_have_value';\n if (!requiresValue) {\n return false;\n }\n return !readMapKeyCelValue(condition.value).value?.trim();\n}\n","import { getColumnEmitOn } from '../schema-utils';\nimport {\n type CelColumnDefinition,\n type CelFilterCondition,\n type CelFilterSchema,\n type CelFilterTree,\n type CompileResult,\n isCelFilterCondition,\n type PillActiveSurface,\n} from '../types';\n\nexport type ComputeIsEmitReadyMeta = {\n activeSurface: PillActiveSurface | null;\n committedConditionIds: Set<string>;\n};\n\nfunction resolveEditingColumn(\n tree: CelFilterTree,\n schema: CelFilterSchema,\n editingConditionId: string,\n): CelColumnDefinition | undefined {\n const condition = tree.root.children.find(\n (child): child is CelFilterCondition => isCelFilterCondition(child) && child.id === editingConditionId,\n );\n return condition && schema.columns.find(column => column.id === condition.columnId);\n}\n\n/**\n * Gates API emission while a commit-mode condition is mid-edit. Only the\n * actively edited condition matters — one popover at a time.\n */\nexport function computeIsEmitReady(\n raw: CompileResult,\n editingConditionId: string | null,\n schema: CelFilterSchema,\n tree: CelFilterTree,\n meta: ComputeIsEmitReadyMeta,\n): boolean {\n if (raw.status !== 'valid') return false;\n if (!editingConditionId) return true;\n\n const columnDef = resolveEditingColumn(tree, schema, editingConditionId);\n // Unknown column or change-mode → nothing to gate, emit live.\n if (!columnDef || getColumnEmitOn(columnDef) === 'change') return true;\n\n // Commit-mode: emit only once the popover is closed and the draft committed.\n const popoverClosed = meta.activeSurface === null;\n return popoverClosed && meta.committedConditionIds.has(editingConditionId);\n}\n","/**\n * Compiles a CEL filter tree into a CEL string or structured validation issues.\n *\n * Pure logic — no React, no display rules. `CelFilterBar` composes\n * `applyDisplayRules(compileCelFilterTree(tree, schema), meta)`.\n */\nimport { MAX_NESTING_DEPTH } from '../constants';\nimport {\n type CelColumnDefinition,\n type CelFilterGroup,\n type CelFilterSchema,\n type CelFilterTree,\n type CompileResult,\n isCelFilterCondition,\n isCelFilterGroup,\n type ValidationIssue,\n} from '../types';\nimport {\n buildConditionExpression,\n type ConditionExpression,\n resolveColumnDefinition,\n resolveFilterShape,\n} from './operators';\nimport { statusFromIssues, validateCondition } from './validate-condition';\n\ntype GroupCompileResult = {\n issues: ValidationIssue[];\n fragments: ConditionExpression[];\n};\n\n/**\n * Combines a group's child fragments into a single fragment.\n *\n * v1 groups are always `&&`. A child fragment with a bare top-level `||`\n * (e.g. a multiText `any`) is parenthesized before joining so precedence is\n * preserved. The produced fragment reports whether *it* needs grouping when\n * placed under a parent `&&`:\n *\n * - 0 children → empty fragment.\n * - 1 child → propagated as-is so the parent decides on parens (a lone `||`\n * fragment must still be wrapped by whoever joins it under `&&`).\n * - >1 children → a pure `&&` chain, which never needs outer parens under `&&`.\n *\n * (If a future `||` group combinator ships, the connective and `needsGrouping`\n * become combinator-aware; today every group is `&&`.)\n */\nfunction combineGroupFragments(fragments: ConditionExpression[]): ConditionExpression {\n if (fragments.length === 0) {\n return { expression: '', needsGrouping: false };\n }\n if (fragments.length === 1) {\n return fragments[0];\n }\n return {\n expression: fragments\n .map(fragment => (fragment.needsGrouping ? `(${fragment.expression})` : fragment.expression))\n .join(' && '),\n needsGrouping: false,\n };\n}\n\nfunction compileGroup(group: CelFilterGroup, schema: CelFilterSchema): GroupCompileResult {\n const depthIssues: ValidationIssue[] =\n group.depth > MAX_NESTING_DEPTH\n ? [\n {\n code: 'nesting_depth_exceeded',\n message: 'This filter is nested too deeply.',\n severity: 'invalid',\n nodeId: group.id,\n nodeType: 'group',\n },\n ]\n : [];\n\n return group.children.reduce<GroupCompileResult>(\n (acc, child) => {\n if (isCelFilterGroup(child)) {\n const nested = compileGroup(child, schema);\n acc.issues.push(...nested.issues);\n if (nested.fragments.length > 0) {\n acc.fragments.push(combineGroupFragments(nested.fragments));\n }\n return acc;\n }\n\n if (isCelFilterCondition(child)) {\n const conditionIssues = validateCondition(child, schema);\n if (conditionIssues.length > 0) {\n acc.issues.push(...conditionIssues);\n return acc;\n }\n\n const shape = resolveFilterShape(child, schema);\n if (!shape) {\n return acc;\n }\n const columnDef: CelColumnDefinition | undefined = resolveColumnDefinition(child, schema);\n acc.fragments.push(buildConditionExpression(child, shape, columnDef));\n }\n\n return acc;\n },\n { issues: depthIssues, fragments: [] },\n );\n}\n\n/**\n * Walks the tree, joins root children with ` && `, and emits a CEL string when\n * everything is complete and valid. An empty root compiles to `\"\"` with status\n * `valid` (the API treats an empty filter as no filter).\n */\nexport function compileCelFilterTree(tree: CelFilterTree, schema: CelFilterSchema): CompileResult {\n const { issues, fragments } = compileGroup(tree.root, schema);\n const status = statusFromIssues(issues);\n\n if (status === 'valid') {\n return { status, expression: combineGroupFragments(fragments).expression, issues, isEmitReady: true };\n }\n\n return { status, issues, isEmitReady: false };\n}\n","/**\n * Tree factories and helpers for the CEL filter builder.\n */\nimport { getDefaultOperator } from './compile/operators';\nimport { isCelFilterCondition } from './types';\nimport type { CelFilterCondition, CelFilterSchema, CelFilterTree } from './types';\n\n/** Generates a stable unique id, falling back when `crypto.randomUUID` is unavailable. */\nexport function createCelNodeId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n return `cel-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Creates an empty tree whose root is a depth-0 `and` group with no children. */\nexport function createEmptyCelFilterTree(): CelFilterTree {\n return {\n root: {\n id: createCelNodeId(),\n type: 'group',\n combinator: 'and',\n depth: 0,\n children: [],\n },\n };\n}\n\nexport type CreateDefaultConditionParams = {\n schema: CelFilterSchema;\n columnId: string;\n};\n\n/**\n * Creates a new condition with the default operator for its column and an\n * undefined value (filled in by the user in the popover).\n */\nexport function createDefaultCondition({ schema, columnId }: CreateDefaultConditionParams): CelFilterCondition {\n const columnDef = schema.columns.find(column => column.id === columnId);\n if (!columnDef) {\n throw new Error(`createDefaultCondition: column \"${columnId}\" is not in schema.columns`);\n }\n\n return {\n id: createCelNodeId(),\n type: 'condition',\n columnId,\n operator: getDefaultOperator(columnDef.filterType),\n value: columnDef.defaultValue,\n };\n}\n\n/** Appends a condition to the root group's children. */\nexport function appendCondition(tree: CelFilterTree, condition: CelFilterCondition): CelFilterTree {\n return { root: { ...tree.root, children: [...tree.root.children, condition] } };\n}\n\n/** Replaces a root-level condition by id, applying `updater` to the existing condition. Root-level only — v1's UI never produces nested groups. */\nexport function replaceCondition(\n tree: CelFilterTree,\n conditionId: string,\n updater: (condition: CelFilterCondition) => CelFilterCondition,\n): CelFilterTree {\n return {\n root: {\n ...tree.root,\n children: tree.root.children.map(child =>\n isCelFilterCondition(child) && child.id === conditionId ? updater(child) : child,\n ),\n },\n };\n}\n\n/** Removes a root-level condition by id. */\nexport function removeConditionById(tree: CelFilterTree, conditionId: string): CelFilterTree {\n return {\n root: {\n ...tree.root,\n children: tree.root.children.filter(child => !(isCelFilterCondition(child) && child.id === conditionId)),\n },\n };\n}\n","import type { Cell, ColumnFilter, ColumnFiltersState, RowData } from '@tanstack/react-table';\n\nimport './table-meta';\nimport type { ColumnFilterDefinition, ColumnFilterValue } from './filter-types';\n\nfunction valueToString(value: unknown): string | undefined {\n if (value === undefined || value === null) return undefined;\n const normalized = String(value).trim();\n return normalized || undefined;\n}\n\nfunction stringArrayFromValue(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value.map(valueToString).filter((v): v is string => !!v);\n }\n const normalized = valueToString(value);\n return normalized ? [normalized] : [];\n}\n\n/** Flattens a scalar or array cell value into trimmed, non-empty strings — the\n * shape `celFilterConfig.onContextualFilter` and `mergeContextualIntoCelTree` want. */\nexport function columnFilterValueToStrings(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value.map(item => String(item).trim()).filter(Boolean);\n }\n const normalized = String(value ?? '').trim();\n return normalized ? [normalized] : [];\n}\n\nexport function hasContextualFilterValue(value: ColumnFilterValue | undefined): boolean {\n if (value === undefined) return false;\n if (typeof value === 'string') return value.trim() !== '';\n if (Array.isArray(value)) {\n return value.filter(item => typeof item === 'string' && item.trim() !== '').length > 0;\n }\n return !!(value.startDate ?? value.endDate);\n}\n\nfunction getDefaultContextualFilterValue<TData extends RowData, TValue>(\n cell: Cell<TData, TValue>,\n filter: ColumnFilterDefinition,\n): ColumnFilterValue | undefined {\n const value = cell.getValue();\n\n if (filter.type === 'checkbox' || filter.type === 'multiText') {\n const values = stringArrayFromValue(value);\n return values.length > 0 ? values : undefined;\n }\n\n if (filter.type === 'radio' || filter.type === 'text') {\n return valueToString(value);\n }\n\n return undefined;\n}\n\n/** Derives the contextual (right-click cell) column filter, or `undefined` if\n * the column has no `meta.filter` or no value can be derived. */\nexport function getContextualColumnFilter<TData extends RowData, TValue>(\n cell: Cell<TData, TValue>,\n): ColumnFilter | undefined {\n const meta = cell.column.columnDef.meta;\n const filter = meta?.filter;\n if (!filter) return undefined;\n\n const value = meta?.contextualFilterValue\n ? meta.contextualFilterValue(cell)\n : getDefaultContextualFilterValue(cell, filter);\n if (!hasContextualFilterValue(value)) return undefined;\n\n return { id: cell.column.id, value };\n}\n\n/** Derives the contextual (right-click cell) global-search term, or `undefined`\n * when the column has no `meta.contextualGlobalSearchValue`. */\nexport function getContextualGlobalSearch<TData extends RowData, TValue>(\n cell: Cell<TData, TValue>,\n): string | undefined {\n const globalSearchValue = cell.column.columnDef.meta?.contextualGlobalSearchValue;\n if (!globalSearchValue) return undefined;\n return valueToString(globalSearchValue(cell));\n}\n\n/**\n * Merges a contextual filter into `ColumnFiltersState`. Checkbox/multiText\n * filters union with any existing values for that column (deduped); every\n * other type replaces the column's filter outright.\n */\nexport function mergeColumnFilter(\n columnFilters: ColumnFiltersState,\n nextFilter: ColumnFilter,\n filterDefinition?: ColumnFilterDefinition,\n): ColumnFiltersState {\n const shouldMergeArrayValue = filterDefinition?.type === 'checkbox' || filterDefinition?.type === 'multiText';\n\n if (!shouldMergeArrayValue) {\n return [...columnFilters.filter(filter => filter.id !== nextFilter.id), nextFilter];\n }\n\n const nextValues = stringArrayFromValue(nextFilter.value);\n if (nextValues.length === 0) return columnFilters;\n\n const existingFilter = columnFilters.find(filter => filter.id === nextFilter.id);\n const existingValues = stringArrayFromValue(existingFilter?.value);\n const mergedValues = Array.from(new Set([...existingValues, ...nextValues]));\n\n if (existingFilter && mergedValues.length === existingValues.length) return columnFilters;\n\n return [...columnFilters.filter(filter => filter.id !== nextFilter.id), { id: nextFilter.id, value: mergedValues }];\n}\n\n/**\n * Counts active filter \"slots\" for UI badges (the Filter-button count and the\n * empty-view filter count). When `filter` is omitted, falls back to a\n * best-effort shape heuristic (ambiguous for `string` vs radio and `string[]`\n * vs multiText).\n */\nexport function getColumnFilterCount(filterValue: unknown, filter?: ColumnFilterDefinition): number {\n const isCheckboxValue = (value: unknown): value is string[] | undefined =>\n value === undefined || (Array.isArray(value) && value.every(item => typeof item === 'string'));\n const isRadioValue = (value: unknown): value is string | undefined =>\n value === undefined || typeof value === 'string';\n const isDateRangeValue = (value: unknown): value is { startDate: Date | null; endDate: Date | null } | undefined =>\n value === undefined || (typeof value === 'object' && value !== null && 'startDate' in value && 'endDate' in value);\n\n if (filter?.type === 'checkbox') {\n return isCheckboxValue(filterValue) ? (filterValue || []).length : 0;\n }\n\n if (filter?.type === 'radio') {\n return isRadioValue(filterValue) && filterValue !== undefined ? 1 : 0;\n }\n\n if (filter?.type === 'dateRange') {\n if (!isDateRangeValue(filterValue)) return 0;\n return Number(!!filterValue?.startDate) + Number(!!filterValue?.endDate);\n }\n\n if (isCheckboxValue(filterValue)) {\n return (filterValue || []).length;\n }\n\n if (isRadioValue(filterValue) && filterValue !== undefined) {\n return 1;\n }\n\n if (isDateRangeValue(filterValue)) {\n return Number(!!filterValue?.startDate) + Number(!!filterValue?.endDate);\n }\n\n return 0;\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport type { ColumnSizingState, OnChangeFn } from '@tanstack/react-table';\n\nexport const RESIZE_MIN = 40;\nexport const RESIZE_MAX = 500;\n/** Grid layout's \"unbounded\" max — not `Infinity` (mirrors the source constant exactly). Only relevant once grid mode ships. */\nexport const RESIZE_MAX_UNBOUNDED = Number.MAX_SAFE_INTEGER;\nexport const DEFAULT_COLUMN_SIZE = 150;\nconst FIT_CONTENT_PLACEHOLDER_SIZE = 400;\nconst PERSIST_DEBOUNCE_MS = 300;\n/** Grid layout's `fr` values are floored here to avoid zero/negative CSS Grid tracks. */\nexport const MIN_FR_VALUE = 0.01;\n\nexport interface UseTableColumnResizingOptions {\n initialSizing?: ColumnSizingState;\n onColumnSizingPersist?: (sizing: ColumnSizingState) => void;\n maxSize?: number;\n}\n\nexport function clampSizing(sizing: ColumnSizingState, maxSize = RESIZE_MAX): ColumnSizingState {\n return Object.entries(sizing).reduce<ColumnSizingState>(\n (acc, [colId, size]) => ({ ...acc, [colId]: Math.min(maxSize, Math.max(RESIZE_MIN, size)) }),\n {},\n );\n}\n\n/** A resize-start snapshot of the grid's flex/fixed classification — captured once per drag. */\nexport interface GridResizeSnapshotMeta {\n containerWidth: number;\n fixedTotal: number;\n flexIds: string[];\n mins: Record<string, number>;\n}\n\nexport interface ComputeGridResizeFrValuesOptions {\n resizingColumnId: string | false;\n deltaOffset?: number | null;\n visualOrder: string[];\n snapshotWidths: Record<string, number>;\n snapshotMeta: GridResizeSnapshotMeta;\n}\n\n/**\n * Redistributes flex-column `fr` values for a live grid-mode drag resize.\n * The dragged column grows/shrinks to `deltaOffset`; the space is absorbed\n * from flex columns to its right first, falling back to the left, while\n * columns on the frozen side keep their pre-drag snapshot width verbatim.\n * Every returned value is a pixel count (not a true proportional weight) —\n * a fresh per-drag redistribution, not a persisted ratio.\n */\nexport function computeGridResizeFrValues({\n resizingColumnId,\n deltaOffset,\n visualOrder,\n snapshotWidths,\n snapshotMeta,\n}: ComputeGridResizeFrValuesOptions): Record<string, number> {\n if (!resizingColumnId || deltaOffset == null || snapshotMeta.containerWidth <= 0) {\n return {};\n }\n\n const { fixedTotal, flexIds, mins, containerWidth } = snapshotMeta;\n const snapshotPx = snapshotWidths[resizingColumnId];\n if (!snapshotPx || !flexIds.includes(resizingColumnId)) {\n return {};\n }\n\n const desiredPx = Math.max(mins[resizingColumnId] ?? 0, snapshotPx + deltaOffset);\n const resizeIdx = visualOrder.indexOf(resizingColumnId);\n const otherFlexIds = flexIds.filter(colId => colId !== resizingColumnId);\n const rightFlexIds = otherFlexIds.filter(colId => visualOrder.indexOf(colId) > resizeIdx);\n const leftFlexIds = otherFlexIds.filter(colId => visualOrder.indexOf(colId) < resizeIdx);\n\n const absorbingIds = rightFlexIds.length > 0 ? rightFlexIds : leftFlexIds;\n const frozenIds = rightFlexIds.length > 0 ? leftFlexIds : rightFlexIds;\n const nextFr: Record<string, number> = {};\n\n for (const colId of frozenIds) {\n nextFr[colId] = snapshotWidths[colId] ?? MIN_FR_VALUE;\n }\n\n const frozenTotal = frozenIds.reduce((sum, colId) => sum + (snapshotWidths[colId] ?? 0), 0);\n const availableForAbsorbing = containerWidth - fixedTotal - desiredPx - frozenTotal;\n const absorbingSnapshotTotal = absorbingIds.reduce((sum, colId) => sum + (snapshotWidths[colId] ?? 0), 0);\n\n for (const colId of absorbingIds) {\n const snap = snapshotWidths[colId] ?? 0;\n const share = absorbingSnapshotTotal > 0 ? snap / absorbingSnapshotTotal : 1 / absorbingIds.length;\n const targetPx = Math.max(mins[colId] ?? 0, availableForAbsorbing * share);\n nextFr[colId] = Math.max(MIN_FR_VALUE, targetPx);\n }\n\n nextFr[resizingColumnId] = Math.max(MIN_FR_VALUE, desiredPx);\n return nextFr;\n}\n\nexport interface GridFlexSizingDefinition {\n flex?: number;\n min?: string;\n max?: string;\n}\n\nexport interface ResolveGridPersistedFrOptions {\n visualOrder: string[];\n persistedFr: Record<string, number>;\n columnSizing: ColumnSizingState;\n measuredMins: Record<string, number>;\n getGridSizing: (columnId: string) => GridFlexSizingDefinition | undefined;\n}\n\n/**\n * Reconciles persisted `fr` values (e.g. seeded from `initialColumnSizing`)\n * against each flex column's current min/max bounds — called while idle\n * (not mid-drag), since live drag values come from `computeGridResizeFrValues`.\n */\nexport function resolveGridPersistedFr({\n visualOrder,\n persistedFr,\n columnSizing,\n measuredMins,\n getGridSizing,\n}: ResolveGridPersistedFrOptions): Record<string, number> {\n const nextFr = { ...persistedFr };\n\n for (const colId of visualOrder) {\n const grid = getGridSizing(colId);\n if (!grid || grid.flex == null) continue;\n\n if (!nextFr[colId] && columnSizing[colId]) {\n nextFr[colId] = columnSizing[colId];\n }\n\n if (nextFr[colId]) {\n const minPx = measuredMins[colId] ?? (grid.min ? parseFloat(grid.min) || 0 : 0);\n const maxPx = grid.max ? parseFloat(grid.max) || Infinity : Infinity;\n nextFr[colId] = Math.max(minPx, Math.min(maxPx, nextFr[colId]));\n }\n }\n\n return nextFr;\n}\n\n/**\n * Column-resize state: clamped `[40, maxSize]` (default max 500), a\n * 300ms-debounced persist on drag, and immediate (debounce-cancelling)\n * persist from the three menu actions. \"Autosize\" in auto layout is a\n * 150⇄400 toggle, not real content measurement — real measurement only\n * exists in grid layout mode (not yet implemented on `DataTable`).\n */\nexport function useTableColumnResizing({\n initialSizing,\n onColumnSizingPersist,\n maxSize,\n}: UseTableColumnResizingOptions = {}) {\n const [columnSizing, setColumnSizing] = useState<ColumnSizingState>(() => clampSizing(initialSizing ?? {}, maxSize));\n const persistTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Re-syncs when `initialSizing`'s reference changes (e.g. an async-loaded\n // persisted sizing lands after mount) — but bails on a fresh-but-equal\n // object so a caller passing an inline literal doesn't clobber in-progress\n // resizes on every render. This is deliberately an effect, not derived\n // during render: `initialSizing` is an external (often async) value the\n // hook must adopt once, not on every render it happens to differ by\n // reference; the equality bailout is what keeps it from cascading.\n useEffect(() => {\n if (!initialSizing) return;\n const next = clampSizing(initialSizing, maxSize);\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setColumnSizing(prev => {\n const keys = Object.keys(next);\n if (Object.keys(prev).length !== keys.length) return next;\n return keys.every(k => prev[k] === next[k]) ? prev : next;\n });\n }, [initialSizing, maxSize]);\n\n useEffect(() => {\n return () => {\n if (persistTimerRef.current) clearTimeout(persistTimerRef.current);\n };\n }, []);\n\n const debouncedPersist = useCallback(\n (sizing: ColumnSizingState) => {\n if (persistTimerRef.current) clearTimeout(persistTimerRef.current);\n persistTimerRef.current = setTimeout(() => onColumnSizingPersist?.(sizing), PERSIST_DEBOUNCE_MS);\n },\n [onColumnSizingPersist],\n );\n\n const handleColumnSizingChange = useCallback<OnChangeFn<ColumnSizingState>>(\n updaterOrValue => {\n setColumnSizing(prev => {\n const raw = typeof updaterOrValue === 'function' ? updaterOrValue(prev) : updaterOrValue;\n const next = clampSizing(raw, maxSize);\n debouncedPersist(next);\n return next;\n });\n },\n [debouncedPersist, maxSize],\n );\n\n const cancelPendingPersist = useCallback(() => {\n if (persistTimerRef.current) {\n clearTimeout(persistTimerRef.current);\n persistTimerRef.current = null;\n }\n }, []);\n\n const handleAutosizeAll = useCallback(() => {\n cancelPendingPersist();\n setColumnSizing({});\n onColumnSizingPersist?.({});\n }, [cancelPendingPersist, onColumnSizingPersist]);\n\n const handleAutosizeColumn = useCallback(\n (columnId: string) => {\n cancelPendingPersist();\n setColumnSizing(prev => {\n const current = prev[columnId] ?? DEFAULT_COLUMN_SIZE;\n const next = { ...prev };\n next[columnId] = current <= DEFAULT_COLUMN_SIZE ? FIT_CONTENT_PLACEHOLDER_SIZE : DEFAULT_COLUMN_SIZE;\n onColumnSizingPersist?.(next);\n return next;\n });\n },\n [cancelPendingPersist, onColumnSizingPersist],\n );\n\n const handleResetColumnSize = useCallback(\n (columnId: string) => {\n cancelPendingPersist();\n setColumnSizing(prev => {\n const next = { ...prev };\n delete next[columnId];\n onColumnSizingPersist?.(next);\n return next;\n });\n },\n [cancelPendingPersist, onColumnSizingPersist],\n );\n\n return { columnSizing, handleColumnSizingChange, handleAutosizeAll, handleAutosizeColumn, handleResetColumnSize };\n}\n","import * as React from 'react';\nimport type { ColumnSizingState, OnChangeFn, RowData, Table } from '@tanstack/react-table';\n\nimport {\n findContentMinColumns,\n getGridColumnTemplate,\n measureMaxContentMins,\n snapshotResizeStart,\n} from '@/lib/data-table/grid-layout';\n\nimport {\n computeGridResizeFrValues,\n resolveGridPersistedFr,\n type GridResizeSnapshotMeta,\n} from './use-table-column-resizing';\nimport type { TableLayout } from '@/data-table/data-table-types';\n\nexport interface UseGridLayoutOptions<TData extends RowData> {\n layout: TableLayout;\n table: Table<TData>;\n /** Scroll container that owns the `[role=\"columnheader\"]` elements measured for resize snapshots. */\n tableBodyScrollRef: React.RefObject<HTMLDivElement | null>;\n displayableColumns: { id: string }[];\n columnOrdering: string[];\n gridMeasuredMins: Record<string, number>;\n setGridMeasuredMins: React.Dispatch<React.SetStateAction<Record<string, number>>>;\n handleColumnSizingChange: OnChangeFn<ColumnSizingState>;\n rawHandleAutosizeAll: () => void;\n rawHandleAutosizeColumn: (columnId: string) => void;\n rawHandleResetColumnSize: (columnId: string) => void;\n}\n\nexport interface UseGridLayoutReturn {\n gridTemplateColumns: string | undefined;\n /** Attach to the grid root `<div role=\"table\">` — the live `--col-fr-*` writer effect reads this directly. */\n gridRootRef: React.RefObject<HTMLDivElement | null>;\n gridVisualColumnOrder: React.RefObject<string[]>;\n gridPersistedFr: React.RefObject<Record<string, number>>;\n gridSnapshotWidths: React.RefObject<Record<string, number>>;\n clearGridFr: (columnId?: string) => void;\n measureContentMins: () => void;\n handleAutosizeAll: () => void;\n handleAutosizeColumn: (columnId: string) => void;\n handleResetColumnSize: (columnId: string) => void;\n}\n\n/**\n * Owns everything `layout=\"grid\"` needs beyond the base column-sizing state:\n * the `gridTemplateColumns` CSS generation, content-min measurement, and the\n * live drag-resize visual feedback. The last of these is a deliberate escape\n * hatch from React's render cycle — `columnResizeMode: 'onEnd'` in grid mode\n * means TanStack's own `columnSizing` state doesn't update until a drag ends,\n * so the only way to show 60fps visual feedback during the drag is to write\n * the `--col-fr-<id>` CSS custom property (which `getGridColumnTemplate`'s\n * `minmax(..., var(--col-fr-<id>, <flex>fr))` tracks already reference)\n * directly via `style.setProperty`, bypassing React state entirely.\n *\n * Deliberate improvement over the legacy source this was ported from: the\n * grid root element is held via `gridRootRef` (a real ref, attached directly\n * to the grid root) instead of re-querying\n * `tableBodyScrollRef.current?.querySelector('[role=\"table\"]')` on every\n * render — a plain `ref` object's `.current` is already kept correctly in\n * sync with whichever DOM node is mounted at that JSX position by React\n * itself, remounts included, so this is a strictly cheaper way to read the\n * same always-current value, not a behavior change.\n */\nexport function useGridLayout<TData extends RowData>({\n layout,\n table,\n tableBodyScrollRef,\n displayableColumns,\n columnOrdering,\n gridMeasuredMins,\n setGridMeasuredMins,\n handleColumnSizingChange,\n rawHandleAutosizeAll,\n rawHandleAutosizeColumn,\n rawHandleResetColumnSize,\n}: UseGridLayoutOptions<TData>): UseGridLayoutReturn {\n const isGrid = layout === 'grid';\n\n const gridRootRef = React.useRef<HTMLDivElement>(null);\n const gridSnapshotWidths = React.useRef<Record<string, number>>({});\n const gridVisualColumnOrder = React.useRef<string[]>([]);\n const gridPersistedFr = React.useRef<Record<string, number>>({});\n const gridSnapshotMeta = React.useRef<GridResizeSnapshotMeta>({\n containerWidth: 0,\n fixedTotal: 0,\n flexIds: [],\n mins: {},\n });\n const prevResizingColumn = React.useRef<string | false>(false);\n const prevResizingForCorrection = React.useRef<string | false>(false);\n\n const clearGridFr = React.useCallback(\n (columnId?: string) => {\n if (!isGrid) return;\n const tableEl = gridRootRef.current;\n if (columnId) {\n delete gridPersistedFr.current[columnId];\n tableEl?.style.removeProperty(`--col-fr-${columnId}`);\n } else {\n for (const colId of Object.keys(gridPersistedFr.current)) {\n tableEl?.style.removeProperty(`--col-fr-${colId}`);\n }\n gridPersistedFr.current = {};\n }\n gridSnapshotWidths.current = {};\n },\n [isGrid],\n );\n\n const headerGroups = table.getHeaderGroups();\n\n // Only ever reads `headerGroups[0]` — correct as long as grouped/nested\n // column headers aren't in use (Monarch doesn't expose that feature today;\n // the auto-mode `totalTableWidth` memo in `data-table.tsx` makes the same\n // assumption). A genuinely multi-level header would need this to\n // reconcile against the leaf row instead — out of scope here.\n //\n // Computes the visual column order alongside the template (not just the\n // template alone) so the companion effect below can sync\n // `gridVisualColumnOrder` without redoing this derivation — a ref can't be\n // written during render, so the write itself happens in that effect.\n const gridTemplate = React.useMemo(() => {\n if (!isGrid) return undefined;\n\n const firstGroup = headerGroups[0];\n if (!firstGroup) return undefined;\n\n const displayableIds = new Set(displayableColumns.map(c => c.id));\n const visibleHeaders = firstGroup.headers.filter(h => displayableIds.has(h.column.id));\n\n return {\n visualOrder: visibleHeaders.map(h => h.column.id),\n template: getGridColumnTemplate({\n headers: visibleHeaders.map(h => ({\n columnId: h.column.id,\n size: h.column.getSize(),\n grid: h.column.columnDef.meta?.grid,\n })),\n gridMeasuredMins,\n }),\n };\n }, [isGrid, headerGroups, displayableColumns, gridMeasuredMins]);\n\n const gridTemplateColumns = gridTemplate?.template;\n\n // Declared before every other effect below so it commits first within the\n // same layout-effect phase — those effects read `gridVisualColumnOrder.current`\n // assuming it already reflects the latest `gridTemplate`.\n React.useLayoutEffect(() => {\n if (gridTemplate) gridVisualColumnOrder.current = gridTemplate.visualOrder;\n }, [gridTemplate]);\n\n const resizingColumn = table.getState().columnSizingInfo.isResizingColumn;\n\n // Snapshot each header's pre-drag width the moment a resize starts — the\n // live drag math (`computeGridResizeFrValues`, below) redistributes space\n // relative to this snapshot, not to the column's ever-changing live size.\n React.useLayoutEffect(() => {\n if (resizingColumn && !prevResizingColumn.current) {\n const headers = tableBodyScrollRef.current?.querySelectorAll('[role=\"columnheader\"]');\n if (headers) {\n const result = snapshotResizeStart({\n headers,\n visualOrder: gridVisualColumnOrder.current,\n getColumnGrid: colId => table.getColumn(colId)?.columnDef.meta?.grid,\n tableEl: gridRootRef.current,\n });\n if (result) {\n Object.assign(gridSnapshotWidths.current, result.widths);\n gridSnapshotMeta.current = result.meta;\n }\n }\n }\n prevResizingColumn.current = resizingColumn || false;\n }, [resizingColumn, table, tableBodyScrollRef]);\n\n const measureContentMins = React.useCallback(() => {\n const tableEl = gridRootRef.current;\n const headers = tableBodyScrollRef.current?.querySelectorAll('[role=\"columnheader\"]');\n const visualOrder = gridVisualColumnOrder.current;\n if (!tableEl || !headers || visualOrder.length !== headers.length) return;\n\n const getColumnGrid = (colId: string) => table.getColumn(colId)?.columnDef.meta?.grid;\n const columnsToMeasure = findContentMinColumns(visualOrder, getColumnGrid);\n if (columnsToMeasure.length === 0) return;\n\n const newMins = measureMaxContentMins(tableEl, headers, visualOrder, columnsToMeasure, getColumnGrid);\n setGridMeasuredMins(prev => {\n const keys = Object.keys(newMins);\n if (keys.length === Object.keys(prev).length && keys.every(k => Math.abs((prev[k] ?? 0) - newMins[k]) < 0.5)) {\n return prev;\n }\n return newMins;\n });\n }, [table, tableBodyScrollRef, setGridMeasuredMins]);\n\n const rowCount = table.getRowCount();\n const tableRows = table.getRowModel().rows;\n const contentMinKey = displayableColumns.map(c => c.id).join(',');\n React.useLayoutEffect(() => {\n if (!isGrid || resizingColumn) return;\n measureContentMins();\n }, [isGrid, resizingColumn, rowCount, contentMinKey, tableRows, measureContentMins]);\n\n React.useEffect(() => {\n if (!isGrid) return;\n const scrollEl = tableBodyScrollRef.current;\n if (!scrollEl) return;\n const observer = new ResizeObserver(() => {\n if (!table.getState().columnSizingInfo.isResizingColumn) {\n measureContentMins();\n }\n });\n observer.observe(scrollEl);\n return () => observer.disconnect();\n }, [isGrid, measureContentMins, table, tableBodyScrollRef]);\n\n // No dependency array — deliberately runs after every render. This is the\n // safety net that keeps `--col-fr-*` alive across anything that could\n // invalidate it (a remount, a key change elsewhere in the tree); narrowing\n // the deps would silently reintroduce that fragility via a missed run\n // instead of a stale DOM query. During an active drag it also writes the\n // live, not-yet-committed `fr` values directly — see the hook doc comment.\n React.useLayoutEffect(() => {\n if (!isGrid) return;\n const tableEl = gridRootRef.current;\n if (!tableEl) return;\n\n const { isResizingColumn, deltaOffset } = table.getState().columnSizingInfo;\n\n if (isResizingColumn && deltaOffset != null) {\n const nextFr = computeGridResizeFrValues({\n resizingColumnId: isResizingColumn,\n deltaOffset,\n visualOrder: gridVisualColumnOrder.current,\n snapshotWidths: gridSnapshotWidths.current,\n snapshotMeta: gridSnapshotMeta.current,\n });\n\n for (const [colId, fr] of Object.entries(nextFr)) {\n tableEl.style.setProperty(`--col-fr-${colId}`, `${fr}fr`);\n gridPersistedFr.current[colId] = fr;\n }\n } else {\n gridPersistedFr.current = resolveGridPersistedFr({\n visualOrder: gridVisualColumnOrder.current,\n persistedFr: gridPersistedFr.current,\n columnSizing: table.getState().columnSizing,\n measuredMins: gridMeasuredMins,\n getGridSizing: colId => {\n const grid = table.getColumn(colId)?.columnDef.meta?.grid;\n return grid && 'flex' in grid ? grid : undefined;\n },\n });\n }\n\n for (const [colId, fr] of Object.entries(gridPersistedFr.current)) {\n tableEl.style.setProperty(`--col-fr-${colId}`, `${fr}fr`);\n }\n });\n\n // Also no dependency array — gated internally by `prevResizingForCorrection`\n // to fire exactly once, on the falling edge of `resizingColumn`. Reconciles\n // the fr-as-px approximation above back into TanStack's real `columnSizing`\n // state once a drag ends, using each column's actual rendered width.\n React.useLayoutEffect(() => {\n const wasResizing = prevResizingForCorrection.current;\n prevResizingForCorrection.current = resizingColumn || false;\n if (!isGrid || resizingColumn || !wasResizing) return;\n\n const headers = tableBodyScrollRef.current?.querySelectorAll('[role=\"columnheader\"]');\n const visualOrder = gridVisualColumnOrder.current;\n if (!headers || visualOrder.length !== headers.length) return;\n\n const corrected: Record<string, number> = {};\n Array.from(headers).forEach((header, idx) => {\n const colId = visualOrder[idx];\n if (!colId) return;\n const grid = table.getColumn(colId)?.columnDef.meta?.grid;\n if (grid && 'flex' in grid && grid.flex != null) {\n corrected[colId] = Math.round(header.getBoundingClientRect().width);\n }\n });\n if (Object.keys(corrected).length > 0) {\n handleColumnSizingChange(prev => ({ ...prev, ...corrected }));\n }\n });\n\n const handleAutosizeAll = React.useCallback(() => {\n clearGridFr();\n rawHandleAutosizeAll();\n }, [clearGridFr, rawHandleAutosizeAll]);\n\n const handleAutosizeColumn = React.useCallback(\n (columnId: string) => {\n clearGridFr(columnId);\n rawHandleAutosizeColumn(columnId);\n },\n [clearGridFr, rawHandleAutosizeColumn],\n );\n\n const handleResetColumnSize = React.useCallback(\n (columnId: string) => {\n clearGridFr(columnId);\n rawHandleResetColumnSize(columnId);\n },\n [clearGridFr, rawHandleResetColumnSize],\n );\n\n const prevColumnOrderingRef = React.useRef(columnOrdering);\n React.useEffect(() => {\n const prev = prevColumnOrderingRef.current;\n prevColumnOrderingRef.current = columnOrdering;\n if (isGrid && prev.length > 0 && prev.join(',') !== columnOrdering.join(',')) {\n gridSnapshotWidths.current = {};\n gridPersistedFr.current = {};\n handleAutosizeAll();\n }\n }, [isGrid, columnOrdering, handleAutosizeAll]);\n\n return {\n gridTemplateColumns,\n gridRootRef,\n gridVisualColumnOrder,\n gridPersistedFr,\n gridSnapshotWidths,\n clearGridFr,\n measureContentMins,\n handleAutosizeAll,\n handleAutosizeColumn,\n handleResetColumnSize,\n };\n}\n","import type { GridResizeSnapshotMeta } from '@/hooks/use-table-column-resizing';\n\nimport type { GridColumnSizing } from './table-meta';\n\nexport type GetColumnGrid = (columnId: string) => GridColumnSizing | undefined;\n\nexport interface GridSnapshotInput {\n headers: NodeListOf<Element>;\n visualOrder: string[];\n getColumnGrid: GetColumnGrid;\n}\n\nexport interface GridResizeSnapshot {\n widths: Record<string, number>;\n fixedTotal: number;\n flexIds: string[];\n mins: Record<string, number>;\n needsMaxContentMeasure: string[];\n}\n\nexport function computeGridResizeSnapshot({\n headers,\n visualOrder,\n getColumnGrid,\n}: GridSnapshotInput): GridResizeSnapshot {\n let fixedTotal = 0;\n const flexIds: string[] = [];\n const mins: Record<string, number> = {};\n const widths: Record<string, number> = {};\n const needsMaxContentMeasure: string[] = [];\n\n Array.from(headers).forEach((header, idx) => {\n const columnId = visualOrder[idx];\n if (!columnId) return;\n const px = header.getBoundingClientRect().width;\n widths[columnId] = px;\n const grid = getColumnGrid(columnId);\n if (grid && 'flex' in grid && grid.flex != null) {\n flexIds.push(columnId);\n const minVal = grid.min;\n if (minVal && minVal !== 'max-content' && minVal !== 'min-content') {\n mins[columnId] = parseFloat(minVal) || 0;\n } else if (minVal === 'max-content' || minVal === 'min-content') {\n needsMaxContentMeasure.push(columnId);\n }\n } else {\n fixedTotal += px;\n }\n });\n\n return { widths, fixedTotal, flexIds, mins, needsMaxContentMeasure };\n}\n\nexport function measureMaxContentMins(\n tableEl: HTMLElement,\n headers: NodeListOf<Element>,\n visualOrder: string[],\n columnsToMeasure: string[],\n getColumnGrid: GetColumnGrid,\n): Record<string, number> {\n const mins: Record<string, number> = {};\n if (columnsToMeasure.length === 0) return mins;\n\n const origTemplate = tableEl.style.gridTemplateColumns;\n tableEl.style.gridTemplateColumns = visualOrder.map(() => 'max-content').join(' ');\n\n Array.from(headers).forEach((header, idx) => {\n const colId = visualOrder[idx];\n if (colId && columnsToMeasure.includes(colId)) {\n let measured = header.getBoundingClientRect().width;\n const grid = getColumnGrid(colId);\n if (grid && 'minCap' in grid && grid.minCap) {\n measured = Math.min(measured, parseFloat(grid.minCap) || measured);\n }\n mins[colId] = measured;\n }\n });\n\n tableEl.style.gridTemplateColumns = origTemplate;\n return mins;\n}\n\nexport interface GridTemplateInput {\n headers: { columnId: string; size: number; grid?: GridColumnSizing }[];\n gridMeasuredMins: Record<string, number>;\n}\n\n/**\n * The live rendered width comes from the `--col-fr-<id>` CSS custom property,\n * not the static `flex` number.\n *\n * A capped flex column (`grid.max` set) does NOT wrap that var in `min()` —\n * `fr` cannot be mixed with a length inside `min()`/`max()`/`clamp()` (they\n * require same-typed arguments), so `min(160px, var(--col-fr-id, 1fr))` is\n * invalid CSS. An invalid track invalidates the *entire*\n * `grid-template-columns` declaration, silently collapsing every column\n * (confirmed in a real browser, not just jsdom string assertions — the\n * legacy source this was ported from has the same construct and was never\n * verified against real Grid layout either). Instead, a capped column's max\n * is the literal `grid.max` value — a fixed ceiling, not itself live-resizable.\n */\nexport function getGridColumnTemplate({ headers, gridMeasuredMins }: GridTemplateInput): string {\n return headers\n .map(h => {\n const { grid } = h;\n if (!grid) return `${h.size}px`;\n if ('fixed' in grid && grid.fixed) return grid.fixed;\n if ('flex' in grid && grid.flex != null) {\n const varName = `--col-fr-${h.columnId}`;\n const measuredMin = gridMeasuredMins[h.columnId];\n const min = measuredMin != null ? `${measuredMin}px` : (grid.min ?? 'auto');\n const max = grid.max ?? `var(${varName}, ${grid.flex}fr)`;\n return `minmax(${min}, ${max})`;\n }\n return `${h.size}px`;\n })\n .join(' ');\n}\n\nexport function findContentMinColumns(visualOrder: string[], getColumnGrid: GetColumnGrid): string[] {\n return visualOrder.filter(colId => {\n const grid = getColumnGrid(colId);\n return grid && 'flex' in grid && grid.flex != null && (grid.min === 'max-content' || grid.min === 'min-content');\n });\n}\n\nexport interface SnapshotResizeStartInput {\n headers: NodeListOf<Element>;\n visualOrder: string[];\n getColumnGrid: GetColumnGrid;\n tableEl: HTMLElement | null;\n}\n\nexport interface SnapshotResizeStartResult {\n widths: Record<string, number>;\n meta: GridResizeSnapshotMeta;\n}\n\nexport function snapshotResizeStart({\n headers,\n visualOrder,\n getColumnGrid,\n tableEl,\n}: SnapshotResizeStartInput): SnapshotResizeStartResult | null {\n if (!headers || visualOrder.length !== headers.length) return null;\n\n const snapshot = computeGridResizeSnapshot({ headers, visualOrder, getColumnGrid });\n\n if (tableEl && snapshot.needsMaxContentMeasure.length > 0) {\n const measuredMins = measureMaxContentMins(\n tableEl,\n headers,\n visualOrder,\n snapshot.needsMaxContentMeasure,\n getColumnGrid,\n );\n Object.assign(snapshot.mins, measuredMins);\n }\n\n const containerWidth = tableEl?.getBoundingClientRect().width ?? 0;\n\n return {\n widths: snapshot.widths,\n meta: {\n containerWidth,\n fixedTotal: snapshot.fixedTotal,\n flexIds: snapshot.flexIds,\n mins: snapshot.mins,\n },\n };\n}\n","'use client';\n\nimport type * as React from 'react';\n\nimport { Alert, AlertDescription } from '@upbound/monarch-core';\nimport { Button } from '@upbound/monarch-core';\nimport { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from '@upbound/monarch-core';\nimport { Icon } from '@upbound/monarch-core';\nimport { IconTile } from '@upbound/monarch-core';\nimport type { IconName } from '@upbound/monarch-core';\nimport { cn } from '@/lib/utils';\nimport type { TableDataState } from '@/lib/data-table/utils';\n\n/**\n * Monarch-native equivalent of TableWrapper's `EmptyConfig` — same four\n * states (error / empty / filtered-empty), rebuilt on Monarch's `Empty`\n * compound API instead of a single props-driven component. Two deliberate\n * adaptations: `icon` takes a Monarch `IconName` (no FontAwesome dependency),\n * and `action` is a rendered node rather than a `ComponentType` reference.\n * `details` has no native `Empty` slot — it composes `Alert` instead.\n */\nexport type DataTableEmptyConfig = {\n icon?: IconName;\n header?: React.ReactNode;\n subheader?: React.ReactNode;\n details?: React.ReactNode;\n action?: React.ReactNode;\n className?: string;\n wrapperClassName?: string;\n};\n\nexport type DataTableEmptyView = {\n empty?: DataTableEmptyConfig;\n error?: DataTableEmptyConfig;\n filter?: DataTableEmptyConfig;\n};\n\nexport const defaultErrorConfig: DataTableEmptyConfig = {\n icon: 'circle-exclamation',\n header: 'Something went wrong',\n subheader: \"We couldn't load this data. Try again in a moment.\",\n};\n\nexport const defaultEmptyConfig: DataTableEmptyConfig = {\n icon: 'inbox',\n header: 'No results',\n subheader: \"There's nothing here yet.\",\n};\n\nexport const defaultNoFilterFoundConfig: DataTableEmptyConfig = {\n icon: 'magnifying-glass',\n header: 'No matching results',\n subheader: 'Try adjusting your search or filters.',\n};\n\nexport function DataTableEmptyView({\n emptyView,\n tableState,\n filterCount,\n resetFilters,\n className,\n}: {\n emptyView?: DataTableEmptyView;\n /** `'success'`/`'loading'` render nothing here — the table body handles those. */\n tableState: TableDataState;\n filterCount: number;\n resetFilters: () => void;\n className?: string;\n}) {\n const isFilteredEmpty = tableState === 'empty' && filterCount > 0;\n const config =\n tableState === 'error'\n ? (emptyView?.error ?? defaultErrorConfig)\n : tableState === 'empty'\n ? isFilteredEmpty\n ? (emptyView?.filter ?? defaultNoFilterFoundConfig)\n : (emptyView?.empty ?? defaultEmptyConfig)\n : null;\n\n // Mirrors a quirk in the source: an error config without its own\n // `wrapperClassName` falls back to the *empty* config's, not its own type's default.\n const wrapperClassName =\n tableState === 'error'\n ? (emptyView?.error?.wrapperClassName ?? emptyView?.empty?.wrapperClassName)\n : config?.wrapperClassName;\n\n const defaultAction =\n isFilteredEmpty && !config?.action ? (\n <Button variant=\"outline\" size=\"sm\" onClick={resetFilters}>\n <Icon name=\"xmark\" />\n Clear filters\n </Button>\n ) : null;\n\n return (\n <div className={cn('flex size-full flex-col justify-center p-6', wrapperClassName, className)}>\n {config && (\n // The error state ignores its own config's `className` for outer\n // padding, matching the source's forced `pt-0` on that branch.\n <Empty className={tableState === 'error' ? 'pt-0' : config.className}>\n <EmptyHeader>\n {config.icon && (\n <EmptyMedia>\n <IconTile variant=\"branded\">\n <Icon name={config.icon} />\n </IconTile>\n </EmptyMedia>\n )}\n {config.header && <EmptyTitle>{config.header}</EmptyTitle>}\n {config.subheader && <EmptyDescription>{config.subheader}</EmptyDescription>}\n </EmptyHeader>\n {(config.details || config.action || defaultAction) && (\n <EmptyContent>\n {config.details && (\n <Alert>\n <AlertDescription>{config.details}</AlertDescription>\n </Alert>\n )}\n {config.action ?? defaultAction}\n </EmptyContent>\n )}\n </Empty>\n )}\n </div>\n );\n}\n","'use client';\n\nimport { Button } from '@upbound/monarch-core';\nimport { Icon } from '@upbound/monarch-core';\nimport { Label } from '@upbound/monarch-core';\nimport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n} from '@upbound/monarch-core';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@upbound/monarch-core';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@upbound/monarch-core';\nimport { getPaginationInfo } from '@/lib/data-table/utils';\nimport { useMounted } from '@/hooks/use-mounted';\n\nexport type RowCountRelation = 'eq' | 'gt';\n\n/** Pass `true` for defaults, `false` to disable the footer entirely (handled by the caller, not this component), or an object to toggle individual parts. */\nexport type DataTablePaginationConfig =\n | boolean\n | {\n /** Shows \"Showing 1 to 20 of 25 results\". @default true */\n summary?: boolean;\n /** Shows the first/previous/next/last icon buttons. @default true */\n arrows?: boolean;\n /** Shows numeric page buttons alongside the arrows. @default false */\n numbers?: boolean;\n /** Shows the rows-per-page selector. @default true */\n pageSizeSelector?: boolean;\n /** Options offered in the rows-per-page selector. @default [10, 20, 30, 40, 50, 60, 70, 80, 90, 100] */\n pageSizeOptions?: number[];\n };\n\nconst DEFAULT_PAGINATION_CONFIG = {\n summary: true,\n arrows: true,\n numbers: false,\n pageSizeSelector: true,\n pageSizeOptions: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100],\n};\nconst PAGE_SIZE_SELECT_ID = 'table-page-size-select';\n\nfunction getPageSizeOptions(pageSizeOptions: number[]): number[] {\n return Array.from(new Set(pageSizeOptions))\n .filter(option => option > 0)\n .sort((a, b) => a - b);\n}\n\nfunction getEffectivePageSize(pageSize: number, pageSizeOptions: number[]): number {\n if (pageSizeOptions.length === 0 || pageSizeOptions.includes(pageSize)) return pageSize;\n return pageSizeOptions.reduce(\n (closest, option) => (Math.abs(option - pageSize) < Math.abs(closest - pageSize) ? option : closest),\n pageSizeOptions[0],\n );\n}\n\n/** Dedupes/sorts `pageSizeOptions`, and snaps `pageSize` to the nearest option when it isn't one (ties go to the lower value). */\nexport function normalizePageSizeOptions(pageSize: number, pageSizeOptions: number[]) {\n const normalizedPageSizeOptions = getPageSizeOptions(pageSizeOptions);\n return { normalizedPageSizeOptions, effectivePageSize: getEffectivePageSize(pageSize, normalizedPageSizeOptions) };\n}\n\nexport type DataTablePaginationProps = {\n pageIndex: number;\n pageSize: number;\n rowCount: number;\n /** `'gt'` renders \"N+ results\" with an explanatory tooltip, for an inexact/server-estimated count. @default 'eq' */\n rowCountRelation?: RowCountRelation;\n paginationConfig?: DataTablePaginationConfig;\n /** Called with the 1-based page number the user navigated to. */\n onPageChange: (page: number) => void;\n onPageSizeChange: (pageSize: number) => void;\n};\n\nexport function DataTablePagination({\n pageIndex,\n pageSize,\n rowCount,\n rowCountRelation = 'eq',\n paginationConfig = true,\n onPageChange,\n onPageSizeChange,\n}: DataTablePaginationProps) {\n const isRowCountExact = rowCountRelation === 'eq';\n const resolved =\n typeof paginationConfig === 'object'\n ? { ...DEFAULT_PAGINATION_CONFIG, ...paginationConfig }\n : DEFAULT_PAGINATION_CONFIG;\n\n const { normalizedPageSizeOptions, effectivePageSize } = normalizePageSizeOptions(pageSize, resolved.pageSizeOptions);\n const { visiblePages, pageCount, itemStart, itemEnd } = getPaginationInfo(pageIndex, rowCount, effectivePageSize);\n const currentPage = pageIndex + 1;\n const mounted = useMounted();\n // Fixed locale for the server-rendered/first-paint value (the server can't\n // know the viewer's locale); the viewer's actual locale once mounted — per\n // Monarch's \"use locale-aware formatting\" content principle for counts.\n const locale = mounted ? undefined : 'en-US';\n\n return (\n <div data-testid=\"table-footer\" className=\"flex items-center justify-between px-2 pt-4\">\n {resolved.summary ? (\n <div className=\"text-body text-muted-foreground\" data-testid=\"table-pagination-summary\">\n Showing <span className=\"text-foreground font-medium\">{itemStart.toLocaleString(locale)}</span> to{' '}\n <span className=\"text-foreground font-medium\">{itemEnd.toLocaleString(locale)}</span> of{' '}\n <span className=\"text-foreground font-medium\">\n {rowCount.toLocaleString(locale)}\n {!isRowCountExact && '+'}\n </span>{' '}\n results\n {!isRowCountExact && (\n <Tooltip>\n <TooltipTrigger className=\"ml-1 align-middle\">\n <Icon name=\"circle-info\" size=\"sm\" />\n </TooltipTrigger>\n <TooltipContent>Add filters or refine your search to reduce the result set.</TooltipContent>\n </Tooltip>\n )}\n </div>\n ) : (\n <div />\n )}\n\n <div className=\"flex items-center gap-4\">\n {resolved.pageSizeSelector && (\n <div className=\"flex items-center gap-2\">\n <Label htmlFor={PAGE_SIZE_SELECT_ID} className=\"font-semibold\">\n Rows per page\n </Label>\n <Select value={String(effectivePageSize)} onValueChange={value => onPageSizeChange(Number(value))}>\n <SelectTrigger id={PAGE_SIZE_SELECT_ID} size=\"sm\" className=\"w-18\" data-testid=\"table-page-size-select\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent align=\"end\">\n <SelectGroup>\n {normalizedPageSizeOptions.map(option => (\n <SelectItem key={option} value={String(option)}>\n {option}\n </SelectItem>\n ))}\n </SelectGroup>\n </SelectContent>\n </Select>\n </div>\n )}\n\n {pageCount > 1 && (resolved.arrows || resolved.numbers) && (\n <Pagination className=\"mx-0 w-auto justify-end\">\n <PaginationContent>\n {resolved.arrows && (\n <PaginationItem>\n <Button\n variant=\"outline\"\n size=\"icon\"\n aria-label=\"Go to first page\"\n disabled={currentPage <= 1}\n onClick={() => onPageChange(1)}\n >\n <Icon name=\"chevrons-left\" className=\"cn-rtl-flip\" />\n </Button>\n </PaginationItem>\n )}\n {resolved.arrows && (\n <PaginationItem>\n <Button\n variant=\"outline\"\n size=\"icon\"\n aria-label=\"Go to previous page\"\n disabled={currentPage <= 1}\n onClick={() => onPageChange(currentPage - 1)}\n >\n <Icon name=\"chevron-left\" className=\"cn-rtl-flip\" />\n </Button>\n </PaginationItem>\n )}\n {resolved.numbers &&\n visiblePages.map((page, index) =>\n page === undefined ? (\n <PaginationItem key={`ellipsis-${index}`}>\n <PaginationEllipsis />\n </PaginationItem>\n ) : (\n <PaginationItem key={page}>\n <PaginationLink\n href=\"#\"\n isActive={page === currentPage}\n onClick={e => {\n e.preventDefault();\n onPageChange(page);\n }}\n >\n {page}\n </PaginationLink>\n </PaginationItem>\n ),\n )}\n {resolved.arrows && (\n <PaginationItem>\n <Button\n variant=\"outline\"\n size=\"icon\"\n aria-label=\"Go to next page\"\n disabled={currentPage >= pageCount}\n onClick={() => onPageChange(currentPage + 1)}\n >\n <Icon name=\"chevron-right\" className=\"cn-rtl-flip\" />\n </Button>\n </PaginationItem>\n )}\n {resolved.arrows && (\n <PaginationItem>\n <Button\n variant=\"outline\"\n size=\"icon\"\n aria-label=\"Go to last page\"\n disabled={currentPage >= pageCount}\n onClick={() => onPageChange(pageCount)}\n >\n <Icon name=\"chevrons-right\" className=\"cn-rtl-flip\" />\n </Button>\n </PaginationItem>\n )}\n </PaginationContent>\n </Pagination>\n )}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport {\n flexRender,\n type Cell,\n type Column,\n type ColumnFilter,\n type Header,\n type HeaderGroup,\n type Row,\n type RowData,\n type SortDirection,\n} from '@tanstack/react-table';\n\nimport { ContextMenu, ContextMenuTrigger } from '@upbound/monarch-core';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@upbound/monarch-core';\nimport { Icon } from '@upbound/monarch-core';\nimport { Skeleton } from '@upbound/monarch-core';\nimport {\n Table as BaseTable,\n TableBody as BaseTableBody,\n TableCell as BaseTableCell,\n TableHead as BaseTableHead,\n TableHeader as BaseTableHeader,\n TableRow as BaseTableRow,\n} from '@upbound/monarch-core';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@upbound/monarch-core';\nimport { cn } from '@/lib/utils';\nimport { getContextualColumnFilter, getContextualGlobalSearch } from '@/lib/data-table/contextual-filters';\nimport { isFilterOnlyColumn, type TableDataState } from '@/lib/data-table/utils';\nimport type { StickyHeaderConfig, TableLayout } from './data-table-types';\nimport { CellContextualFilter, type ContextualMenuAction } from './cell-contextual-filter';\n\n// ── Column pinning ─────────────────────────────────────\n\n/** Matches `TableHeader`'s own background (table.tsx) — pinned/sticky header cells need this instead of `bg-card` so they don't stand out as a different (white) shade from the rest of the grey header row. */\nconst HEADER_SURFACE_BG = 'bg-[color-mix(in_oklch,var(--muted)_50%,var(--card))]';\n\n/**\n * Grid mode (`layout=\"grid\"`) renders `<div role=\"...\">` markup instead of\n * `<table>/<thead>/<tbody>/<tr>/<th>/<td>`, so it can't reuse those elements'\n * own visual classes from `table.tsx`. These mirror them exactly — keep in\n * sync with `TableHead`/`TableCell`/`TableRow` in `table.tsx` (`@upbound/monarch-core`).\n */\nconst TABLE_HEAD_CLASSES =\n 'text-body-sm text-muted-foreground h-10 px-4 text-left align-middle font-medium whitespace-nowrap has-[[role=checkbox]]:pr-0';\nconst TABLE_CELL_CLASSES = 'px-4 py-2 align-middle whitespace-nowrap has-[[role=checkbox]]:pr-0';\nconst TABLE_ROW_CLASSES =\n 'hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted border-b motion-safe:transition-colors';\n\n/**\n * Renders the table root: `<Table>` (a native `<table>`) for `layout=\"auto\"`,\n * or a `<div role=\"table\">` grid container for `layout=\"grid\"` — the only\n * element with an actual `display:grid` + `grid-template-columns`. Every\n * nested rowgroup/row adopts these tracks via `grid-cols-subgrid` instead of\n * recomputing its own column widths.\n */\nexport function DataTableRoot({\n layout = 'auto',\n gridTemplateColumns,\n gridRootRef,\n className,\n style,\n children,\n}: {\n layout?: TableLayout;\n gridTemplateColumns?: string;\n /** Grid mode only — the live drag-resize CSS-var writer reads this ref directly. */\n gridRootRef?: React.RefObject<HTMLDivElement | null>;\n className?: string;\n style?: React.CSSProperties;\n children: React.ReactNode;\n}) {\n if (layout === 'grid') {\n return (\n <div\n ref={gridRootRef}\n role=\"table\"\n className={cn('text-body grid w-full', className)}\n style={{ ...style, gridTemplateColumns }}\n >\n {children}\n </div>\n );\n }\n return (\n <BaseTable className={className} style={style}>\n {children}\n </BaseTable>\n );\n}\n\n/** Sticky positioning + edge-border classes for a pinned column cell (header or body), either side. */\nfunction getColumnPinningProps<TData extends RowData, TValue>(\n column: Column<TData, TValue>,\n surface: 'header' | 'body' = 'body',\n): { className: string; style: React.CSSProperties } {\n const isPinned = column.getIsPinned();\n if (!isPinned) return { className: '', style: {} };\n\n const isLastLeft = isPinned === 'left' && column.getIsLastColumn('left');\n const isFirstRight = isPinned === 'right' && column.getIsFirstColumn('right');\n\n return {\n className: cn(\n 'sticky',\n surface === 'header' ? HEADER_SURFACE_BG : 'bg-card',\n isLastLeft && 'border-r-2 border-r-border',\n isFirstRight && 'border-l-2 border-l-border',\n ),\n style: {\n left: isPinned === 'left' ? `${column.getStart('left')}px` : undefined,\n right: isPinned === 'right' ? `${column.getAfter('right')}px` : undefined,\n width: column.getSize(),\n },\n };\n}\n\n// ── Sort indicator ──────────────────────────────────────\n\nfunction DataTableSortIcon({ sortOrder }: { sortOrder: SortDirection | false }) {\n if (!sortOrder) return null;\n return (\n <Icon\n name={sortOrder === 'asc' ? 'arrow-up' : 'arrow-down'}\n size=\"xs\"\n className=\"text-primary group-hover/col-actions:text-foreground group-data-[state=open]/col-actions:text-foreground mr-0.5 shrink-0\"\n />\n );\n}\n\n// ── Column actions dropdown ─────────────────────────────\n// The dropdown's trigger is the whole header label (name + sort icon +\n// ellipsis) — see `HeaderCellContent` — so this only builds the menu content.\n\nfunction ColumnActionsMenuItems<TData extends RowData, TValue>({\n header,\n onAutosizeAll,\n onAutosizeColumn,\n layout = 'auto',\n}: {\n header: Header<TData, TValue>;\n onAutosizeAll: () => void;\n onAutosizeColumn: (columnId: string) => void;\n layout?: TableLayout;\n}) {\n const isGrid = layout === 'grid';\n const canSort = header.column.getCanSort();\n const canResize = header.column.getCanResize();\n const canHide = header.column.getCanHide();\n const canPin = !isGrid && header.column.getCanPin();\n\n return (\n <DropdownMenuContent align=\"start\" className=\"w-45\">\n {canSort && (\n <>\n <DropdownMenuItem\n disabled={header.column.getIsSorted() === 'asc'}\n onClick={() => header.column.toggleSorting(false)}\n >\n <Icon name=\"arrow-up\" />\n Sort ascending\n </DropdownMenuItem>\n <DropdownMenuItem\n disabled={header.column.getIsSorted() === 'desc'}\n onClick={() => header.column.toggleSorting(true)}\n >\n <Icon name=\"arrow-down\" />\n Sort descending\n </DropdownMenuItem>\n {!!header.column.getIsSorted() && (\n <DropdownMenuItem onClick={() => header.column.clearSorting()}>\n <Icon name=\"xmark\" />\n Remove sorting\n </DropdownMenuItem>\n )}\n </>\n )}\n\n {canResize && (\n <>\n {canSort && <DropdownMenuSeparator />}\n {!isGrid && (\n <DropdownMenuItem onClick={() => onAutosizeColumn(header.column.id)}>\n <Icon name=\"arrows-left-right\" />\n Autosize column\n </DropdownMenuItem>\n )}\n <DropdownMenuItem onClick={() => onAutosizeAll()}>\n <Icon name=\"table-columns\" />\n {isGrid ? 'Reset all columns' : 'Autosize all columns'}\n </DropdownMenuItem>\n </>\n )}\n\n {(canHide || canPin) && (\n <>\n {(canSort || canResize) && <DropdownMenuSeparator />}\n {canHide && (\n <DropdownMenuItem onClick={() => header.column.toggleVisibility()}>\n <Icon name=\"eye-slash\" />\n Hide column\n </DropdownMenuItem>\n )}\n {canPin &&\n (header.column.getIsPinned() ? (\n <DropdownMenuItem onClick={() => header.column.pin(false)}>\n <Icon name=\"thumbtack\" />\n Unpin column\n </DropdownMenuItem>\n ) : (\n <DropdownMenuItem onClick={() => header.column.pin('left')}>\n <Icon name=\"thumbtack\" />\n Pin column\n </DropdownMenuItem>\n ))}\n </>\n )}\n </DropdownMenuContent>\n );\n}\n\n// ── Header cell content ─────────────────────────────────\n\nfunction HeaderCellContent<TData extends RowData, TValue>({\n header,\n canResize,\n isActionColumn,\n isGroupedColumn,\n shouldShowActionsMenu,\n onAutosizeAll,\n onAutosizeColumn,\n onResetColumnSize,\n layout = 'auto',\n}: {\n header: Header<TData, TValue>;\n canResize: boolean;\n isActionColumn: boolean;\n isGroupedColumn: boolean;\n shouldShowActionsMenu: boolean;\n onAutosizeAll: () => void;\n onAutosizeColumn: (columnId: string) => void;\n onResetColumnSize: (columnId: string) => void;\n layout?: TableLayout;\n}) {\n const resizeHandler = header.getResizeHandler();\n const headerTitle = typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : '';\n const sorted = header.column.getIsSorted();\n\n // One trigger for the whole label — name, sort icon, and the ellipsis all\n // live inside it, in that order, so the ellipsis always sits immediately\n // next to whichever of the two (sort icon, else name) renders last. The\n // named group (`col-actions`) is scoped to this button specifically, so it\n // doesn't fight the header cell's own (unnamed) `group` that drives the\n // resize handle's hover reveal.\n const labelButton = (\n <button\n type=\"button\"\n aria-label={\n shouldShowActionsMenu ? (headerTitle ? `${headerTitle} column actions` : 'Column actions') : undefined\n }\n className={cn(\n 'group/col-actions text-muted-foreground -mx-2 -my-1 flex min-w-0 items-center gap-1 truncate rounded-md px-2 py-1 text-left font-medium motion-safe:transition-colors',\n sorted && 'text-primary',\n shouldShowActionsMenu\n ? 'hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 cursor-pointer'\n : 'cursor-default',\n )}\n >\n <DataTableSortIcon sortOrder={sorted} />\n <span className=\"min-w-0 truncate\">{flexRender(header.column.columnDef.header, header.getContext())}</span>\n\n {shouldShowActionsMenu && (\n <Icon\n size=\"sm\"\n name=\"ellipsis\"\n className=\"ml-1 shrink-0 opacity-0 transition-none group-hover/col-actions:opacity-100 group-focus-visible/col-actions:opacity-100 group-data-[state=open]/col-actions:opacity-100\"\n />\n )}\n </button>\n );\n\n const label = shouldShowActionsMenu ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>{labelButton}</DropdownMenuTrigger>\n <ColumnActionsMenuItems\n header={header}\n onAutosizeAll={onAutosizeAll}\n onAutosizeColumn={onAutosizeColumn}\n layout={layout}\n />\n </DropdownMenu>\n ) : (\n labelButton\n );\n\n return (\n <>\n <div className=\"flex min-w-0 items-center gap-1\">\n <div className=\"min-w-0 flex-1\">\n {!isActionColumn &&\n !isGroupedColumn &&\n (headerTitle ? (\n <Tooltip>\n <TooltipTrigger asChild>{label}</TooltipTrigger>\n <TooltipContent>{headerTitle}</TooltipContent>\n </Tooltip>\n ) : (\n label\n ))}\n </div>\n </div>\n\n {canResize && (\n <button\n type=\"button\"\n aria-label=\"Resize column\"\n className=\"hover:border-primary absolute top-0 right-0 z-10 h-full w-2 cursor-col-resize border-r border-transparent opacity-0 group-hover:opacity-100 hover:opacity-100 motion-safe:transition-opacity\"\n onMouseDown={resizeHandler}\n onDoubleClick={e => {\n e.preventDefault();\n onResetColumnSize(header.column.id);\n }}\n />\n )}\n </>\n );\n}\n\n// ── Header ───────────────────────────────────────────────\n\nconst DEFAULT_STICKY_HEADER_OFFSET_PX = 0;\nconst DEFAULT_STICKY_HEADER_ROW_HEIGHT_PX = 48;\n\nexport function DataTableHeader<TData extends RowData>({\n headerGroups,\n onAutosizeAll,\n onAutosizeColumn,\n onResetColumnSize,\n stickyHeader,\n layout = 'auto',\n}: {\n headerGroups: HeaderGroup<TData>[];\n onAutosizeAll: () => void;\n onAutosizeColumn: (columnId: string) => void;\n /** Called when the user double-clicks the resize separator to reset a column to its default size. */\n onResetColumnSize: (columnId: string) => void;\n stickyHeader?: StickyHeaderConfig;\n layout?: TableLayout;\n}) {\n const isGrid = layout === 'grid';\n const stickyHeaderOffset =\n typeof stickyHeader === 'object'\n ? (stickyHeader?.offset ?? DEFAULT_STICKY_HEADER_OFFSET_PX)\n : DEFAULT_STICKY_HEADER_OFFSET_PX;\n const stickyHeaderRowHeight =\n typeof stickyHeader === 'object'\n ? (stickyHeader?.rowHeight ?? DEFAULT_STICKY_HEADER_ROW_HEIGHT_PX)\n : DEFAULT_STICKY_HEADER_ROW_HEIGHT_PX;\n\n const renderHeaders = (headerGroup: HeaderGroup<TData>, headerGroupIndex: number) => {\n const visibleHeaders = headerGroup.headers.filter(header => !isFilterOnlyColumn(header.column));\n\n return visibleHeaders.map((header, headerIndex) => {\n const meta = header.column.columnDef.meta;\n const isActionColumn = !!meta?.actions;\n const isGroupedColumn = header.column.getIsGrouped();\n const canSort = header.column.getCanSort();\n // Grid mode's last column has no right-side flex neighbor to absorb a\n // resize into (`computeGridResizeFrValues` prefers the right side) —\n // dragging it would try to grow the grid past its container.\n const isLastColumn = isGrid && headerIndex === visibleHeaders.length - 1;\n const canResize = header.column.getCanResize() && !isLastColumn;\n const canHide = header.column.getCanHide();\n const canPin = !isGrid && header.column.getCanPin();\n const shouldShowActionsMenu = !isGroupedColumn && !isActionColumn && (canSort || canResize || canHide || canPin);\n const stickyTopPx = stickyHeader ? stickyHeaderOffset + headerGroupIndex * stickyHeaderRowHeight : undefined;\n const isPinned = !isGrid && header.column.getIsPinned();\n const pinning = isGrid ? { className: '', style: {} } : getColumnPinningProps(header.column, 'header');\n\n const content = (\n <HeaderCellContent\n header={header}\n canResize={canResize}\n isActionColumn={isActionColumn}\n isGroupedColumn={isGroupedColumn}\n shouldShowActionsMenu={shouldShowActionsMenu}\n onAutosizeAll={onAutosizeAll}\n onAutosizeColumn={onAutosizeColumn}\n onResetColumnSize={onResetColumnSize}\n layout={layout}\n />\n );\n\n const cellClassName = cn(\n 'group relative overflow-visible text-left',\n !!stickyHeader && cn(HEADER_SURFACE_BG, 'sticky z-20'),\n pinning.className,\n isPinned && 'z-30',\n );\n\n if (isGrid) {\n return (\n <div\n key={header.id}\n role=\"columnheader\"\n className={cn(TABLE_HEAD_CLASSES, cellClassName, 'h-auto py-1.5 whitespace-normal')}\n style={{\n minWidth: header.column.columnDef.minSize,\n ...(stickyTopPx !== undefined ? { top: stickyTopPx } : {}),\n }}\n >\n {content}\n </div>\n );\n }\n\n return (\n <BaseTableHead\n key={header.id}\n className={cn(cellClassName, 'h-auto py-1.5 whitespace-normal')}\n style={{\n ...pinning.style,\n minWidth: header.column.columnDef.minSize,\n maxWidth: header.column.columnDef.maxSize,\n ...(!isPinned ? { width: header.column.getSize() } : {}),\n ...(stickyTopPx !== undefined ? { top: stickyTopPx } : {}),\n }}\n >\n {content}\n </BaseTableHead>\n );\n });\n };\n\n if (isGrid) {\n return (\n <div\n role=\"rowgroup\"\n className={cn('col-span-full grid grid-cols-subgrid', HEADER_SURFACE_BG, !!stickyHeader && 'sticky z-20')}\n style={stickyHeader ? { top: stickyHeaderOffset } : undefined}\n >\n {headerGroups.map((headerGroup, headerGroupIndex) => (\n <div key={headerGroup.id} role=\"row\" className=\"col-span-full grid grid-cols-subgrid border-b\">\n {renderHeaders(headerGroup, headerGroupIndex)}\n </div>\n ))}\n </div>\n );\n }\n\n return (\n <BaseTableHeader>\n {headerGroups.map((headerGroup, headerGroupIndex) => (\n <BaseTableRow key={headerGroup.id}>{renderHeaders(headerGroup, headerGroupIndex)}</BaseTableRow>\n ))}\n </BaseTableHeader>\n );\n}\n\n// ── Row ──────────────────────────────────────────────────\n\nexport type DataTableRowProps = React.HTMLAttributes<HTMLElement> & {\n hoverable?: boolean;\n disabled?: boolean;\n layout?: TableLayout;\n};\n\nexport const DataTableRow = React.forwardRef<HTMLElement, DataTableRowProps>(\n ({ hoverable, disabled, className, layout = 'auto', ...props }, ref) => {\n const classes = cn(\n 'break-all',\n hoverable && 'cursor-pointer',\n disabled && 'cursor-not-allowed opacity-80',\n className,\n );\n\n if (layout === 'grid') {\n return (\n <div\n ref={ref as React.Ref<HTMLDivElement>}\n role=\"row\"\n className={cn(TABLE_ROW_CLASSES, 'col-span-full grid grid-cols-subgrid', classes)}\n {...props}\n />\n );\n }\n\n return <BaseTableRow ref={ref as React.Ref<HTMLTableRowElement>} className={classes} {...props} />;\n },\n);\nDataTableRow.displayName = 'DataTableRow';\n\n// ── Cell ─────────────────────────────────────────────────\n\nexport function DataTableCell<TData extends RowData, TValue>({\n cell,\n className,\n showContextualFilter,\n onContextCell,\n onContextSearch,\n contextualMenuActions,\n layout = 'auto',\n}: {\n cell: Cell<TData, TValue>;\n className?: string;\n showContextualFilter?: boolean;\n onContextCell?: (filter: ColumnFilter, cell: Cell<TData, TValue>) => void;\n onContextSearch?: (searchTerm: string, cell: Cell<TData, TValue>) => void;\n contextualMenuActions?: ContextualMenuAction<TData, TValue>[];\n layout?: TableLayout;\n}) {\n const isGrid = layout === 'grid';\n const meta = cell.column.columnDef.meta;\n const isActions = !!meta?.actions;\n const shouldTruncate = !isActions;\n const isPinned = !isGrid && cell.column.getIsPinned();\n const pinning = isGrid ? { className: '', style: {} } : getColumnPinningProps(cell.column);\n const shouldShowContextualMenu = !!showContextualFilter && !!onContextCell && !isActions;\n const contextualGlobalSearch = shouldShowContextualMenu ? getContextualGlobalSearch(cell) : undefined;\n const contextualFilter = shouldShowContextualMenu ? getContextualColumnFilter(cell) : undefined;\n const content = flexRender(cell.column.columnDef.cell, cell.getContext());\n\n const cellClassName = cn(\n isActions && 'text-right',\n shouldTruncate && 'overflow-hidden text-ellipsis whitespace-nowrap',\n isGrid && 'flex items-center',\n pinning.className,\n isPinned && 'z-10',\n className,\n );\n\n const cellElement = isGrid ? (\n <div\n role=\"cell\"\n className={cn(TABLE_CELL_CLASSES, cellClassName)}\n style={{ minWidth: cell.column.columnDef.minSize }}\n >\n {content}\n </div>\n ) : (\n <BaseTableCell\n className={cellClassName}\n style={{\n ...pinning.style,\n ...(!isPinned ? { width: cell.column.getSize() } : {}),\n minWidth: cell.column.columnDef.minSize,\n maxWidth: cell.column.columnDef.maxSize,\n }}\n >\n {content}\n </BaseTableCell>\n );\n\n if (!shouldShowContextualMenu || !onContextCell) return cellElement;\n\n return (\n <ContextMenu>\n <ContextMenuTrigger asChild>{cellElement}</ContextMenuTrigger>\n <CellContextualFilter\n filter={contextualFilter}\n globalSearch={contextualGlobalSearch}\n cell={cell}\n onContextCell={onContextCell}\n onContextSearch={onContextSearch}\n contextualMenuActions={contextualMenuActions}\n />\n </ContextMenu>\n );\n}\n\n// ── Group row ────────────────────────────────────────────\n\nexport function DataTableGroupRow({\n groupLabel,\n colSpan,\n layout = 'auto',\n}: {\n groupLabel: string;\n colSpan: number;\n layout?: TableLayout;\n}) {\n if (layout === 'grid') {\n return (\n <div role=\"row\" className=\"bg-muted/50 hover:bg-muted/50 col-span-full grid grid-cols-subgrid\">\n <div\n role=\"cell\"\n style={{ gridColumn: `span ${colSpan}` }}\n className=\"text-foreground border-b px-4 py-2 font-semibold whitespace-nowrap\"\n >\n {groupLabel}\n </div>\n </div>\n );\n }\n return (\n <BaseTableRow className=\"bg-muted/50 hover:bg-muted/50\">\n <BaseTableCell colSpan={colSpan} className=\"text-foreground border-b font-semibold whitespace-nowrap\">\n {groupLabel}\n </BaseTableCell>\n </BaseTableRow>\n );\n}\n\n// ── Skeleton (loading) rows ──────────────────────────────\n\nexport type SkeletonColumn = { id: string; size?: number; minSize?: number; maxSize?: number };\n\nexport function DataTableSkeletonBody({\n rowCount = 10,\n columns,\n renderCell,\n layout = 'auto',\n}: {\n rowCount?: number;\n columns: SkeletonColumn[];\n renderCell?: (columnId: string) => React.ReactNode | undefined;\n layout?: TableLayout;\n}) {\n const isGrid = layout === 'grid';\n const rows = Array.from({ length: rowCount }).map((_, rowIndex) => (\n <DataTableRow key={`skeleton-row-${rowIndex}`} layout={layout}>\n {columns.map(col =>\n isGrid ? (\n <div\n key={`skeleton-col-${col.id}-row-${rowIndex}`}\n role=\"cell\"\n className={cn(TABLE_CELL_CLASSES, 'flex items-center overflow-hidden')}\n style={{ minWidth: col.minSize }}\n >\n {renderCell?.(col.id) ?? <Skeleton className=\"h-4 w-full\" />}\n </div>\n ) : (\n <BaseTableCell\n key={`skeleton-col-${col.id}-row-${rowIndex}`}\n style={{ width: col.size, minWidth: col.minSize, maxWidth: col.maxSize }}\n >\n {renderCell?.(col.id) ?? <Skeleton className=\"h-4 w-full\" />}\n </BaseTableCell>\n ),\n )}\n </DataTableRow>\n ));\n\n if (isGrid) {\n return (\n <div role=\"rowgroup\" className=\"col-span-full grid grid-cols-subgrid\" data-testid=\"table-skeleton-loader\">\n {rows}\n </div>\n );\n }\n\n return <BaseTableBody data-testid=\"table-skeleton-loader\">{rows}</BaseTableBody>;\n}\n\n// ── Expanded row ─────────────────────────────────────────\n\nexport function DataTableExpandedRow({\n colSpan,\n show,\n children,\n layout = 'auto',\n}: {\n colSpan: number;\n show?: boolean;\n children: React.ReactNode;\n layout?: TableLayout;\n}) {\n if (!show) return null;\n if (layout === 'grid') {\n return (\n <div role=\"row\" className=\"col-span-full grid grid-cols-subgrid\">\n <div role=\"cell\" style={{ gridColumn: `span ${colSpan}` }} className=\"bg-card p-0 align-top whitespace-normal\">\n {children}\n </div>\n </div>\n );\n }\n return (\n <BaseTableRow className=\"hover:bg-transparent\">\n <BaseTableCell colSpan={colSpan} className=\"bg-card p-0 align-top whitespace-normal\">\n {children}\n </BaseTableCell>\n </BaseTableRow>\n );\n}\n\n// ── Body ─────────────────────────────────────────────────\n\nexport function DataTableBody<TData extends RowData>({\n tableRows,\n tableState,\n columns,\n skeletonRowCount,\n renderSkeletonCell,\n onRowRender,\n renderExpandedRow,\n showContextualFilter,\n onContextCell,\n onContextSearch,\n contextualMenuActions,\n layout = 'auto',\n}: {\n tableRows: Row<TData>[];\n tableState: TableDataState;\n columns: Column<TData, unknown>[];\n skeletonRowCount?: number;\n renderSkeletonCell?: (columnId: string) => React.ReactNode | undefined;\n onRowRender?: (row: TData) => DataTableRowProps;\n renderExpandedRow?: (row: TData) => React.ReactNode;\n showContextualFilter?: boolean;\n onContextCell?: (filter: ColumnFilter, cell: Cell<TData, unknown>) => void;\n onContextSearch?: (searchTerm: string, cell: Cell<TData, unknown>) => void;\n contextualMenuActions?: ContextualMenuAction<TData, unknown>[];\n layout?: TableLayout;\n}) {\n const isGrid = layout === 'grid';\n const visibleColumns = columns.filter(column => !isFilterOnlyColumn(column));\n const colSpan = visibleColumns.length;\n\n if (tableState === 'loading') {\n const skeletonColumns: SkeletonColumn[] = visibleColumns.map(c => ({\n id: c.id,\n size: c.columnDef.size,\n minSize: c.columnDef.minSize,\n maxSize: c.columnDef.maxSize,\n }));\n return (\n <DataTableSkeletonBody\n columns={skeletonColumns}\n rowCount={skeletonRowCount}\n renderCell={renderSkeletonCell}\n layout={layout}\n />\n );\n }\n\n const rows = tableRows.map(row => {\n if (row.getIsGrouped?.()) {\n const groupLabel =\n row.groupingValue ?? (row.groupingColumnId ? row.getGroupingValue?.(row.groupingColumnId) : undefined);\n return <DataTableGroupRow key={row.id} groupLabel={String(groupLabel ?? '')} colSpan={colSpan} layout={layout} />;\n }\n\n const isExpanded = !!(renderExpandedRow && row.getIsExpanded?.());\n const expandedRow = renderExpandedRow ? renderExpandedRow(row.original) : null;\n\n return (\n <React.Fragment key={row.id}>\n <DataTableRow\n {...(onRowRender ? onRowRender(row.original) : {})}\n data-expanded={isExpanded || undefined}\n layout={layout}\n >\n {row\n .getVisibleCells()\n .filter(cell => !isFilterOnlyColumn(cell.column))\n .map(cell => (\n <DataTableCell\n key={cell.id}\n cell={cell}\n showContextualFilter={showContextualFilter}\n onContextCell={onContextCell}\n onContextSearch={onContextSearch}\n contextualMenuActions={contextualMenuActions}\n layout={layout}\n />\n ))}\n </DataTableRow>\n <DataTableExpandedRow colSpan={colSpan} show={isExpanded} layout={layout}>\n {expandedRow}\n </DataTableExpandedRow>\n </React.Fragment>\n );\n });\n\n if (isGrid) {\n return (\n <div role=\"rowgroup\" className=\"col-span-full grid grid-cols-subgrid\">\n {rows}\n </div>\n );\n }\n\n return <BaseTableBody>{rows}</BaseTableBody>;\n}\n","'use client';\n\nimport * as React from 'react';\nimport type { Column, ColumnFiltersState, RowData } from '@tanstack/react-table';\n\nimport { ActiveFilter, FilterBar, type FilterDefinition, type FilterOption, type FilterValue } from '@/filter-bar';\nimport {\n isCheckboxColumnFilter,\n isDateRangeColumnFilter,\n isMultiTextColumnFilter,\n isRadioColumnFilter,\n type ColumnFilterDefinition,\n type ColumnFilterOption,\n type ColumnFilterValue,\n} from '@/lib/data-table/filter-types';\nimport { isFilterOnlyColumn } from '@/lib/data-table/utils';\n\nexport type ViewFilterProps<TData extends RowData> = {\n columns: Column<TData, unknown>[];\n columnFilters: ColumnFiltersState;\n onColumnFiltersChange: React.Dispatch<React.SetStateAction<ColumnFiltersState>>;\n className?: string;\n};\n\nfunction toFilterOption(opt: string | ColumnFilterOption): FilterOption {\n return typeof opt === 'string' ? { value: opt, label: opt } : { value: opt.value, label: opt.label };\n}\n\n/** Maps a column's `meta.filter` (the `ColumnFilterDefinition` vocabulary) onto Monarch `FilterBar`'s own `FilterDefinition` shape. */\nfunction toFilterBarDefinition(key: string, filter: ColumnFilterDefinition): FilterDefinition & { order: number } {\n const base = { key, label: filter.title, order: filter.order ?? 0 };\n\n if (isCheckboxColumnFilter(filter)) {\n const options = 'options' in filter && filter.options ? filter.options : [];\n return {\n ...base,\n type: 'checkbox',\n options: options.map(toFilterOption),\n searchable: filter.searchable ?? true,\n };\n }\n if (isRadioColumnFilter(filter)) {\n return {\n ...base,\n type: 'radio',\n options: filter.options.map(toFilterOption),\n searchable: filter.searchable ?? true,\n };\n }\n if (isDateRangeColumnFilter(filter)) {\n return { ...base, type: 'date', includeTime: filter.includeTime };\n }\n if (isMultiTextColumnFilter(filter)) {\n return { ...base, type: 'multiText', placeholder: filter.placeholder };\n }\n return { ...base, type: 'text', placeholder: filter.placeholder };\n}\n\n/** The empty value a filter starts at the moment it's added, before the user picks anything. */\nfunction emptyValueFor(filter: ColumnFilterDefinition): ColumnFilterValue {\n if (isCheckboxColumnFilter(filter)) return [];\n if (isRadioColumnFilter(filter)) return undefined;\n if (isDateRangeColumnFilter(filter)) return { startDate: null, endDate: null };\n if (isMultiTextColumnFilter(filter)) return [];\n return undefined;\n}\n\n/**\n * The plain (non-CEL) filter row — a thin state adapter over Monarch's\n * `FilterBar`, mirroring TableWrapper's own `ViewFilter` (itself just a\n * `FilterBar` adapter, not a hand-rolled UI). Every `meta.filter` shape\n * (checkbox, radio, dateRange, text, multiText) gets a chip here, mapped onto\n * the matching `FilterBar` chip type — checkbox and radio chips are\n * searchable by default (opt out per column via `meta.filter.searchable:\n * false`). CEL-based filtering (`celFilterConfig`) is the richer,\n * operator-driven tier this is not meant to replace.\n */\nexport function ViewFilter<TData extends RowData>({\n columns,\n columnFilters,\n onColumnFiltersChange,\n className,\n}: ViewFilterProps<TData>) {\n const filterableColumns = React.useMemo(\n () =>\n columns\n .filter(column => !isFilterOnlyColumn(column) && column.getCanFilter())\n .flatMap(column => {\n const filter = column.columnDef.meta?.filter;\n return filter ? [{ key: column.id, filter }] : [];\n }),\n [columns],\n );\n\n const filterDefinitions = React.useMemo<(FilterDefinition & { order: number })[]>(\n () =>\n filterableColumns.map(({ key, filter }) => toFilterBarDefinition(key, filter)).sort((a, b) => a.order - b.order),\n [filterableColumns],\n );\n\n const emptyValueByKey = React.useMemo(\n () => new Map(filterableColumns.map(({ key, filter }) => [key, emptyValueFor(filter)])),\n [filterableColumns],\n );\n\n const activeFilters = React.useMemo<ActiveFilter[]>(\n () => columnFilters.map(filter => ({ key: filter.id, value: filter.value as FilterValue | undefined })),\n [columnFilters],\n );\n\n return (\n <FilterBar\n className={className}\n filters={filterDefinitions}\n activeFilters={activeFilters}\n onAddFilter={key =>\n onColumnFiltersChange(prev => [...prev.filter(f => f.id !== key), { id: key, value: emptyValueByKey.get(key) }])\n }\n onRemoveFilter={key => onColumnFiltersChange(prev => prev.filter(f => f.id !== key))}\n onChangeFilter={(key, value) =>\n onColumnFiltersChange(prev => [...prev.filter(f => f.id !== key), { id: key, value }])\n }\n />\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport { type DateRange } from 'react-day-picker';\nimport { Icon } from '@upbound/monarch-core';\n\nimport { cn } from '@/lib/utils';\nimport { Badge } from '@upbound/monarch-core';\nimport { Button } from '@upbound/monarch-core';\nimport { ButtonGroup, ButtonGroupText } from '@upbound/monarch-core';\nimport { Calendar } from '@upbound/monarch-core';\nimport {\n Combobox,\n ComboboxChip,\n ComboboxClearAll,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxInput,\n ComboboxItem,\n ComboboxList,\n ComboboxSelectedChips,\n ComboboxSeparator,\n ComboboxTrigger,\n ComboboxValue,\n} from '@upbound/monarch-core';\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n} from '@upbound/monarch-core';\nimport { Input } from '@upbound/monarch-core';\nimport { Label } from '@upbound/monarch-core';\nimport { Popover, PopoverContent, PopoverTrigger } from '@upbound/monarch-core';\n\n// ── Types ─────────────────────────────────────────────\n\ntype FilterType = 'checkbox' | 'radio' | 'text' | 'multiText' | 'date';\n\ninterface FilterOption {\n value: string;\n label: string;\n icon?: React.ReactNode;\n}\n\ninterface FilterDefinitionBase {\n key: string;\n label: string;\n}\n\ninterface CheckboxFilterDefinition extends FilterDefinitionBase {\n type?: 'checkbox';\n options: FilterOption[];\n /**\n * When `true`, the chip's value popup becomes a searchable Combobox\n * (multi-select with a search input). Use for long option lists where a\n * basic dropdown becomes hard to scan. When `false` or omitted, the chip\n * uses the standard checkbox dropdown.\n */\n searchable?: boolean;\n}\n\ninterface RadioFilterDefinition extends FilterDefinitionBase {\n type: 'radio';\n options: FilterOption[];\n /** Same searchable-Combobox swap as `CheckboxFilterDefinition`, constrained to a single selection. */\n searchable?: boolean;\n}\n\ninterface TextFilterDefinition extends FilterDefinitionBase {\n type: 'text';\n placeholder?: string;\n}\n\ninterface MultiTextFilterDefinition extends FilterDefinitionBase {\n type: 'multiText';\n placeholder?: string;\n}\n\ninterface DateFilterDefinition extends FilterDefinitionBase {\n type: 'date';\n /**\n * `true` always shows Start/End time inputs, `false` never shows them,\n * and omitted auto-detects from whether the current value already carries\n * a non-midnight time component.\n */\n includeTime?: boolean;\n}\n\ntype FilterDefinition =\n | CheckboxFilterDefinition\n | RadioFilterDefinition\n | TextFilterDefinition\n | MultiTextFilterDefinition\n | DateFilterDefinition;\n\ntype CheckboxFilterValue = string[];\ntype RadioFilterValue = string;\ntype TextFilterValue = string;\ntype MultiTextFilterValue = string[];\ntype DateFilterValue = { startDate: Date | null; endDate: Date | null };\ntype FilterValue = CheckboxFilterValue | RadioFilterValue | TextFilterValue | MultiTextFilterValue | DateFilterValue;\n\ninterface ActiveFilter {\n key: string;\n value?: FilterValue;\n}\n\n// ── Value helpers ─────────────────────────────────────\n\nfunction asCheckboxValue(value: FilterValue | undefined): CheckboxFilterValue {\n return Array.isArray(value) ? value : [];\n}\n\nfunction asRadioValue(value: FilterValue | undefined): RadioFilterValue {\n return typeof value === 'string' ? value : '';\n}\n\nfunction asTextValue(value: FilterValue | undefined): TextFilterValue {\n return typeof value === 'string' ? value : '';\n}\n\nfunction asMultiTextValue(value: FilterValue | undefined): MultiTextFilterValue {\n return Array.isArray(value) ? value : [];\n}\n\nfunction asDateValue(value: FilterValue | undefined): DateFilterValue {\n if (value && typeof value === 'object' && !Array.isArray(value)) return value as DateFilterValue;\n return { startDate: null, endDate: null };\n}\n\nfunction hasExplicitTime(date: Date | null): boolean {\n if (!date) return false;\n return date.getHours() !== 0 || date.getMinutes() !== 0;\n}\n\nfunction formatTimeForInput(date: Date | null): string {\n if (!date) return '';\n return `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`;\n}\n\nfunction applyTimeToDate(date: Date, time: string): Date {\n const [hours, minutes] = time.split(':').map(Number);\n const next = new Date(date);\n next.setHours(hours || 0, minutes || 0, 0, 0);\n return next;\n}\n\nfunction formatDateLabel(date: Date): string {\n return date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });\n}\n\n// ── FilterBar ─────────────────────────────────────────\n\ninterface FilterBarProps extends React.ComponentProps<'div'> {\n filters: FilterDefinition[];\n activeFilters: ActiveFilter[];\n onAddFilter: (key: string) => void;\n onRemoveFilter: (key: string) => void;\n onChangeFilter: (key: string, value: FilterValue) => void;\n}\n\nfunction FilterBar({\n filters,\n activeFilters,\n onAddFilter,\n onRemoveFilter,\n onChangeFilter,\n className,\n children,\n ...props\n}: FilterBarProps) {\n const usedKeys = new Set(activeFilters.map(f => f.key));\n const availableFilters = filters.filter(f => !usedKeys.has(f.key));\n const shouldShowFilters = availableFilters.length > 0 || activeFilters.length > 0;\n\n // Tracks the most recently added filter so its chip can open its value\n // popup immediately, without waiting for a second click.\n const [pendingOpenKey, setPendingOpenKey] = React.useState<string | null>(null);\n\n function handleAddFilter(key: string) {\n onAddFilter(key);\n setPendingOpenKey(key);\n }\n\n return (\n <div\n data-slot=\"filter-bar\"\n data-visible-filters={shouldShowFilters}\n className={cn('flex flex-wrap items-center gap-2', className)}\n {...props}\n >\n {/* Add filter button */}\n {availableFilters.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\">\n <Icon name=\"plus\" data-icon=\"inline-start\" />\n Add filter\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align=\"start\"\n className=\"w-48\"\n // Picking a filter here immediately auto-opens its chip's own\n // value popup, which grabs focus for itself (autoFocus input, or\n // the popup's first item). Radix's default close behavior moves\n // focus back to this menu's trigger once its close animation\n // finishes — a hair after the new popup opens in a real browser\n // — which yanks focus out of that popup and, being non-modal,\n // makes it treat that as an outside interaction and dismiss\n // itself. Suppress the auto-return so the new popup keeps focus.\n onCloseAutoFocus={e => e.preventDefault()}\n >\n {availableFilters.map(filter => (\n <DropdownMenuItem key={filter.key} onSelect={() => handleAddFilter(filter.key)}>\n {filter.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n\n {/* Active filter chips */}\n {activeFilters.map(active => {\n const definition = filters.find(f => f.key === active.key);\n if (!definition) return null;\n return (\n <FilterChip\n key={active.key}\n definition={definition}\n value={active.value}\n autoOpen={active.key === pendingOpenKey}\n onChangeValue={value => onChangeFilter(active.key, value)}\n onRemove={() => onRemoveFilter(active.key)}\n />\n );\n })}\n\n {/* Children (count, actions) — sit immediately after the last chip\n with the same `gap-2` spacing. With the parent's `flex-wrap`, a\n long row of chips will push the action onto the next line instead\n of stretching across an empty horizontal void. */}\n {children}\n </div>\n );\n}\n\n// ── FilterChip (dispatcher) ────────────────────────────\n\ninterface FilterChipProps {\n definition: FilterDefinition;\n value: FilterValue | undefined;\n /** Opens the chip's value popup as soon as it mounts — used right after the filter is added. */\n autoOpen?: boolean;\n onChangeValue: (value: FilterValue) => void;\n onRemove: () => void;\n}\n\nfunction FilterChip({ definition, value, autoOpen, onChangeValue, onRemove }: FilterChipProps) {\n const type = definition.type ?? 'checkbox';\n\n switch (type) {\n case 'checkbox':\n return (\n <CheckboxFilterChip\n definition={definition as CheckboxFilterDefinition}\n value={value}\n autoOpen={autoOpen}\n onChangeValue={onChangeValue}\n onRemove={onRemove}\n />\n );\n case 'radio':\n return (\n <RadioFilterChip\n definition={definition as RadioFilterDefinition}\n value={value}\n autoOpen={autoOpen}\n onChangeValue={onChangeValue}\n onRemove={onRemove}\n />\n );\n case 'text':\n return (\n <TextFilterChip\n definition={definition as TextFilterDefinition}\n value={value}\n autoOpen={autoOpen}\n onChangeValue={onChangeValue}\n onRemove={onRemove}\n />\n );\n case 'multiText':\n return (\n <MultiTextFilterChip\n definition={definition as MultiTextFilterDefinition}\n value={value}\n autoOpen={autoOpen}\n onChangeValue={onChangeValue}\n onRemove={onRemove}\n />\n );\n case 'date':\n return (\n <DateFilterChip\n definition={definition as DateFilterDefinition}\n value={value}\n autoOpen={autoOpen}\n onChangeValue={onChangeValue}\n onRemove={onRemove}\n />\n );\n }\n}\n\n// ── Shared chip chrome ─────────────────────────────────\n\nfunction FilterChipRemoveButton({ label, onRemove }: { label: string; onRemove: () => void }) {\n return (\n <Button variant=\"outline\" size=\"icon\" aria-label={`Remove ${label} filter`} onClick={onRemove}>\n <Icon name=\"xmark\" />\n </Button>\n );\n}\n\n// ── Checkbox chip ──────────────────────────────────────\n\nfunction CheckboxFilterChip({\n definition,\n value,\n autoOpen,\n onChangeValue,\n onRemove,\n}: {\n definition: CheckboxFilterDefinition;\n value: FilterValue | undefined;\n autoOpen?: boolean;\n onChangeValue: (value: FilterValue) => void;\n onRemove: () => void;\n}) {\n const { label, options, searchable = false } = definition;\n const values = asCheckboxValue(value);\n const displayLabel =\n values.length === 0\n ? 'Any'\n : values.length === 1\n ? (options.find(o => o.value === values[0])?.label ?? values[0])\n : `${values.length} selected`;\n\n function toggle(optionValue: string) {\n const next = values.includes(optionValue) ? values.filter(v => v !== optionValue) : [...values, optionValue];\n onChangeValue(next);\n }\n\n return (\n <ButtonGroup>\n <ButtonGroupText>{label}</ButtonGroupText>\n {searchable ? (\n <Combobox\n items={options}\n itemToStringValue={(item: FilterOption) => item.label}\n multiple\n defaultOpen={autoOpen}\n value={options.filter(o => values.includes(o.value))}\n onValueChange={(selected: FilterOption[]) => onChangeValue(selected.map(s => s.value))}\n >\n <ComboboxTrigger\n render={<Button variant=\"outline\" className=\"gap-1 font-normal [&>svg:last-child]:size-(--icon-sm)\" />}\n >\n <span className={values.length === 0 ? 'text-muted-foreground' : ''}>{displayLabel}</span>\n </ComboboxTrigger>\n <ComboboxContent className=\"min-w-64\" collisionAvoidance={{ side: 'none', align: 'shift' }}>\n <ComboboxInput showTrigger={false} placeholder={`Search ${label.toLowerCase()}…`} />\n {values.length > 0 && (\n <>\n <ComboboxSelectedChips>\n <ComboboxValue>\n {(selected: FilterOption[]) => (\n <>\n {selected.map(item => (\n <ComboboxChip key={item.value}>{item.label}</ComboboxChip>\n ))}\n </>\n )}\n </ComboboxValue>\n <ComboboxClearAll onClick={() => onChangeValue([])} />\n </ComboboxSelectedChips>\n <ComboboxSeparator />\n </>\n )}\n <ComboboxEmpty>No {label.toLowerCase()} found.</ComboboxEmpty>\n <ComboboxList>\n {(item: FilterOption) => (\n <ComboboxItem key={item.value} value={item}>\n {item.icon}\n {item.label}\n </ComboboxItem>\n )}\n </ComboboxList>\n </ComboboxContent>\n </Combobox>\n ) : (\n <DropdownMenu defaultOpen={autoOpen}>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" className=\"gap-1 font-normal\">\n <span className={values.length === 0 ? 'text-muted-foreground' : ''}>{displayLabel}</span>\n <Icon name=\"chevron-down\" size=\"sm\" className=\"text-muted-foreground\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-48\">\n {options.map(opt => (\n <DropdownMenuCheckboxItem\n key={opt.value}\n checked={values.includes(opt.value)}\n onCheckedChange={() => toggle(opt.value)}\n >\n {opt.icon}\n {opt.label}\n </DropdownMenuCheckboxItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n <FilterChipRemoveButton label={label} onRemove={onRemove} />\n </ButtonGroup>\n );\n}\n\n// ── Radio chip ─────────────────────────────────────────\n\nfunction RadioFilterChip({\n definition,\n value,\n autoOpen,\n onChangeValue,\n onRemove,\n}: {\n definition: RadioFilterDefinition;\n value: FilterValue | undefined;\n autoOpen?: boolean;\n onChangeValue: (value: FilterValue) => void;\n onRemove: () => void;\n}) {\n const { label, options, searchable = false } = definition;\n const selectedValue = asRadioValue(value);\n const displayLabel = selectedValue ? (options.find(o => o.value === selectedValue)?.label ?? selectedValue) : 'Any';\n const selected = options.find(o => o.value === selectedValue) ?? null;\n\n return (\n <ButtonGroup>\n <ButtonGroupText>{label}</ButtonGroupText>\n {searchable ? (\n <Combobox\n items={options}\n itemToStringValue={(item: FilterOption) => item.label}\n defaultOpen={autoOpen}\n value={selected}\n onValueChange={(next: FilterOption | null) => onChangeValue(next?.value ?? '')}\n >\n <ComboboxTrigger\n render={<Button variant=\"outline\" className=\"gap-1 font-normal [&>svg:last-child]:size-(--icon-sm)\" />}\n >\n <span className={selectedValue ? '' : 'text-muted-foreground'}>{displayLabel}</span>\n </ComboboxTrigger>\n <ComboboxContent className=\"min-w-64\" collisionAvoidance={{ side: 'none', align: 'shift' }}>\n <ComboboxInput showTrigger={false} placeholder={`Search ${label.toLowerCase()}…`} />\n <ComboboxEmpty>No {label.toLowerCase()} found.</ComboboxEmpty>\n <ComboboxList>\n {(item: FilterOption) => (\n <ComboboxItem key={item.value} value={item}>\n {item.icon}\n {item.label}\n </ComboboxItem>\n )}\n </ComboboxList>\n </ComboboxContent>\n </Combobox>\n ) : (\n <DropdownMenu defaultOpen={autoOpen}>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" className=\"gap-1 font-normal\">\n <span className={selectedValue ? '' : 'text-muted-foreground'}>{displayLabel}</span>\n <Icon name=\"chevron-down\" size=\"sm\" className=\"text-muted-foreground\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-48\">\n <DropdownMenuRadioGroup value={selectedValue} onValueChange={onChangeValue}>\n {options.map(opt => (\n <DropdownMenuRadioItem key={opt.value} value={opt.value}>\n {opt.icon}\n {opt.label}\n </DropdownMenuRadioItem>\n ))}\n </DropdownMenuRadioGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n <FilterChipRemoveButton label={label} onRemove={onRemove} />\n </ButtonGroup>\n );\n}\n\n// ── Text chip ──────────────────────────────────────────\n\nfunction TextFilterChip({\n definition,\n value,\n autoOpen,\n onChangeValue,\n onRemove,\n}: {\n definition: TextFilterDefinition;\n value: FilterValue | undefined;\n autoOpen?: boolean;\n onChangeValue: (value: FilterValue) => void;\n onRemove: () => void;\n}) {\n const { label, placeholder } = definition;\n const text = asTextValue(value);\n const [open, setOpen] = React.useState(!!autoOpen);\n\n return (\n <ButtonGroup>\n <ButtonGroupText>{label}</ButtonGroupText>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button variant=\"outline\" className=\"gap-1 font-normal\">\n <span className={text ? '' : 'text-muted-foreground'}>{text || 'Any'}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\">\n <Input\n autoFocus\n value={text}\n placeholder={placeholder ?? 'Enter a value…'}\n onChange={e => onChangeValue(e.target.value)}\n onKeyDown={e => {\n if (e.key === 'Enter') setOpen(false);\n }}\n />\n </PopoverContent>\n </Popover>\n <FilterChipRemoveButton label={label} onRemove={onRemove} />\n </ButtonGroup>\n );\n}\n\n// ── MultiText chip ─────────────────────────────────────\n\nfunction MultiTextFilterChip({\n definition,\n value,\n autoOpen,\n onChangeValue,\n onRemove,\n}: {\n definition: MultiTextFilterDefinition;\n value: FilterValue | undefined;\n autoOpen?: boolean;\n onChangeValue: (value: FilterValue) => void;\n onRemove: () => void;\n}) {\n const { label, placeholder } = definition;\n const tokens = asMultiTextValue(value);\n const [draft, setDraft] = React.useState('');\n const displayLabel = tokens.length === 0 ? 'Any' : tokens.length === 1 ? tokens[0] : `${tokens.length} values`;\n\n function addToken() {\n const token = draft.trim();\n if (!token || tokens.includes(token)) {\n setDraft('');\n return;\n }\n onChangeValue([...tokens, token]);\n setDraft('');\n }\n\n function removeToken(token: string) {\n onChangeValue(tokens.filter(t => t !== token));\n }\n\n return (\n <ButtonGroup>\n <ButtonGroupText>{label}</ButtonGroupText>\n <Popover defaultOpen={autoOpen}>\n <PopoverTrigger asChild>\n <Button variant=\"outline\" className=\"gap-1 font-normal\">\n <span className={tokens.length === 0 ? 'text-muted-foreground' : ''}>{displayLabel}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\">\n <div className=\"flex flex-col gap-2\">\n {tokens.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {tokens.map(token => (\n <Badge key={token} variant=\"secondary\" className=\"gap-1\">\n {token}\n <button\n type=\"button\"\n aria-label={`Remove ${token}`}\n onClick={() => removeToken(token)}\n className=\"cursor-pointer\"\n >\n <Icon name=\"xmark\" size=\"xs\" />\n </button>\n </Badge>\n ))}\n </div>\n )}\n <Input\n autoFocus\n value={draft}\n placeholder={placeholder ?? 'Type a value, press Enter…'}\n onChange={e => setDraft(e.target.value)}\n onKeyDown={e => {\n if (e.key === 'Enter') {\n e.preventDefault();\n addToken();\n } else if (e.key === 'Backspace' && draft === '' && tokens.length > 0) {\n removeToken(tokens[tokens.length - 1]);\n }\n }}\n />\n </div>\n </PopoverContent>\n </Popover>\n <FilterChipRemoveButton label={label} onRemove={onRemove} />\n </ButtonGroup>\n );\n}\n\n// ── Date chip ──────────────────────────────────────────\n\nfunction DateFilterChip({\n definition,\n value,\n autoOpen,\n onChangeValue,\n onRemove,\n}: {\n definition: DateFilterDefinition;\n value: FilterValue | undefined;\n autoOpen?: boolean;\n onChangeValue: (value: FilterValue) => void;\n onRemove: () => void;\n}) {\n const { label, includeTime } = definition;\n const { startDate, endDate } = asDateValue(value);\n const showTimeInputs = includeTime ?? (hasExplicitTime(startDate) || hasExplicitTime(endDate));\n\n const displayLabel = !startDate\n ? 'Any'\n : !endDate || startDate.getTime() === endDate.getTime()\n ? formatDateLabel(startDate)\n : `${formatDateLabel(startDate)} – ${formatDateLabel(endDate)}`;\n\n function pickRange(range: DateRange | undefined) {\n if (!range?.from) {\n onChangeValue({ startDate: null, endDate: null });\n return;\n }\n onChangeValue({ startDate: range.from, endDate: range.to ?? range.from });\n }\n\n function pickStartTime(time: string) {\n if (!startDate) return;\n onChangeValue({ startDate: applyTimeToDate(startDate, time), endDate });\n }\n\n function pickEndTime(time: string) {\n if (!endDate) return;\n onChangeValue({ startDate, endDate: applyTimeToDate(endDate, time) });\n }\n\n return (\n <ButtonGroup>\n <ButtonGroupText>{label}</ButtonGroupText>\n <Popover defaultOpen={autoOpen}>\n <PopoverTrigger asChild>\n <Button variant=\"outline\" className=\"gap-1 font-normal\">\n <span className={startDate ? '' : 'text-muted-foreground'}>{displayLabel}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-fit\">\n <div className=\"flex flex-col gap-2\">\n <Calendar\n mode=\"range\"\n selected={{ from: startDate ?? undefined, to: endDate ?? undefined }}\n onSelect={pickRange}\n />\n {showTimeInputs && (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex w-full items-center gap-2\">\n <Label\n htmlFor={`${definition.key}-start-time`}\n className=\"text-body-sm text-muted-foreground w-10 shrink-0\"\n >\n Start\n </Label>\n <Input\n id={`${definition.key}-start-time`}\n type=\"time\"\n className=\"w-full\"\n value={formatTimeForInput(startDate)}\n onChange={e => pickStartTime(e.target.value)}\n disabled={!startDate}\n />\n </div>\n <div className=\"flex w-full items-center gap-2\">\n <Label\n htmlFor={`${definition.key}-end-time`}\n className=\"text-body-sm text-muted-foreground w-10 shrink-0\"\n >\n End\n </Label>\n <Input\n id={`${definition.key}-end-time`}\n type=\"time\"\n className=\"w-full\"\n value={formatTimeForInput(endDate)}\n onChange={e => pickEndTime(e.target.value)}\n disabled={!endDate}\n />\n </div>\n </div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n <FilterChipRemoveButton label={label} onRemove={onRemove} />\n </ButtonGroup>\n );\n}\n\nexport {\n FilterBar,\n FilterChip,\n type FilterType,\n type FilterDefinition,\n type CheckboxFilterDefinition,\n type RadioFilterDefinition,\n type TextFilterDefinition,\n type MultiTextFilterDefinition,\n type DateFilterDefinition,\n type ActiveFilter,\n type FilterOption,\n type FilterValue,\n type CheckboxFilterValue,\n type RadioFilterValue,\n type TextFilterValue,\n type MultiTextFilterValue,\n type DateFilterValue,\n type FilterBarProps,\n};\n","/**\n * Non-CEL column filter definitions — the `meta.filter` vocabulary consumed by\n * contextual (right-click cell) filtering and by the plain filter bar.\n * Mirrors TableWrapper's `Filters/types.ts` shapes; `id` is omitted here since\n * it comes from the owning `ColumnDef.id`, not the filter definition itself.\n */\n\nexport type ColumnFilterType = 'checkbox' | 'radio' | 'dateRange' | 'text' | 'multiText';\n\nexport type ColumnFilterOption = {\n label: string;\n value: string;\n disabled?: boolean;\n children?: ColumnFilterOption[];\n};\n\nexport type FetchColumnFilterOptionsArgs = {\n query: string;\n page: number;\n signal: AbortSignal;\n};\n\nexport type FetchColumnFilterOptionsResult = {\n items: ColumnFilterOption[];\n hasMore: boolean;\n};\n\nexport type FetchColumnFilterOptions = (args: FetchColumnFilterOptionsArgs) => Promise<FetchColumnFilterOptionsResult>;\n\ntype ColumnFilterBase = {\n title: string;\n type: ColumnFilterType;\n order?: number;\n};\n\ntype StaticCheckboxColumnFilter = ColumnFilterBase & {\n type: 'checkbox';\n options: string[] | ColumnFilterOption[];\n fetchFilterOptions?: never;\n /** Whether the chip's value popup is a searchable Combobox. Defaults to `true`. */\n searchable?: boolean;\n};\n\ntype AsyncCheckboxColumnFilter = ColumnFilterBase & {\n type: 'checkbox';\n fetchFilterOptions: FetchColumnFilterOptions;\n options?: never;\n /** Whether the chip's value popup is a searchable Combobox. Defaults to `true`. */\n searchable?: boolean;\n};\n\nexport type CheckboxColumnFilter = StaticCheckboxColumnFilter | AsyncCheckboxColumnFilter;\n\nexport type RadioColumnFilter = ColumnFilterBase & {\n type: 'radio';\n options: string[] | ColumnFilterOption[];\n /** Whether the chip's value popup is a searchable Combobox. Defaults to `true`. */\n searchable?: boolean;\n};\n\nexport type DateRangeColumnFilter = ColumnFilterBase & {\n type: 'dateRange';\n /** When true, always show time inputs. When false, never show them. When omitted, auto-detect from value. */\n includeTime?: boolean;\n};\n\nexport type TextColumnFilter = ColumnFilterBase & {\n type: 'text';\n placeholder?: string;\n};\n\nexport type MultiTextColumnFilter = ColumnFilterBase & {\n type: 'multiText';\n /** Defaults to comma (`,`) when omitted. */\n delimiter?: string;\n description?: string;\n placeholder?: string;\n};\n\nexport type ColumnFilterDefinition =\n CheckboxColumnFilter | DateRangeColumnFilter | RadioColumnFilter | TextColumnFilter | MultiTextColumnFilter;\n\nexport type CheckboxColumnFilterValue = string[] | undefined;\nexport type RadioColumnFilterValue = string | undefined;\nexport type DateRangeColumnFilterValue = { startDate: Date | null; endDate: Date | null } | undefined;\nexport type TextColumnFilterValue = string | undefined;\nexport type MultiTextColumnFilterValue = string[] | undefined;\n\nexport type ColumnFilterValue =\n | CheckboxColumnFilterValue\n | RadioColumnFilterValue\n | DateRangeColumnFilterValue\n | TextColumnFilterValue\n | MultiTextColumnFilterValue;\n\nexport const isDateRangeColumnFilter = (definition: ColumnFilterDefinition): definition is DateRangeColumnFilter =>\n definition.type === 'dateRange';\n\nexport const isRadioColumnFilter = (definition: ColumnFilterDefinition): definition is RadioColumnFilter =>\n definition.type === 'radio';\n\nexport const isCheckboxColumnFilter = (definition: ColumnFilterDefinition): definition is CheckboxColumnFilter =>\n definition.type === 'checkbox';\n\nexport const isTextColumnFilter = (definition: ColumnFilterDefinition): definition is TextColumnFilter =>\n definition.type === 'text';\n\nexport const isMultiTextColumnFilter = (definition: ColumnFilterDefinition): definition is MultiTextColumnFilter =>\n definition.type === 'multiText';\n\nexport const isCheckboxColumnFilterValue = (value: unknown): value is CheckboxColumnFilterValue =>\n value === undefined || (Array.isArray(value) && value.every(item => typeof item === 'string'));\n\nexport const isRadioColumnFilterValue = (value: unknown): value is RadioColumnFilterValue =>\n value === undefined || typeof value === 'string';\n\nexport const isDateRangeColumnFilterValue = (value: unknown): value is DateRangeColumnFilterValue =>\n value === undefined || (typeof value === 'object' && value !== null && 'startDate' in value && 'endDate' in value);\n","import { cn } from '@/lib/utils';\n\nfunction SectionHeader({ className, children, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"section-header\"\n className={cn('flex w-full items-start justify-between gap-4', className)}\n {...props}\n >\n {children}\n </div>\n );\n}\n\nfunction SectionHeaderContent({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"section-header-content\" className={cn('flex flex-col gap-1', className)} {...props} />;\n}\n\nfunction SectionHeaderTitle({ className, ...props }: React.ComponentProps<'h2'>) {\n return <h2 data-slot=\"section-header-title\" className={cn('text-h3 text-foreground', className)} {...props} />;\n}\n\nfunction SectionHeaderDescription({ className, ...props }: React.ComponentProps<'p'>) {\n return (\n <p data-slot=\"section-header-description\" className={cn('text-body text-muted-foreground', className)} {...props} />\n );\n}\n\nfunction SectionHeaderMeta({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"section-header-meta\"\n className={cn(\n 'text-body text-muted-foreground flex flex-wrap items-center gap-4',\n \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-(--icon-default)\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction SectionHeaderActions({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"section-header-actions\" className={cn('flex items-center gap-2', className)} {...props} />;\n}\n\nfunction SectionHeaderTabs({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"section-header-tabs\" className={cn('border-b', className)} {...props} />;\n}\n\nexport {\n SectionHeader,\n SectionHeaderContent,\n SectionHeaderTitle,\n SectionHeaderDescription,\n SectionHeaderMeta,\n SectionHeaderActions,\n SectionHeaderTabs,\n};\n"],"mappings":"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","names":["_a","getColumnPinning","Fragment","jsx","jsxs","Button","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","Icon","React","jsx","mins","hrs","days","id","jsx","jsxs","DropdownMenu","DropdownMenuTrigger","Button","Icon","DropdownMenuContent","DropdownMenuItem","React","React","Icon","Button","useCallback","useState","useState","useCallback","Fragment","jsx","jsxs","Button","Icon","Icon","InputGroup","InputGroupAddon","InputGroupInput","useCallback","useEffect","useRef","useState","_a","useState","useRef","useEffect","useCallback","React","_a","Button","Icon","jsx","jsxs","Button","Icon","Button","Icon","Label","Select","SelectContent","SelectGroup","SelectItem","SelectTrigger","SelectValue","Tooltip","TooltipContent","TooltipTrigger","jsx","jsxs","Tooltip","TooltipTrigger","Icon","TooltipContent","Label","Select","SelectTrigger","SelectValue","SelectContent","SelectGroup","SelectItem","Button","React","flexRender","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","Icon","Tooltip","TooltipContent","TooltipTrigger","Fragment","jsx","jsxs","Icon","DropdownMenuContent","DropdownMenuItem","flexRender","DropdownMenu","DropdownMenuTrigger","Tooltip","TooltipTrigger","TooltipContent","React","React","Icon","Badge","Button","ButtonGroup","ButtonGroupText","Calendar","Combobox","ComboboxChip","ComboboxClearAll","ComboboxContent","ComboboxEmpty","ComboboxInput","ComboboxItem","ComboboxList","ComboboxSelectedChips","ComboboxSeparator","ComboboxTrigger","ComboboxValue","DropdownMenu","DropdownMenuCheckboxItem","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","Input","Label","Popover","PopoverContent","PopoverTrigger","Fragment","jsx","jsxs","DropdownMenu","DropdownMenuTrigger","Button","Icon","DropdownMenuContent","DropdownMenuItem","ButtonGroup","ButtonGroupText","Combobox","ComboboxTrigger","ComboboxContent","ComboboxInput","ComboboxSelectedChips","ComboboxValue","ComboboxChip","ComboboxClearAll","ComboboxSeparator","ComboboxEmpty","ComboboxList","ComboboxItem","DropdownMenuCheckboxItem","_a","Popover","PopoverTrigger","PopoverContent","Input","Badge","Calendar","Label","jsx","jsx","Fragment","jsx","jsxs","_a","_b","InputGroup","InputGroupAddon","Icon","InputGroupInput"]}
1
+ {"version":3,"sources":["../src/data-table/cell-contextual-filter.tsx","../src/data-table/column-options.tsx","../src/lib/utils.ts","../src/lib/data-table/utils.ts","../src/data-table/columns.tsx","../src/relative-time.tsx","../src/hooks/use-mounted.ts","../src/data-table/data-table.tsx","../src/cel-filter-bar/cel-filter-bar.tsx","../src/hooks/use-cel-filter-editor-state.ts","../src/lib/cel-filter/constants.ts","../src/lib/cel-filter/date-utils.ts","../src/lib/cel-filter/types.ts","../src/lib/cel-filter/value-utils.ts","../src/lib/cel-filter/compile/escape-cel-string.ts","../src/lib/cel-filter/compile/operators.ts","../src/lib/cel-filter/compile/validate-condition.ts","../src/lib/cel-filter/compile/apply-display-rules.ts","../src/lib/cel-filter/schema-utils.ts","../src/lib/cel-filter/compile/compute-is-emit-ready.ts","../src/lib/cel-filter/compile/compile-cel-filter-tree.ts","../src/lib/cel-filter/tree-utils.ts","../src/lib/data-table/contextual-filters.ts","../src/hooks/use-table-column-resizing.ts","../src/hooks/use-grid-layout.ts","../src/lib/data-table/grid-layout.ts","../src/hooks/use-filter-visibility.ts","../src/data-table/empty-view.tsx","../src/data-table/filter-toggle.tsx","../src/data-table/pagination.tsx","../src/data-table/table-primitives.tsx","../src/data-table/view-filter.tsx","../src/filter-bar/filter-bar.tsx","../src/lib/data-table/filter-types.ts","../src/section-header.tsx"],"sourcesContent":["'use client';\n\nimport type { Cell, ColumnFilter, RowData } from '@tanstack/react-table';\n\nimport {\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuSeparator,\n ContextMenuSub,\n ContextMenuSubContent,\n ContextMenuSubTrigger,\n} from '@upbound/monarch-core';\n\n/** A single entry (or nested submenu) in a cell's contextual right-click menu, alongside the built-in \"Filter by this value\" item. */\nexport type ContextualMenuAction<TData extends RowData = RowData, TValue = unknown> = {\n id: string;\n label: React.ReactNode;\n disabled?: boolean | ((cell: Cell<TData, TValue>) => boolean);\n onSelect?: (cell: Cell<TData, TValue>) => void;\n items?: ContextualMenuAction<TData, TValue>[];\n className?: string;\n};\n\nexport type CellContextualFilterProps<TData extends RowData, TValue> = {\n filter?: ColumnFilter;\n globalSearch?: string;\n cell: Cell<TData, TValue>;\n onContextCell: (filter: ColumnFilter, cell: Cell<TData, TValue>) => void;\n onContextSearch?: (searchTerm: string, cell: Cell<TData, TValue>) => void;\n contextualMenuActions?: ContextualMenuAction<TData, TValue>[];\n};\n\n/**\n * The right-click cell menu content: an always-present \"Filter by this value\"\n * item (disabled, never hidden, when nothing is derivable) plus any\n * `contextualMenuActions`. Renders only the `ContextMenuContent` — the\n * `ContextMenu`/`ContextMenuTrigger` wrapping the cell lives in the caller.\n */\nexport function CellContextualFilter<TData extends RowData, TValue>({\n filter,\n globalSearch,\n cell,\n onContextCell,\n onContextSearch,\n contextualMenuActions = [],\n}: CellContextualFilterProps<TData, TValue>) {\n const disabled = !filter && !(globalSearch && onContextSearch);\n\n function handleSelect() {\n if (globalSearch && onContextSearch) {\n onContextSearch(globalSearch, cell);\n return;\n }\n if (!filter) return;\n onContextCell(filter, cell);\n }\n\n function renderAction(action: ContextualMenuAction<TData, TValue>) {\n const actionDisabled = typeof action.disabled === 'function' ? action.disabled(cell) : (action.disabled ?? false);\n\n if (action.items?.length) {\n return (\n <ContextMenuSub key={action.id}>\n <ContextMenuSubTrigger\n disabled={actionDisabled}\n className={action.className}\n onClick={(event: React.MouseEvent) => event.stopPropagation()}\n >\n {action.label}\n </ContextMenuSubTrigger>\n <ContextMenuSubContent>{action.items.map(renderAction)}</ContextMenuSubContent>\n </ContextMenuSub>\n );\n }\n\n // Radix fires both `onClick` and `onSelect` for a pointer activation but\n // only `onSelect` for keyboard — this flag stops the pointer path from\n // double-invoking `action.onSelect`.\n let handledClick = false;\n\n return (\n <ContextMenuItem\n key={action.id}\n disabled={actionDisabled}\n onClick={(event: React.MouseEvent) => {\n event.stopPropagation();\n handledClick = true;\n action.onSelect?.(cell);\n }}\n onSelect={() => {\n if (handledClick) {\n handledClick = false;\n return;\n }\n action.onSelect?.(cell);\n }}\n >\n {action.label}\n </ContextMenuItem>\n );\n }\n\n return (\n <ContextMenuContent>\n <ContextMenuItem\n disabled={disabled}\n onClick={(event: React.MouseEvent) => event.stopPropagation()}\n onSelect={handleSelect}\n >\n Filter by this value\n </ContextMenuItem>\n {contextualMenuActions.length > 0 && (\n <>\n <ContextMenuSeparator />\n {contextualMenuActions.map(renderAction)}\n </>\n )}\n </ContextMenuContent>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport { flexRender, type Column, type ColumnOrderState, type RowData } from '@tanstack/react-table';\n\nimport { Button } from '@upbound/monarch-core';\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@upbound/monarch-core';\nimport { Icon } from '@upbound/monarch-core';\nimport { cn } from '@/lib/utils';\nimport {\n isFilterOnlyColumn,\n mergeUnpinnedColumnOrder,\n normalizeColumnOrdering,\n splitColumnOrderByPinning,\n} from '@/lib/data-table/utils';\n\n/** Honors both runtime (drag-pinned) and declarative (`meta.pinning`) pin state. */\nfunction getColumnPinning<TData extends RowData>(column: Column<TData, unknown> | undefined): 'left' | 'right' | false {\n if (!column) return false;\n return column.getIsPinned() || column.columnDef.meta?.pinning || false;\n}\n\nfunction ColumnOptionsItem<TData extends RowData>({\n column,\n disableColumnOrdering,\n isDropTarget,\n onDragStart,\n onDrop,\n onDragOver,\n onDragEnd,\n}: {\n column: Column<TData, unknown>;\n disableColumnOrdering?: boolean;\n isDropTarget: boolean;\n onDragStart: (column: Column<TData, unknown>) => (event: React.DragEvent) => void;\n onDrop: (column: Column<TData, unknown>) => (event: React.DragEvent) => void;\n onDragOver: (event: React.DragEvent) => void;\n onDragEnd: (event: React.DragEvent) => void;\n}) {\n const [isDraggedOver, setIsDraggedOver] = React.useState(false);\n const isDraggable = column.getIsPinned() === false && !column.columnDef.meta?.pinning && !disableColumnOrdering;\n const canHide = column.getCanHide();\n\n // Rendering the header outside of an actual header cell — `header`/`table`\n // are unused by ordinary string/label header defs, matching the source.\n const headerContent = React.useMemo(\n () => flexRender(column.columnDef.header, { column, header: null, table: null } as never),\n [column],\n );\n\n const dragProps = {\n draggable: isDraggable,\n onDragStart: isDraggable ? onDragStart(column) : undefined,\n onDrop: isDropTarget\n ? (e: React.DragEvent) => {\n onDrop(column)(e);\n setIsDraggedOver(false);\n }\n : undefined,\n onDragOver: isDropTarget\n ? (e: React.DragEvent) => {\n onDragOver(e);\n setIsDraggedOver(true);\n }\n : undefined,\n onDragLeave: isDropTarget ? () => setIsDraggedOver(false) : undefined,\n onDragEnd: isDraggable ? onDragEnd : undefined,\n className: cn(\n 'relative flex items-center gap-2',\n isDraggedOver && 'before:bg-primary before:absolute before:inset-x-0 before:top-0 before:h-0.5',\n ),\n };\n\n const itemContent = (\n <>\n {isDraggable && <Icon name=\"grip-vertical\" size=\"sm\" className=\"text-muted-foreground cursor-move\" />}\n <span className=\"flex min-w-0 flex-1 items-center gap-2\">{headerContent}</span>\n </>\n );\n\n if (!canHide) {\n return <DropdownMenuItem {...dragProps}>{itemContent}</DropdownMenuItem>;\n }\n\n return (\n <DropdownMenuCheckboxItem\n checked={column.getIsVisible()}\n onCheckedChange={() => column.toggleVisibility()}\n {...dragProps}\n >\n {itemContent}\n </DropdownMenuCheckboxItem>\n );\n}\n\nexport type ColumnOptionsProps<TData extends RowData> = {\n columns: Column<TData, unknown>[];\n columnOrdering: ColumnOrderState;\n onColumnOrderingChange: React.Dispatch<React.SetStateAction<ColumnOrderState>>;\n disableColumnOrdering?: boolean;\n};\n\n/**\n * The \"Columns\" dropdown: per-column visibility toggle + native HTML5\n * drag-and-drop reordering (the source uses the browser's own drag/drop API,\n * not a DnD library). Pinned/actions/filter-only columns are excluded from\n * dragging and from the draggable list respectively; reordering only ever\n * touches the unpinned slots (`mergeUnpinnedColumnOrder`), so pinned columns\n * never jump position.\n */\nexport function ColumnOptions<TData extends RowData>({\n columns: rawColumns,\n columnOrdering,\n onColumnOrderingChange,\n disableColumnOrdering,\n}: ColumnOptionsProps<TData>) {\n const [isDragging, setIsDragging] = React.useState(false);\n const [isLastDropZoneActive, setIsLastDropZoneActive] = React.useState(false);\n\n const columns = React.useMemo(\n () => rawColumns.filter(col => !isFilterOnlyColumn(col) && col.columnDef.meta?.actions !== true),\n [rawColumns],\n );\n const allColumnById = React.useMemo(() => new Map(rawColumns.map(col => [col.id, col])), [rawColumns]);\n const columnById = React.useMemo(() => new Map(columns.map(col => [col.id, col])), [columns]);\n const fullColumnOrder = React.useMemo(\n () =>\n normalizeColumnOrdering(\n columnOrdering,\n rawColumns.map(col => col.id),\n ),\n [columnOrdering, rawColumns],\n );\n\n const getColumnPinningFor = React.useCallback(\n (columnId: string) => getColumnPinning(allColumnById.get(columnId)),\n [allColumnById],\n );\n\n const { leftPinnedColumns, unpinnedColumns, rightPinnedColumns } = splitColumnOrderByPinning(\n fullColumnOrder,\n getColumnPinningFor,\n );\n\n function handleDragStart(column: Column<TData, unknown>) {\n return (event: React.DragEvent) => {\n event.dataTransfer.setData('text/plain', column.id);\n event.dataTransfer.dropEffect = 'move';\n event.dataTransfer.effectAllowed = 'move';\n setIsDragging(true);\n };\n }\n\n function handleDrop(targetColumn: Column<TData, unknown>) {\n return (event: React.DragEvent) => {\n event.preventDefault();\n event.stopPropagation();\n\n const draggedColumnId = event.dataTransfer.getData('text/plain');\n const targetColumnId = targetColumn.id;\n if (!draggedColumnId || !targetColumnId || draggedColumnId === targetColumnId) {\n setIsDragging(false);\n return;\n }\n\n const draggedIndex = unpinnedColumns.indexOf(draggedColumnId);\n if (draggedIndex === -1) {\n setIsDragging(false);\n return;\n }\n\n const newOrder = [...unpinnedColumns];\n const [removed] = newOrder.splice(draggedIndex, 1);\n const targetIndex = newOrder.indexOf(targetColumnId);\n if (targetIndex === -1) {\n setIsDragging(false);\n return;\n }\n newOrder.splice(targetIndex, 0, removed);\n\n onColumnOrderingChange(mergeUnpinnedColumnOrder(fullColumnOrder, newOrder, getColumnPinningFor));\n setIsDragging(false);\n };\n }\n\n function handleDropAtEnd(event: React.DragEvent) {\n event.preventDefault();\n event.stopPropagation();\n setIsLastDropZoneActive(false);\n\n const draggedColumnId = event.dataTransfer.getData('text/plain');\n if (!draggedColumnId) {\n setIsDragging(false);\n return;\n }\n\n const draggedIndex = unpinnedColumns.indexOf(draggedColumnId);\n if (draggedIndex === -1) {\n setIsDragging(false);\n return;\n }\n\n const newOrder = [...unpinnedColumns];\n const [removed] = newOrder.splice(draggedIndex, 1);\n newOrder.push(removed);\n\n onColumnOrderingChange(mergeUnpinnedColumnOrder(fullColumnOrder, newOrder, getColumnPinningFor));\n setIsDragging(false);\n }\n\n function handleDragOver(event: React.DragEvent) {\n event.preventDefault();\n }\n\n function handleDragEnd() {\n setIsDragging(false);\n setIsLastDropZoneActive(false);\n }\n\n function orderedColumns(ids: string[]) {\n return ids.map(id => columnById.get(id)).filter((c): c is Column<TData, unknown> => !!c && !c.getIsGrouped?.());\n }\n\n function canDropOnColumn(column: Column<TData, unknown>) {\n return column.getIsPinned() === false && !column.columnDef.meta?.pinning;\n }\n\n const leftPinned = orderedColumns(leftPinnedColumns);\n const unpinned = orderedColumns(unpinnedColumns);\n const rightPinned = orderedColumns(rightPinnedColumns);\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" className=\"shrink-0\">\n <Icon name=\"table-columns\" data-icon=\"inline-start\" />\n Columns\n <Icon name=\"chevron-down\" data-icon=\"inline-end\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"w-58 p-0\">\n <div className=\"p-1\">\n {[...leftPinned, ...unpinned].map(column => (\n <ColumnOptionsItem\n key={column.id}\n column={column}\n disableColumnOrdering={disableColumnOrdering}\n isDropTarget={canDropOnColumn(column)}\n onDragStart={handleDragStart}\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n onDragEnd={handleDragEnd}\n />\n ))}\n {!disableColumnOrdering && (\n <div\n onDrop={handleDropAtEnd}\n onDragOver={e => {\n e.preventDefault();\n setIsLastDropZoneActive(true);\n }}\n onDragLeave={() => setIsLastDropZoneActive(false)}\n className={cn(\n 'relative w-full transition-colors',\n isDragging && 'h-3',\n isLastDropZoneActive &&\n 'bg-muted before:bg-primary before:absolute before:inset-x-0 before:top-0 before:h-0.5',\n )}\n />\n )}\n {rightPinned.map(column => (\n <ColumnOptionsItem\n key={column.id}\n column={column}\n disableColumnOrdering={disableColumnOrdering}\n isDropTarget={canDropOnColumn(column)}\n onDragStart={handleDragStart}\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n onDragEnd={handleDragEnd}\n />\n ))}\n </div>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n","import { clsx, type ClassValue } from 'clsx';\nimport { extendTailwindMerge } from 'tailwind-merge';\n\nconst twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n 'font-size': [\n {\n text: [\n 'display-hero',\n 'display-kpi-sm',\n 'display-kpi',\n 'display-kpi-lg',\n 'display-feature',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'body-lg',\n 'body',\n 'body-sm',\n 'caption',\n 'eyebrow',\n ],\n },\n ],\n },\n },\n});\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport function sortBy<T>(items: T[], getKey: (item: T) => string): T[] {\n return [...items].sort((a, b) => getKey(a).localeCompare(getKey(b)));\n}\n","import type { Column, ColumnOrderState, FilterFn, Row, RowData } from '@tanstack/react-table';\n\nimport './table-meta';\nimport type { DateRangeColumnFilterValue } from './filter-types';\n\nconst TO_EACH_SIDE = 2;\n\ntype ColumnPinningPosition = 'left' | 'right' | false;\n\n/**\n * Reconciles a persisted column order against the table's actual columns:\n * drops stale/duplicate ids and appends any column missing from the\n * persisted order (in `allColumnIds` order).\n */\nexport function normalizeColumnOrdering(columnOrdering: ColumnOrderState, allColumnIds: string[]): ColumnOrderState {\n const validIds = new Set(allColumnIds);\n const seenIds = new Set<string>();\n\n const trackedColumnIds = columnOrdering.filter(columnId => {\n if (!validIds.has(columnId) || seenIds.has(columnId)) return false;\n seenIds.add(columnId);\n return true;\n });\n\n return [...trackedColumnIds, ...allColumnIds.filter(columnId => !seenIds.has(columnId))];\n}\n\nexport function isSameColumnOrdering(left: ColumnOrderState, right: ColumnOrderState): boolean {\n return left.length === right.length && left.every((columnId, index) => columnId === right[index]);\n}\n\n/** Splits a full column order into left-pinned / unpinned / right-pinned buckets, preserving relative order within each. */\nexport function splitColumnOrderByPinning(\n fullColumnOrder: string[],\n getColumnPinning: (columnId: string) => ColumnPinningPosition,\n) {\n return {\n leftPinnedColumns: fullColumnOrder.filter(columnId => getColumnPinning(columnId) === 'left'),\n unpinnedColumns: fullColumnOrder.filter(columnId => getColumnPinning(columnId) === false),\n rightPinnedColumns: fullColumnOrder.filter(columnId => getColumnPinning(columnId) === 'right'),\n };\n}\n\n/**\n * Refills only the unpinned slots of `fullColumnOrder` from `nextUnpinnedOrder`,\n * in order — pinned columns keep their exact index. This is what keeps\n * drag-reordering from relocating pinned/actions columns to the array edges.\n */\nexport function mergeUnpinnedColumnOrder(\n fullColumnOrder: string[],\n nextUnpinnedOrder: string[],\n getColumnPinning: (columnId: string) => ColumnPinningPosition,\n): ColumnOrderState {\n const nextUnpinnedIterator = nextUnpinnedOrder[Symbol.iterator]();\n\n return fullColumnOrder.map(columnId =>\n getColumnPinning(columnId) === false ? (nextUnpinnedIterator.next().value ?? columnId) : columnId,\n );\n}\n\nexport type PaginationInfo = {\n visiblePages: (number | undefined)[];\n pageCount: number;\n itemStart: number;\n itemEnd: number;\n};\n\n/** Computes the pagination footer's visible page numbers (with ellipsis markers), page count, and item range. */\nexport function getPaginationInfo(pageIndex: number, totalRows: number, pageSize: number): PaginationInfo {\n const currentPage = pageIndex + 1;\n const pageCount = Math.ceil(totalRows / pageSize);\n\n function getPages(): (number | undefined)[] {\n if (pageCount === 0) return [];\n if (pageCount === 1) return [1];\n if (pageCount === 2) return [1, 2];\n\n const runStart = Math.max(currentPage - TO_EACH_SIDE, 2);\n const runEnd = Math.min(currentPage + TO_EACH_SIDE, pageCount - 1);\n const hasBeginningEllipsis = runStart > 2;\n const hasEndingEllipsis = currentPage + 3 < pageCount;\n\n return [\n 1,\n ...(hasBeginningEllipsis ? [undefined] : []),\n ...Array.from({ length: runEnd - runStart + 1 }).map((_, i) => i + runStart),\n ...(hasEndingEllipsis ? [undefined] : []),\n pageCount,\n ];\n }\n\n return {\n pageCount,\n visiblePages: getPages(),\n itemStart: totalRows === 0 ? 0 : pageIndex * pageSize + 1,\n itemEnd: Math.min(currentPage * pageSize, totalRows),\n };\n}\n\n/** Ascending date sort; invalid dates sort first (treated as `-Infinity`). */\nexport function sortColumnByDate<T>(rowA: Row<T>, rowB: Row<T>, columnId: string): number {\n const dateA = new Date(rowA.getValue(columnId) as string | number | Date).getTime();\n const dateB = new Date(rowB.getValue(columnId) as string | number | Date).getTime();\n\n const dateNumA = isNaN(dateA) ? -Infinity : dateA;\n const dateNumB = isNaN(dateB) ? -Infinity : dateB;\n\n return dateNumA - dateNumB;\n}\n\nfunction isDateValid(date: Date): boolean {\n return !isNaN(date.getTime());\n}\n\n/** An invalid/missing filter range passes every row (filter inactive); an invalid row date fails (excluded). */\nexport const filterColumnByDateRange: FilterFn<RowData> = (\n row: Row<RowData>,\n columnId: string,\n filterValue: NonNullable<DateRangeColumnFilterValue>,\n) => {\n const { startDate, endDate } = filterValue;\n if (!startDate || !isDateValid(startDate) || !endDate || !isDateValid(endDate)) return true;\n\n const date = new Date(row.getValue(columnId) as string | number | Date);\n if (!isDateValid(date)) return false;\n\n return date >= startDate && date <= endDate;\n};\n\n/**\n * @deprecated Prefer TanStack's built-in `arrIncludesSome` filter fn — kept\n * only for the case-insensitive matching it does that `arrIncludesSome`\n * doesn't; a straight swap changes behavior for mixed-case data.\n */\nexport const filterColumnByArrayValues: FilterFn<RowData> = (\n row: Row<RowData>,\n columnId: string,\n arrayOfValues: string[],\n) => {\n if (arrayOfValues.length) {\n const rowValue = row.getValue(columnId) as string;\n return arrayOfValues.filter(val => val?.toLowerCase() === rowValue?.toLowerCase()).length > 0;\n }\n return true;\n};\n\n/** Sorts by `secondaryColumnId` when the primary column's values are equal. Never returns 0 (always a definite order). */\nexport function secondarySortByColumn(\n secondaryColumnId: string,\n): (rowA: Row<RowData>, rowB: Row<RowData>, columnId: string) => number {\n return (rowA: Row<RowData>, rowB: Row<RowData>, columnId: string): number => {\n const rowAPrimaryColumnValue = rowA.getValue(columnId) as string;\n const rowBPrimaryColumnValue = rowB.getValue(columnId) as string;\n const rowASecondaryColumnValue = rowA.getValue(secondaryColumnId) as string;\n const rowBSecondaryColumnValue = rowB.getValue(secondaryColumnId) as string;\n\n if (rowAPrimaryColumnValue === rowBPrimaryColumnValue) {\n return rowASecondaryColumnValue > rowBSecondaryColumnValue ? 1 : -1;\n }\n return rowAPrimaryColumnValue > rowBPrimaryColumnValue ? 1 : -1;\n };\n}\n\nexport function isFilterOnlyColumn<T>(column: Column<T, unknown>): boolean {\n return column.columnDef.meta?.filterOnly === true;\n}\n\n/** Whether at least one column defines a `meta.filter` and is filterable — i.e. there's something the plain filter row could show. */\nexport function hasFilterableColumns<T>(columns: Column<T, unknown>[]): boolean {\n return columns.some(\n column => !isFilterOnlyColumn(column) && column.getCanFilter() && !!column.columnDef.meta?.filter,\n );\n}\n\nexport type TableDataState = 'empty' | 'loading' | 'error' | 'success';\n\n/** Strict precedence: error > loading > empty > success. `loading` still renders table content (skeleton rows). */\nexport function getTableState({\n error,\n loading,\n rowCount,\n}: {\n error: boolean;\n loading: boolean;\n rowCount: number;\n}): TableDataState {\n if (error) return 'error';\n if (loading) return 'loading';\n return rowCount === 0 ? 'empty' : 'success';\n}\n","'use client';\n\nimport * as React from 'react';\nimport type { CellContext, ColumnDef, Row, RowData } from '@tanstack/react-table';\n\nimport { Button } from '@upbound/monarch-core';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@upbound/monarch-core';\nimport { Icon } from '@upbound/monarch-core';\nimport { Link } from '@upbound/monarch-core';\nimport { RelativeTime } from '@/relative-time';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@upbound/monarch-core';\nimport { cn } from '@/lib/utils';\n\n// ── Row actions menu ────────────────────────────────────\n// Built on Monarch's DropdownMenu (Radix), not legacy's Popover + <ul>/<li> —\n// Radix's menu already closes on item select, so there's no `closePopover`\n// render-prop to thread through; consumers just pass `DropdownMenuItem`s.\n\nexport function RowActions({\n align = 'end',\n children,\n contentClassName,\n}: {\n align?: 'start' | 'end';\n children: React.ReactNode;\n contentClassName?: string;\n}) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n aria-label=\"Row actions\"\n onClick={(e: React.MouseEvent) => e.stopPropagation()}\n >\n <Icon name=\"ellipsis-vertical\" size=\"sm\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align={align}\n className={contentClassName}\n onClick={(event: React.MouseEvent) => event.stopPropagation()}\n >\n {children}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n\nexport function RowActionItem({\n disabled,\n className,\n tooltip,\n children,\n onClick,\n}: {\n disabled?: boolean;\n className?: string;\n tooltip?: string;\n children: React.ReactNode;\n onClick?: React.ComponentProps<typeof DropdownMenuItem>['onClick'];\n}) {\n const item = (\n <DropdownMenuItem disabled={disabled} className={className} onClick={onClick}>\n {children}\n </DropdownMenuItem>\n );\n\n if (!tooltip) return item;\n\n // Trigger wraps the item in a plain span (not `asChild` onto the item\n // itself) so hover still reaches the tooltip even when the item is\n // disabled — a disabled DropdownMenuItem has `pointer-events-none`.\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"block\">{item}</span>\n </TooltipTrigger>\n <TooltipContent>{tooltip}</TooltipContent>\n </Tooltip>\n );\n}\n\n/** A ready-made right-pinned, non-sortable/filterable/hideable \"Actions\" column. */\nexport function getActionsColumnDefinition<TData extends RowData, TValue = unknown>({\n cell,\n}: Pick<ColumnDef<TData, TValue>, 'cell'>): ColumnDef<TData, TValue> {\n return {\n id: 'actions',\n header: 'Actions',\n size: 80,\n enableColumnFilter: false,\n enableGlobalFilter: false,\n enableSorting: false,\n enableHiding: false,\n meta: { pinning: 'right', actions: true },\n cell,\n };\n}\n\n// ── Row expansion ───────────────────────────────────────\n\nexport function ExpandButton<TData extends RowData>({ row }: { row: Row<TData> }) {\n if (!row.getCanExpand()) return null;\n const isExpanded = row.getIsExpanded();\n\n return (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n aria-label={isExpanded ? 'Collapse row' : 'Expand row'}\n onClick={(e: React.MouseEvent) => {\n e.stopPropagation();\n row.getToggleExpandedHandler()();\n }}\n >\n <Icon name={isExpanded ? 'chevron-up' : 'chevron-down'} size=\"sm\" />\n </Button>\n );\n}\n\n/** A ready-made right-pinned, fixed-width (28px) \"Expand\" column. Defaults to an `ExpandButton` cell. */\nexport function getExpandColumnDefinition<TData extends RowData, TValue = unknown>(options?: {\n cell?: (context: CellContext<TData, TValue>) => React.ReactNode;\n}): ColumnDef<TData, TValue> {\n return {\n id: 'expand',\n header: '',\n size: 28,\n minSize: 28,\n maxSize: 28,\n enableColumnFilter: false,\n enableGlobalFilter: false,\n enableSorting: false,\n enableHiding: false,\n meta: { pinning: 'right', actions: true },\n cell: options?.cell ?? (({ row }) => <ExpandButton row={row} />),\n };\n}\n\n// ── Value cell ───────────────────────────────────────────\n\nexport type DataTableValueCellProps = {\n content?: React.ReactNode;\n /** Shown as a tooltip; also becomes the link's native title when `href` is set. */\n title?: string;\n className?: string;\n href?: string;\n onClick?: () => void;\n};\n\n/**\n * A generic cell renderer: a link (when `href` is set), a dashed-underline\n * value with a hover tooltip (when `title` is set), or plain content — with\n * an em-dash placeholder when `content` is empty. Consumers who need router\n * navigation wrap their own router link with `Link asChild` at the call site.\n */\nexport function DataTableValueCell({ content, title, className, href, onClick }: DataTableValueCellProps) {\n const baseClassName = cn('text-body truncate', className);\n\n if (href) {\n return (\n <p className={baseClassName}>\n <Link href={href} title={title} onClick={onClick}>\n {content}\n </Link>\n </p>\n );\n }\n\n if (title) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n className={cn(\n baseClassName,\n 'focus-visible:ring-ring/30 cursor-help underline decoration-dashed underline-offset-2 focus-visible:ring-2',\n )}\n onClick={onClick}\n >\n {content}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">{title}</TooltipContent>\n </Tooltip>\n );\n }\n\n return <p className={baseClassName}>{content ? <span>{content}</span> : <span>&mdash;</span>}</p>;\n}\n\n/** A timestamp cell — relative time in the cell, absolute time on hover (via Monarch's `RelativeTime`); an em-dash when absent. */\nexport function TimestampCell({ timestamp }: { timestamp?: Date | string | number }) {\n if (!timestamp) return <DataTableValueCell content=\"—\" />;\n return <RelativeTime date={timestamp} className=\"block\" />;\n}\n","'use client';\n\nimport * as React from 'react';\nimport { cn } from '@/lib/utils';\nimport { useMounted } from '@/hooks/use-mounted';\n\n// ── Format helpers ─────────────────────────────────────────────────────────────\n//\n// `locale` is `undefined` (browser/runtime default — the viewer's actual\n// locale, per Monarch's \"use locale-aware formatting\" content principle) once\n// mounted client-side, and a fixed `'en-US'` for the server-rendered/first-\n// paint value — the server can't know the viewer's locale ahead of time, and\n// passing a locale that differs between server and client render would\n// hydration-mismatch. Callers gate this via `useMounted()` below, so the\n// locale-aware value replaces the fixed one right after mount (see\n// RelativeTime/AbsoluteTimestamp).\n\n/** Returns a human-readable relative label for `date` vs now. */\nfunction formatRelativeDefault(date: Date, locale: string | undefined): string {\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n\n // Future dates\n if (diffMs < 0) {\n const abs = Math.abs(diffMs);\n const mins = Math.floor(abs / 60000);\n const hrs = Math.floor(mins / 60);\n const days = Math.floor(hrs / 24);\n if (abs < 60000) return 'just now';\n if (mins < 60) return `in ${mins} minute${mins === 1 ? '' : 's'}`;\n if (hrs < 24) return `in ${hrs} hour${hrs === 1 ? '' : 's'}`;\n if (days < 7) return `in ${days} day${days === 1 ? '' : 's'}`;\n if (days < 30) return `in ${Math.floor(days / 7)} week${Math.floor(days / 7) === 1 ? '' : 's'}`;\n return `on ${date.toLocaleDateString(locale, {\n month: 'short',\n day: 'numeric',\n ...(date.getFullYear() !== now.getFullYear() ? { year: 'numeric' } : {}),\n })}`;\n }\n\n // Past dates\n const secs = Math.floor(diffMs / 1000);\n const mins = Math.floor(secs / 60);\n const hrs = Math.floor(mins / 60);\n const days = Math.floor(hrs / 24);\n\n if (secs < 60) return 'just now';\n if (mins < 60) return `${mins} minute${mins === 1 ? '' : 's'} ago`;\n if (hrs < 24) return `${hrs} hour${hrs === 1 ? '' : 's'} ago`;\n if (days === 1) return 'yesterday';\n if (days < 7) return `${days} days ago`;\n if (days < 14) return 'last week';\n if (days < 30) return `${Math.floor(days / 7)} weeks ago`;\n\n // > 30 days: fall back to absolute date\n return `on ${date.toLocaleDateString(locale, {\n month: 'short',\n day: 'numeric',\n ...(date.getFullYear() !== now.getFullYear() ? { year: 'numeric' } : {}),\n })}`;\n}\n\n/**\n * Compact relative label — abbreviates units for tight horizontal space\n * (tables, KPI cards). Preserves \"ago\", \"in\", \"on\", and \"just now\" so\n * directionality and reference points stay legible at a glance.\n */\nfunction formatRelativeCompact(date: Date, locale: string | undefined): string {\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n\n // Future dates\n if (diffMs < 0) {\n const abs = Math.abs(diffMs);\n const mins = Math.floor(abs / 60000);\n const hrs = Math.floor(mins / 60);\n const days = Math.floor(hrs / 24);\n if (abs < 60000) return 'just now';\n if (mins < 60) return `in ${mins}m`;\n if (hrs < 24) return `in ${hrs}h`;\n if (days < 7) return `in ${days}d`;\n if (days < 30) return `in ${Math.floor(days / 7)}w`;\n return `on ${date.toLocaleDateString(locale, {\n month: 'short',\n day: 'numeric',\n ...(date.getFullYear() !== now.getFullYear() ? { year: 'numeric' } : {}),\n })}`;\n }\n\n // Past dates\n const secs = Math.floor(diffMs / 1000);\n const mins = Math.floor(secs / 60);\n const hrs = Math.floor(mins / 60);\n const days = Math.floor(hrs / 24);\n\n if (secs < 60) return 'just now';\n if (mins < 60) return `${mins}m ago`;\n if (hrs < 24) return `${hrs}h ago`;\n if (days < 7) return `${days}d ago`;\n if (days < 30) return `${Math.floor(days / 7)}w ago`;\n\n return `on ${date.toLocaleDateString(locale, {\n month: 'short',\n day: 'numeric',\n ...(date.getFullYear() !== now.getFullYear() ? { year: 'numeric' } : {}),\n })}`;\n}\n\nfunction formatRelative(date: Date, variant: 'default' | 'compact', locale: string | undefined): string {\n return variant === 'compact' ? formatRelativeCompact(date, locale) : formatRelativeDefault(date, locale);\n}\n\n/** Returns the update interval in ms appropriate for the current age. */\nfunction updateInterval(date: Date): number {\n const diffMs = Math.abs(Date.now() - date.getTime());\n const diffMin = diffMs / 60000;\n if (diffMin < 60) return 60_000; // update every minute while < 1 hour old\n if (diffMin < 1440) return 300_000; // every 5 min while < 1 day old\n return 3_600_000; // every hour otherwise\n}\n\n/** Formats an absolute tooltip title. */\nfunction absoluteTitle(date: Date, locale: string | undefined): string {\n return date.toLocaleString(locale, {\n weekday: 'long',\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n timeZoneName: 'short',\n });\n}\n\n// ── Component ──────────────────────────────────────────────────────────────────\n\nexport interface RelativeTimeProps extends Omit<React.TimeHTMLAttributes<HTMLTimeElement>, 'dateTime' | 'title'> {\n /**\n * The timestamp to display. Accepts a `Date`, ISO string, or unix milliseconds.\n */\n date: Date | string | number;\n /**\n * Format variant. `default` produces full-word output (\"5 minutes ago\",\n * \"yesterday\"). `compact` abbreviates units (\"5m ago\", \"1d ago\") for tight\n * horizontal space like tables, KPI cards, or inline metadata.\n */\n variant?: 'default' | 'compact';\n /**\n * Override the tooltip shown on hover. Defaults to the full localized\n * absolute date-time string (e.g. \"Monday, January 20, 2025 at 3:22 PM PST\").\n */\n title?: string;\n}\n\n/**\n * Displays a timestamp as a live-updating relative string (\"5 minutes ago\",\n * \"yesterday\", \"on Nov 18\") with the absolute date in the native tooltip.\n *\n * Falls back to an absolute \"on [Month Day]\" format for dates older than 30 days\n * so that stale timestamps remain legible at a glance.\n *\n * @see https://design.upbound.io/components/date-and-time\n */\nexport function RelativeTime({ date, variant = 'default', title, className, ...props }: RelativeTimeProps) {\n const d = React.useMemo(() => new Date(date), [date]);\n const mounted = useMounted();\n // Fixed locale for the server-rendered/first-paint value (the server can't\n // know the viewer's locale); the viewer's actual locale once mounted.\n const locale = mounted ? undefined : 'en-US';\n\n const [label, setLabel] = React.useState<string>(() => formatRelative(d, variant, locale));\n\n React.useEffect(() => {\n // Re-compute immediately on mount (picks up the viewer's real locale, and\n // avoids the relative label going stale)\n setLabel(formatRelative(d, variant, locale));\n\n const schedule = () => {\n const id = window.setInterval(() => {\n setLabel(formatRelative(d, variant, locale));\n }, updateInterval(d));\n return id;\n };\n const id = schedule();\n return () => window.clearInterval(id);\n }, [d, variant, locale]);\n\n return (\n <time\n dateTime={d.toISOString()}\n title={title ?? absoluteTitle(d, locale)}\n className={cn('tabular-nums', className)}\n {...props}\n >\n {label}\n </time>\n );\n}\n\n// ── Absolute Timestamp ────────────────────────────────────────────────────────\n\n/** Formats am/pm per Content Principles: lowercase, space before, no periods. */\nfunction formatAmPm(date: Date, options: Intl.DateTimeFormatOptions, locale: string | undefined): string {\n const parts = new Intl.DateTimeFormat(locale, options).formatToParts(date);\n let result = '';\n for (const part of parts) {\n if (part.type === 'dayPeriod') {\n result += part.value.toLowerCase().replace(/\\./g, '');\n } else {\n result += part.value;\n }\n }\n return result;\n}\n\nfunction formatAbsolute(date: Date, variant: string, end: Date | undefined, locale: string | undefined): string {\n switch (variant) {\n case 'deadline': {\n const weekday = date.toLocaleDateString(locale, { weekday: 'short' });\n const datePart = date.toLocaleDateString(locale, { month: 'short', day: 'numeric', year: 'numeric' });\n const timePart = formatAmPm(date, { hour: 'numeric', minute: '2-digit' }, locale);\n const tz = date.toLocaleTimeString(locale, { timeZoneName: 'short' }).split(' ').pop() ?? '';\n return `${weekday}, ${datePart} \\u00b7 ${timePart} ${tz}`;\n }\n case 'log': {\n const datePart = date.toLocaleDateString(locale, { month: 'short', day: 'numeric', year: 'numeric' });\n const timePart = formatAmPm(date, { hour: 'numeric', minute: '2-digit' }, locale);\n const tz = date.toLocaleTimeString(locale, { timeZoneName: 'short' }).split(' ').pop() ?? '';\n return `${datePart}, ${timePart} ${tz}`;\n }\n case 'range': {\n if (!end) return date.toLocaleDateString(locale, { month: 'short', day: 'numeric', year: 'numeric' });\n const startYear = date.getFullYear();\n const endYear = end.getFullYear();\n if (startYear === endYear) {\n const start = date.toLocaleDateString(locale, { month: 'short', day: 'numeric' });\n const endStr = end.toLocaleDateString(locale, { month: 'short', day: 'numeric', year: 'numeric' });\n return `${start} \\u2013 ${endStr}`;\n }\n const start = date.toLocaleDateString(locale, { month: 'short', day: 'numeric', year: 'numeric' });\n const endStr = end.toLocaleDateString(locale, { month: 'short', day: 'numeric', year: 'numeric' });\n return `${start} \\u2013 ${endStr}`;\n }\n case 'date':\n default:\n return date.toLocaleDateString(locale, { month: 'short', day: 'numeric', year: 'numeric' });\n }\n}\n\nexport interface AbsoluteTimestampProps extends Omit<React.TimeHTMLAttributes<HTMLTimeElement>, 'dateTime'> {\n /** The timestamp to display. */\n date: Date | string | number;\n /** Format variant matching the Content Principles absolute timestamp table. */\n variant?: 'deadline' | 'log' | 'date' | 'range';\n /** End date for range variant. */\n end?: Date | string | number;\n}\n\n/**\n * Formats a date as an absolute timestamp following the Content Principles.\n * Use for deadlines, certificate expiry, audit logs, and date-only displays.\n */\nexport function AbsoluteTimestamp({ date, variant = 'date', end, className, ...props }: AbsoluteTimestampProps) {\n const d = React.useMemo(() => new Date(date), [date]);\n const e = React.useMemo(() => (end ? new Date(end) : undefined), [end]);\n const mounted = useMounted();\n // Fixed locale for the server-rendered/first-paint value (the server can't\n // know the viewer's locale); the viewer's actual locale once mounted.\n const locale = mounted ? undefined : 'en-US';\n\n return (\n <time\n dateTime={d.toISOString()}\n title={absoluteTitle(d, locale)}\n className={cn('tabular-nums', className)}\n {...props}\n >\n {formatAbsolute(d, variant, e, locale)}\n </time>\n );\n}\n\n// ── Elapsed Time ──────────────────────────────────────────────────────────────\n\nfunction formatElapsed(totalSeconds: number, variant: string): string {\n const days = Math.floor(totalSeconds / 86400);\n const hours = Math.floor((totalSeconds % 86400) / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = Math.floor(totalSeconds % 60);\n\n switch (variant) {\n case 'expanded': {\n const parts: string[] = [];\n if (days > 0) parts.push(`${days} day${days === 1 ? '' : 's'}`);\n if (hours > 0) parts.push(`${hours} hour${hours === 1 ? '' : 's'}`);\n if (minutes > 0) parts.push(`${minutes} minute${minutes === 1 ? '' : 's'}`);\n if (seconds > 0 || parts.length === 0) parts.push(`${seconds} second${seconds === 1 ? '' : 's'}`);\n return parts.join(', ');\n }\n case 'long': {\n if (days > 0) return `${days}d ${hours}h`;\n if (hours > 0) return `${hours}h ${minutes}m`;\n return `${minutes}m`;\n }\n case 'compact':\n default: {\n if (days > 0) return `${days}d ${hours}h`;\n if (hours > 0) return `${hours}h ${minutes}m ${seconds}s`;\n if (minutes > 0) return `${minutes}m ${seconds}s`;\n return `${seconds}s`;\n }\n }\n}\n\nexport interface ElapsedTimeProps extends Omit<React.TimeHTMLAttributes<HTMLTimeElement>, 'dateTime'> {\n /** Total elapsed seconds. Ignored if startedAt is provided. */\n seconds?: number;\n /** Format variant matching the Content Principles elapsed time table. */\n variant?: 'compact' | 'expanded' | 'long';\n /** Live-tick every second for active operations. */\n live?: boolean;\n /** Compute elapsed from a start time instead of a fixed seconds value. */\n startedAt?: Date | string | number;\n}\n\n/**\n * Formats a duration as elapsed time following the Content Principles.\n * Use for reconciliation loops, build jobs, health checks, and running operations.\n */\nexport function ElapsedTime({\n seconds: secondsProp,\n variant = 'compact',\n live = false,\n startedAt,\n className,\n ...props\n}: ElapsedTimeProps) {\n const startDate = React.useMemo(() => (startedAt ? new Date(startedAt) : undefined), [startedAt]);\n\n const computeSeconds = React.useCallback(() => {\n if (startDate) return Math.floor((Date.now() - startDate.getTime()) / 1000);\n return secondsProp ?? 0;\n }, [startDate, secondsProp]);\n\n const [elapsed, setElapsed] = React.useState(computeSeconds);\n\n React.useEffect(() => {\n setElapsed(computeSeconds());\n\n if (!live && !startDate) return;\n\n const id = window.setInterval(() => {\n setElapsed(computeSeconds());\n }, 1000);\n return () => window.clearInterval(id);\n }, [live, startDate, computeSeconds]);\n\n const iso = `PT${elapsed}S`;\n\n return (\n <time dateTime={iso} className={cn('tabular-nums', className)} {...props}>\n {formatElapsed(elapsed, variant)}\n </time>\n );\n}\n","import { useSyncExternalStore } from 'react';\n\nfunction subscribe() {\n return () => {};\n}\n\n/**\n * Returns `false` on the server and during initial client hydration, then\n * `true` once mounted — for values that are only valid client-side (e.g. the\n * viewer's actual `Intl` locale, vs. a fixed locale used for the server-\n * rendered/first-paint value) without a hydration mismatch. Implemented via\n * `useSyncExternalStore` rather than `useEffect` + `setState` — the latter\n * works, but re-derives the same \"true\" value on every mount and trips\n * `react-hooks/set-state-in-effect` since there's no actual subscription.\n */\nexport function useMounted() {\n return useSyncExternalStore(\n subscribe,\n () => true,\n () => false,\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport {\n getCoreRowModel,\n getExpandedRowModel,\n getFacetedRowModel,\n getFacetedUniqueValues,\n getFilteredRowModel,\n getGroupedRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n noop,\n useReactTable,\n type Cell,\n type ColumnFilter,\n type ColumnFiltersState,\n type ColumnOrderState,\n type ColumnPinningState,\n type ExpandedState,\n type PaginationState,\n type RowData,\n type SortingState,\n type VisibilityState,\n} from '@tanstack/react-table';\n\nimport { CelFilterBar } from '@/cel-filter-bar';\nimport { Icon } from '@upbound/monarch-core';\nimport { InputGroup, InputGroupAddon, InputGroupInput } from '@upbound/monarch-core';\nimport { createEmptyCelFilterTree } from '@/lib/cel-filter';\nimport {\n columnFilterValueToStrings,\n getColumnFilterCount,\n mergeColumnFilter,\n} from '@/lib/data-table/contextual-filters';\nimport {\n getTableState,\n hasFilterableColumns,\n isFilterOnlyColumn,\n isSameColumnOrdering,\n normalizeColumnOrdering,\n} from '@/lib/data-table/utils';\nimport { cn } from '@/lib/utils';\nimport { RESIZE_MAX_UNBOUNDED, useTableColumnResizing } from '@/hooks/use-table-column-resizing';\nimport { useGridLayout } from '@/hooks/use-grid-layout';\nimport { useFilterVisibility } from '@/hooks/use-filter-visibility';\n\nimport { ColumnOptions } from './column-options';\nimport type { DataTableProps } from './data-table-types';\nimport { DataTableEmptyView } from './empty-view';\nimport { FilterToggle } from './filter-toggle';\nimport { DataTablePagination } from './pagination';\nimport { DataTableBody, DataTableHeader, DataTableRoot } from './table-primitives';\nimport { ViewFilter } from './view-filter';\nimport { SectionHeader, SectionHeaderContent, SectionHeaderDescription, SectionHeaderTitle } from '../section-header';\n\nconst DEFAULT_PAGE_SIZE = 20;\n\n/**\n * Full port of legacy `TableWrapper` — same prop surface\n * (`DataTableProps<T>` mirrors `TableWrapperProps<T>` name-for-name), same\n * controlled/uncontrolled state merges, same behavior. The only intended\n * difference is that columns, headers, rows, cells, and menus render through\n * Monarch's own primitives instead of legacy's hand-rolled ones.\n */\nexport function DataTable<TData extends RowData>({\n id,\n config,\n\n title,\n description,\n emptyView,\n showError,\n className,\n fitContent = false,\n loading = false,\n renderSkeletonCell,\n serverSidePagination = false,\n ActionsComponent: Actions,\n onRowRender,\n renderExpandedRow,\n expanded: parentExpanded,\n onExpandedChange: parentOnExpandedChange,\n\n disableSearch = false,\n disableFilters = false,\n disableSorting = false,\n paginationConfig = true,\n disableColumnReordering = false,\n disableColumnVisibility = false,\n disableColumnResizing = false,\n disableColumnPinning = false,\n\n searchTerm: parentGlobalFilter,\n onSearchTermChange: parentSetGlobalFilter,\n\n filters: parentColumnFilters,\n onFiltersChange: parentSetColumnFilters,\n\n pagination: parentPagination,\n onPaginationChange: parentSetPagination,\n\n sorting: parentSorting,\n onSortingChange: parentSetSorting,\n\n columnOrdering: parentColumnOrdering,\n onColumnOrderingChange: parentSetColumnOrdering,\n\n columnVisibility: parentColumnVisibility,\n onColumnVisibilityChange: parentSetColumnVisibility,\n\n columnPinning: parentColumnPinning,\n onColumnPinningChange: parentSetColumnPinning,\n\n grouping: parentGrouping,\n onGroupingChange: parentSetGrouping,\n\n celFilterClassName,\n showContextualFilter = false,\n onContextCell,\n contextualMenuActions,\n\n layout = 'auto',\n\n initialColumnSizing,\n onColumnSizingPersist,\n\n stickyHeader = false,\n\n celFilterConfig,\n\n filterVisibility,\n}: DataTableProps<TData>) {\n const isGrid = layout === 'grid';\n const tableBodyScrollRef = React.useRef<HTMLDivElement>(null);\n\n const [innerGlobalFilter, setInnerGlobalFilter] = React.useState('');\n const [innerColumnOrdering, setInnerColumnOrdering] = React.useState<ColumnOrderState>([]);\n const [innerColumnFilters, setInnerColumnFilters] = React.useState<ColumnFiltersState>([]);\n const [innerSorting, setInnerSorting] = React.useState<SortingState>(config.state?.sorting || []);\n const [innerColumnPinning, setInnerColumnPinning] = React.useState<ColumnPinningState>({ left: [], right: [] });\n\n const [innerPagination, setInnerPagination] = React.useState<PaginationState>({\n pageIndex: config.state?.pagination?.pageIndex || 0,\n pageSize: config.state?.pagination?.pageSize || DEFAULT_PAGE_SIZE,\n });\n\n const [innerGrouping, setInnerGrouping] = React.useState<string[]>([]);\n const [innerColumnVisibility, setInnerColumnVisibility] = React.useState<VisibilityState>({});\n const [innerExpanded, setInnerExpanded] = React.useState<ExpandedState>({});\n\n const {\n columnSizing,\n handleColumnSizingChange,\n handleAutosizeAll: rawHandleAutosizeAll,\n handleAutosizeColumn: rawHandleAutosizeColumn,\n handleResetColumnSize: rawHandleResetColumnSize,\n } = useTableColumnResizing({\n initialSizing: initialColumnSizing,\n onColumnSizingPersist,\n maxSize: isGrid ? RESIZE_MAX_UNBOUNDED : undefined,\n });\n\n const {\n showFilterToggle: filterToggleRequested,\n filterRowVisible,\n setFilterRowVisible,\n } = useFilterVisibility(filterVisibility);\n\n const globalFilter = parentGlobalFilter ?? innerGlobalFilter;\n const applyGlobalFilter = parentSetGlobalFilter ?? setInnerGlobalFilter;\n\n const columnFilters = parentColumnFilters || innerColumnFilters;\n const applyColumnFilters = parentSetColumnFilters ?? setInnerColumnFilters;\n\n const pagination = parentPagination || innerPagination;\n const setPagination = parentSetPagination ?? setInnerPagination;\n const shouldDisablePagination = paginationConfig === false;\n\n // In server-side pagination mode a search/filter change must return to the\n // first page — the active page often doesn't exist for the new result set.\n // We do this at the moment of the change rather than from a state-diff\n // effect: filters that arrive via props (deep-link / lens hydration) must\n // NOT reset the page, only edits the user routes through these setters.\n const resetPageIndexOnFilterChange = React.useCallback(() => {\n if (!serverSidePagination || pagination.pageIndex === 0) return;\n setPagination(prev => ({ ...prev, pageIndex: 0 }));\n }, [serverSidePagination, pagination.pageIndex, setPagination]);\n\n const setGlobalFilter = React.useCallback<React.Dispatch<React.SetStateAction<string>>>(\n value => {\n applyGlobalFilter(value);\n resetPageIndexOnFilterChange();\n },\n [applyGlobalFilter, resetPageIndexOnFilterChange],\n );\n\n const setColumnFilters = React.useCallback<React.Dispatch<React.SetStateAction<ColumnFiltersState>>>(\n value => {\n applyColumnFilters(value);\n resetPageIndexOnFilterChange();\n },\n [applyColumnFilters, resetPageIndexOnFilterChange],\n );\n\n React.useLayoutEffect(() => {\n if (shouldDisablePagination) return;\n tableBodyScrollRef.current?.scrollTo({ top: 0 });\n }, [shouldDisablePagination, pagination.pageIndex]);\n\n const sorting = parentSorting || innerSorting;\n const setSorting = parentSetSorting ?? setInnerSorting;\n\n const columnOrdering = parentColumnOrdering || innerColumnOrdering;\n const setColumnOrdering = parentSetColumnOrdering ?? setInnerColumnOrdering;\n\n const columnVisibility = parentColumnVisibility ?? innerColumnVisibility;\n const setColumnVisibility = parentSetColumnVisibility ?? setInnerColumnVisibility;\n\n const expanded = parentExpanded ?? innerExpanded;\n const setExpanded = parentOnExpandedChange ?? setInnerExpanded;\n\n const columnPinning = parentColumnPinning ?? innerColumnPinning;\n const setColumnPinning = parentSetColumnPinning ?? setInnerColumnPinning;\n\n const grouping = parentGrouping ?? innerGrouping;\n const setGrouping = parentSetGrouping ?? setInnerGrouping;\n\n const hasGrouping = grouping.length > 0;\n\n const hasExternalSearch = parentGlobalFilter !== undefined;\n const hasExternalFilters = parentColumnFilters !== undefined;\n const shouldDisableFiltersModels = !!disableFilters && !!disableSearch && !hasExternalSearch && !hasExternalFilters;\n\n // eslint-disable-next-line react-hooks/incompatible-library\n const table = useReactTable<TData>({\n ...config,\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: !disableSorting ? getSortedRowModel() : undefined,\n getPaginationRowModel: !shouldDisablePagination ? getPaginationRowModel() : undefined,\n getFilteredRowModel: !shouldDisableFiltersModels ? getFilteredRowModel() : undefined,\n getFacetedRowModel: !shouldDisableFiltersModels ? getFacetedRowModel() : undefined,\n getFacetedUniqueValues: !shouldDisableFiltersModels ? getFacetedUniqueValues() : undefined,\n ...(!!renderExpandedRow && {\n getExpandedRowModel: getExpandedRowModel(),\n getRowCanExpand: () => true,\n paginateExpandedRows: false,\n }),\n getGroupedRowModel: hasGrouping ? getGroupedRowModel() : undefined,\n getExpandedRowModel: hasGrouping ? getExpandedRowModel() : undefined,\n groupedColumnMode: hasGrouping ? 'reorder' : undefined,\n enableFilters: !shouldDisableFiltersModels,\n enableGlobalFilter: !shouldDisableFiltersModels,\n enableColumnFilters: !shouldDisableFiltersModels,\n enableColumnResizing: !disableColumnResizing,\n enableColumnPinning: !disableColumnPinning,\n enableHiding: !disableColumnVisibility,\n columnResizeMode: disableColumnResizing ? undefined : isGrid ? 'onEnd' : 'onChange',\n defaultColumn: {\n size: 150,\n minSize: 40,\n maxSize: isGrid ? RESIZE_MAX_UNBOUNDED : 500,\n },\n state: {\n sorting: disableSorting ? [] : sorting,\n globalFilter: shouldDisableFiltersModels ? '' : globalFilter,\n columnFilters: shouldDisableFiltersModels ? [] : columnFilters,\n pagination: shouldDisablePagination ? undefined : pagination,\n columnOrder: disableColumnReordering ? [] : columnOrdering,\n columnVisibility: disableColumnVisibility ? {} : columnVisibility,\n columnSizing: disableColumnResizing ? {} : columnSizing,\n columnPinning: disableColumnPinning ? { left: [], right: [] } : columnPinning,\n ...(!!renderExpandedRow && { expanded }),\n grouping,\n ...(hasGrouping && { expanded: true as const }),\n },\n manualSorting: serverSidePagination,\n manualFiltering: serverSidePagination,\n manualPagination: serverSidePagination,\n onSortingChange: disableSorting ? noop : setSorting,\n onColumnFiltersChange: shouldDisableFiltersModels ? noop : setColumnFilters,\n onGlobalFilterChange: shouldDisableFiltersModels ? noop : setGlobalFilter,\n onPaginationChange: shouldDisablePagination ? noop : setPagination,\n onColumnOrderChange: disableColumnReordering ? noop : setColumnOrdering,\n onColumnVisibilityChange: disableColumnVisibility ? noop : setColumnVisibility,\n onColumnSizingChange: disableColumnResizing ? noop : handleColumnSizingChange,\n onColumnPinningChange: disableColumnPinning ? noop : setColumnPinning,\n ...(!!renderExpandedRow && {\n onExpandedChange: (updater: ExpandedState | ((prev: ExpandedState) => ExpandedState)) =>\n setExpanded(prev => (typeof updater === 'function' ? updater(prev) : updater)),\n }),\n onGroupingChange: setGrouping,\n });\n\n const headerGroups = table.getHeaderGroups();\n const tableRows = table.getRowModel().rows;\n const rowCount = table.getRowCount();\n\n const flatColumns = table.getAllFlatColumns();\n const displayableColumns = flatColumns.filter(col => !isFilterOnlyColumn(col));\n\n const orderedVisibleColumns = table.getVisibleLeafColumns().filter(col => !isFilterOnlyColumn(col));\n\n // Only offer the toggle when there's actually something to filter — a plain\n // filterable column or a CEL filter config — and filtering isn't disabled.\n // Otherwise the button would render but do nothing.\n const hasFilters = !!celFilterConfig || hasFilterableColumns(flatColumns);\n const showFilterToggle = filterToggleRequested && !disableFilters && hasFilters;\n\n const [gridMeasuredMins, setGridMeasuredMins] = React.useState<Record<string, number>>({});\n const { gridTemplateColumns, gridRootRef, handleAutosizeAll, handleAutosizeColumn, handleResetColumnSize } =\n useGridLayout<TData>({\n layout,\n table,\n tableBodyScrollRef,\n displayableColumns,\n columnOrdering,\n gridMeasuredMins,\n setGridMeasuredMins,\n handleColumnSizingChange,\n rawHandleAutosizeAll,\n rawHandleAutosizeColumn,\n rawHandleResetColumnSize,\n });\n\n const handleContextCell = React.useCallback(\n (filter: ColumnFilter, cell: Cell<TData, unknown>) => {\n if (celFilterConfig?.onContextualFilter) {\n celFilterConfig.onContextualFilter({\n columnId: filter.id,\n values: columnFilterValueToStrings(filter.value),\n cell,\n });\n return;\n }\n\n const filterDefinition = table.getColumn(filter.id)?.columnDef.meta?.filter;\n setColumnFilters(prev => mergeColumnFilter(prev, filter, filterDefinition));\n onContextCell?.(filter, cell);\n },\n [celFilterConfig, onContextCell, setColumnFilters, table],\n );\n\n const handleContextSearch = React.useCallback(\n (searchTerm: string) => {\n setGlobalFilter(searchTerm);\n },\n [setGlobalFilter],\n );\n\n const totalTableWidth = React.useMemo(() => {\n if (isGrid) return 0;\n const firstGroup = headerGroups[0];\n if (!firstGroup) return 0;\n\n const displayableIds = new Set(displayableColumns.map(c => c.id));\n return firstGroup.headers\n .filter(h => displayableIds.has(h.column.id))\n .reduce((sum, h) => sum + h.column.getSize(), 0);\n }, [isGrid, headerGroups, displayableColumns]);\n\n const filterCount = celFilterConfig\n ? celFilterConfig.activeFilterCount\n : table\n .getState()\n .columnFilters.map(({ id: columnFilterId, value }) =>\n getColumnFilterCount(value, table.getColumn(columnFilterId)?.columnDef.meta?.filter),\n )\n .reduce((prev, curr) => prev + curr, 0);\n\n const tableState = getTableState({ error: !!showError, loading, rowCount });\n\n const shouldDisable = tableState === 'error';\n const shouldRenderTableContent = tableState !== 'error' && tableState !== 'empty';\n\n const resetFilters = () => {\n if (celFilterConfig) {\n celFilterConfig.onTreeChange(createEmptyCelFilterTree());\n } else {\n table.resetColumnFilters();\n }\n setGlobalFilter('');\n };\n\n React.useEffect(() => {\n // Sync the inner mirror when the parent-supplied searchTerm changes (e.g. switching views).\n if (parentGlobalFilter !== undefined) {\n setInnerGlobalFilter(parentGlobalFilter);\n }\n }, [parentGlobalFilter]);\n\n React.useEffect(() => {\n if (disableColumnReordering) return;\n\n const allColumnIds = flatColumns.map(col => col.id);\n const normalizedColumnOrdering = normalizeColumnOrdering(columnOrdering, allColumnIds);\n\n if (!isSameColumnOrdering(columnOrdering, normalizedColumnOrdering)) {\n setColumnOrdering(normalizedColumnOrdering);\n }\n }, [columnOrdering, disableColumnReordering, flatColumns, setColumnOrdering]);\n\n const showViewHeader = !!title || !!Actions;\n const showColumnOptions = !disableColumnReordering || !disableColumnVisibility;\n\n const toolbarSearch = !disableSearch && (\n <InputGroup className=\"w-70\">\n <InputGroupAddon align=\"inline-start\">\n <Icon name=\"magnifying-glass\" />\n </InputGroupAddon>\n <InputGroupInput\n aria-label=\"Search\"\n placeholder=\"Search…\"\n disabled={shouldDisable}\n value={globalFilter}\n onChange={e => setGlobalFilter(e.target.value)}\n />\n </InputGroup>\n );\n\n const toolbarColumns = !!showColumnOptions && (\n <ColumnOptions\n columns={flatColumns}\n columnOrdering={columnOrdering}\n onColumnOrderingChange={setColumnOrdering}\n disableColumnOrdering={disableColumnReordering}\n />\n );\n\n return (\n <div\n id={`table-${id}`}\n data-testid={`table-${id}`}\n className={cn(\n 'flex w-full flex-col',\n !fitContent && (shouldRenderTableContent ? 'h-full min-h-0' : 'h-screen max-h-[calc(100vh-100px)]'),\n className,\n )}\n >\n {showViewHeader && (\n <SectionHeader className=\"mb-4 flex w-full gap-2\">\n <SectionHeaderContent>\n {!!title && <SectionHeaderTitle>{title}</SectionHeaderTitle>}\n {!!description && <SectionHeaderDescription>{description}</SectionHeaderDescription>}\n </SectionHeaderContent>\n </SectionHeader>\n )}\n\n <div className=\"mb-4 flex flex-row gap-2\">\n {toolbarSearch}\n <div className=\"ml-auto flex items-center gap-2\">\n {showFilterToggle && (\n <FilterToggle pressed={filterRowVisible} onPressedChange={setFilterRowVisible} count={filterCount} />\n )}\n {!!Actions && <Actions state={tableState} />}\n {toolbarColumns}\n </div>\n </div>\n\n {!disableFilters && (!showFilterToggle || filterRowVisible) && (\n <div className=\"flex w-full\">\n {celFilterConfig ? (\n <div className={cn('mr-2 mb-4 min-w-0 flex-1', celFilterClassName)}>\n <CelFilterBar\n schema={celFilterConfig.schema}\n tree={celFilterConfig.tree}\n onChange={celFilterConfig.onTreeChange}\n onCompileResultChange={celFilterConfig.onCompileResultChange}\n onRestrictedOptionSelect={celFilterConfig.onRestrictedOptionSelect}\n showClearButton={celFilterConfig.showClearButton}\n />\n </div>\n ) : (\n <ViewFilter\n columns={flatColumns}\n columnFilters={columnFilters}\n onColumnFiltersChange={setColumnFilters}\n className=\"data-[visible-filters=true]:mb-4\"\n />\n )}\n </div>\n )}\n\n {shouldRenderTableContent ? (\n <>\n <div className=\"flex min-h-0 flex-1 flex-col\" data-testid=\"table-main\">\n <div\n ref={tableBodyScrollRef}\n className={cn(\n 'min-h-0 flex-1 overflow-auto rounded-lg border **:data-[slot=table-container]:overflow-visible',\n !!stickyHeader && 'max-h-[calc(100svh-250px)]',\n )}\n >\n <DataTableRoot\n layout={layout}\n gridTemplateColumns={gridTemplateColumns}\n gridRootRef={gridRootRef}\n style={\n isGrid\n ? { width: '100%' }\n : totalTableWidth > 0\n ? { width: `max(100%, ${totalTableWidth}px)`, minWidth: '100%' }\n : { width: '100%' }\n }\n >\n <DataTableHeader\n headerGroups={headerGroups}\n onAutosizeAll={handleAutosizeAll}\n onAutosizeColumn={handleAutosizeColumn}\n onResetColumnSize={handleResetColumnSize}\n stickyHeader={stickyHeader}\n layout={layout}\n />\n <DataTableBody\n tableRows={tableRows}\n tableState={tableState}\n columns={orderedVisibleColumns}\n skeletonRowCount={pagination.pageSize}\n renderSkeletonCell={renderSkeletonCell}\n onRowRender={onRowRender}\n renderExpandedRow={renderExpandedRow}\n showContextualFilter={showContextualFilter}\n onContextCell={handleContextCell}\n onContextSearch={handleContextSearch}\n contextualMenuActions={contextualMenuActions}\n layout={layout}\n />\n </DataTableRoot>\n </div>\n </div>\n\n {!shouldDisablePagination && !!pagination && (\n <DataTablePagination\n rowCount={rowCount}\n rowCountRelation={config.rowCountRelation ?? 'eq'}\n paginationConfig={paginationConfig}\n pageSize={pagination.pageSize}\n pageIndex={pagination.pageIndex}\n onPageChange={p => table.setPageIndex(p - 1)}\n onPageSizeChange={nextPageSize =>\n setPagination(prev => ({ ...(prev || pagination), pageIndex: 0, pageSize: nextPageSize }))\n }\n />\n )}\n </>\n ) : (\n <DataTableEmptyView\n emptyView={emptyView}\n tableState={tableState}\n filterCount={filterCount + (!!globalFilter.trim() ? 1 : 0)}\n resetFilters={resetFilters}\n />\n )}\n </div>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport { Icon } from '@upbound/monarch-core';\nimport { type DateRange } from 'react-day-picker';\n\nimport { cn, sortBy } from '@/lib/utils';\nimport { useMounted } from '@/hooks/use-mounted';\nimport { Badge } from '@upbound/monarch-core';\nimport { Button } from '@upbound/monarch-core';\nimport { ButtonGroup, ButtonGroupText } from '@upbound/monarch-core';\nimport { Calendar } from '@upbound/monarch-core';\nimport {\n Combobox,\n ComboboxChip,\n ComboboxClearAll,\n ComboboxCollection,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxGroup,\n ComboboxInput,\n ComboboxItem,\n ComboboxLabel,\n ComboboxList,\n ComboboxSelectedChips,\n ComboboxSeparator,\n ComboboxTrigger,\n ComboboxValue,\n} from '@upbound/monarch-core';\nimport { Input } from '@upbound/monarch-core';\nimport { InputGroup, InputGroupAddon, InputGroupInput, InputGroupText } from '@upbound/monarch-core';\nimport { Label } from '@upbound/monarch-core';\nimport { Popover, PopoverContent, PopoverTrigger } from '@upbound/monarch-core';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@upbound/monarch-core';\n\nimport { useCelFilterEditorState, type CelConditionEditorController } from '@/hooks/use-cel-filter-editor-state';\nimport {\n allowsMultipleConditions,\n appendCondition,\n applyDisplayRules,\n applyOperatorChange,\n calendarDayStartInstant,\n compileCelFilterTree,\n computeIsEmitReady,\n createDefaultCondition,\n dateBoundaryForOperator,\n formatCalendarDateUtc,\n formatInstantLabel,\n getAllowedOperators,\n getOperatorLabel,\n getQuantifierLabel,\n isCelFilterCondition,\n isCheckboxCelValue,\n isDateRangeOperator,\n isDateRelativeOperator,\n isDateWindowOperator,\n isRelativeDateCelValue,\n parseCalendarDate,\n readDateCelValue,\n readMapKeyCelValue,\n readMultiTextCelValue,\n readTimeOfDay,\n RELATIVE_DURATION_PRESET_VALUES,\n removeConditionById,\n replaceCondition,\n resolveColumnDefinition,\n resolveFilterShape,\n withTimeOfDay,\n type CelColumnDefinition,\n type CelColumnOption,\n type CelFilterBarProps,\n type CelFilterCondition,\n type CelOperator,\n type CompileResult,\n type DateCelValue,\n type MapKeyCelValue,\n type MultiTextCelValue,\n type RelativeDurationPreset,\n} from '@/lib/cel-filter';\n\ntype PortalContainer = React.ComponentProps<typeof ComboboxContent>['container'];\n\nconst RELATIVE_PRESET_LABELS: Record<RelativeDurationPreset, string> = {\n '24h': 'Last 24 hours',\n '168h': 'Last 7 days',\n '720h': 'Last 30 days',\n};\n\n// Neutralizes Select's default purple focus ring/border and matches the\n// plain grey hover/focus background the rest of a pill's segments (value\n// trigger, remove button — both Button variant=\"outline\") use, so every\n// Select-based segment reads as part of one continuous control. `!` is\n// required on the hover border: Select's own hover border is a compound\n// variant (hover:not-disabled:not-aria-invalid:border-ring/50) that a plain\n// hover:border-input doesn't win against via class order alone.\nconst SEGMENT_SELECT_TRIGGER_CLASSNAME =\n 'hover:border-input! focus-visible:border-input focus-visible:ring-0 hover:bg-muted focus-visible:bg-muted aria-expanded:bg-muted';\n\n// ── CelFilterBar ──────────────────────────────────────\n\nfunction CelFilterBar({\n tree,\n onChange,\n schema,\n onCompileResultChange,\n onRestrictedOptionSelect,\n showClearButton = false,\n className,\n}: CelFilterBarProps) {\n const editor = useCelFilterEditorState();\n const onCompileResultChangeRef = React.useRef(onCompileResultChange);\n React.useEffect(() => {\n onCompileResultChangeRef.current = onCompileResultChange;\n });\n\n const rawResult = React.useMemo(() => compileCelFilterTree(tree, schema), [tree, schema]);\n const displayResult = React.useMemo(\n () =>\n applyDisplayRules(rawResult, {\n editingConditionId: editor.editingConditionId,\n committedConditionIds: editor.committedConditionIds,\n }),\n [rawResult, editor.editingConditionId, editor.committedConditionIds],\n );\n const isEmitReady = React.useMemo(\n () =>\n computeIsEmitReady(rawResult, editor.editingConditionId, schema, tree, {\n activeSurface: editor.activeSurface,\n committedConditionIds: editor.committedConditionIds,\n }),\n [rawResult, editor.editingConditionId, editor.activeSurface, editor.committedConditionIds, schema, tree],\n );\n\n React.useEffect(() => {\n onCompileResultChangeRef.current?.({ ...displayResult, isEmitReady });\n }, [displayResult, isEmitReady]);\n\n const conditions = tree.root.children.filter(isCelFilterCondition);\n\n // Ref for the CelFilterBar's own root node, used to anchor Combobox popups.\n // Helps rendering correctly the popup when rendered inside a modal Dialog/Sheet.\n const containerRef = React.useRef<HTMLDivElement>(null);\n\n function handleAddFilter(columnId: string) {\n const condition = createDefaultCondition({ schema, columnId });\n onChange(appendCondition(tree, condition));\n editor.beginEditing(condition.id);\n editor.suppressDismissFor(condition.id);\n }\n\n function handleRemove(conditionId: string) {\n onChange(removeConditionById(tree, conditionId));\n editor.removeCondition(conditionId);\n }\n\n function handleClearAll() {\n onChange({ root: { ...tree.root, children: [] } });\n editor.clearSuppress();\n }\n\n return (\n <div data-slot=\"cel-filter-bar\" className={cn('flex flex-wrap items-center gap-2', className)} ref={containerRef}>\n <CelAddFilterButton schema={schema} conditions={conditions} onSelect={handleAddFilter} container={containerRef} />\n\n {conditions.map(condition => {\n const columnDef = resolveColumnDefinition(condition, schema);\n if (!columnDef) return null;\n return (\n <CelFilterPill\n key={condition.id}\n condition={condition}\n columnDef={columnDef}\n schema={schema}\n tree={tree}\n onChange={onChange}\n controller={editor.getController(condition.id)}\n issues={displayResult.issues.filter(issue => issue.nodeId === condition.id)}\n onRemove={() => handleRemove(condition.id)}\n onRestrictedOptionSelect={onRestrictedOptionSelect}\n container={containerRef}\n />\n );\n })}\n\n {showClearButton && conditions.length > 0 && (\n <Button variant=\"ghost\" size=\"sm\" onClick={handleClearAll}>\n Clear all\n </Button>\n )}\n </div>\n );\n}\n\n// ── Add filter menu ───────────────────────────────────\n\ntype CelAddFilterGroup = { value: string; items: CelColumnDefinition[] };\n\nfunction CelAddFilterButton({\n schema,\n conditions,\n onSelect,\n container,\n}: {\n schema: CelFilterBarProps['schema'];\n conditions: CelFilterCondition[];\n onSelect: (columnId: string) => void;\n container?: PortalContainer;\n}) {\n const usedSingleInstanceColumnIds = new Set(\n conditions\n .map(condition => resolveColumnDefinition(condition, schema))\n .filter(\n (columnDef): columnDef is CelColumnDefinition => !!columnDef && !allowsMultipleConditions(columnDef.filterType),\n )\n .map(columnDef => columnDef.id),\n );\n const availableColumns = schema.columns.filter(column => !usedSingleInstanceColumnIds.has(column.id));\n\n const groupMap = new Map<string, CelColumnDefinition[]>();\n for (const column of availableColumns) {\n const key = column.group ?? '';\n const list = groupMap.get(key) ?? [];\n list.push(column);\n groupMap.set(key, list);\n }\n const groups: CelAddFilterGroup[] = sortBy(\n Array.from(groupMap.entries()).map(([value, items]) => ({ value, items: sortBy(items, item => item.title) })),\n group => group.value,\n );\n\n return (\n <Combobox\n items={groups}\n itemToStringValue={(item: CelColumnDefinition) => item.title}\n itemToStringLabel={(item: CelColumnDefinition) => item.title}\n onValueChange={(column: CelColumnDefinition | null) => {\n if (column) onSelect(column.id);\n }}\n >\n {/* role=\"combobox\" doesn't pick up child text as its accessible name the\n way a plain button would — an explicit aria-label is required, not\n just a nicety. */}\n <ComboboxTrigger aria-label=\"Add filter\" render={<Button variant=\"outline\" />}>\n <Icon name=\"plus\" data-icon=\"inline-start\" />\n Add filter\n </ComboboxTrigger>\n <ComboboxContent container={container} align=\"start\" className=\"w-64\">\n <ComboboxInput showTrigger={false} placeholder=\"Search filters…\" />\n <ComboboxEmpty>No filters found.</ComboboxEmpty>\n <ComboboxList>\n {(group: CelAddFilterGroup) => (\n <ComboboxGroup key={group.value} items={group.items}>\n {group.value && <ComboboxLabel>{group.value}</ComboboxLabel>}\n <ComboboxCollection>\n {(column: CelColumnDefinition) => (\n <ComboboxItem key={column.id} value={column}>\n {column.title}\n </ComboboxItem>\n )}\n </ComboboxCollection>\n </ComboboxGroup>\n )}\n </ComboboxList>\n </ComboboxContent>\n </Combobox>\n );\n}\n\n// ── Filter pill ────────────────────────────────────────\n\nfunction formatConditionSummary(\n condition: CelFilterCondition,\n columnDef: CelColumnDefinition,\n locale?: string,\n): string {\n const shape = columnDef.filterType === 'keyValue' ? 'map' : columnDef.filterType;\n\n switch (shape) {\n case 'checkbox': {\n const value = isCheckboxCelValue(condition.value) ? condition.value : [];\n if (value.length === 0) return 'Any';\n if (value.length === 1) {\n return columnDef.options?.find(opt => opt.value === value[0])?.label ?? value[0];\n }\n return `${value.length} ${columnDef.pluralTitle}`;\n }\n case 'radio':\n case 'static': {\n const value = typeof condition.value === 'string' ? condition.value : '';\n if (!value) return 'Any';\n return columnDef.options?.find(opt => opt.value === value)?.label ?? value;\n }\n case 'text':\n return typeof condition.value === 'string' && condition.value ? condition.value : 'Any';\n case 'multiText': {\n const value = readMultiTextCelValue(condition.value);\n if (value.tokens.length === 0) return 'Any';\n if (value.tokens.length === 1) return value.tokens[0];\n return `${value.tokens.length} values`;\n }\n case 'date': {\n const value = readDateCelValue(condition.value);\n if (isRelativeDateCelValue(value)) return value.preset ? RELATIVE_PRESET_LABELS[value.preset] : 'Any';\n if (value.range)\n return `${formatInstantLabel(value.range.start, { locale })} – ${formatInstantLabel(value.range.end, { locale })}`;\n if (value.instant) return formatInstantLabel(value.instant, { withTime: value.hasTime, locale });\n return 'Any';\n }\n case 'map': {\n const value = readMapKeyCelValue(condition.value);\n if (!value.key) return 'Any';\n return value.value ? `${value.key}=${value.value}` : value.key;\n }\n default:\n return 'Any';\n }\n}\n\nfunction CelFilterPill({\n condition,\n columnDef,\n schema,\n tree,\n onChange,\n controller,\n issues,\n onRemove,\n onRestrictedOptionSelect,\n container,\n}: {\n condition: CelFilterCondition;\n columnDef: CelColumnDefinition;\n schema: CelFilterBarProps['schema'];\n tree: CelFilterBarProps['tree'];\n onChange: CelFilterBarProps['onChange'];\n controller: CelConditionEditorController;\n issues: CompileResult['issues'];\n onRemove: () => void;\n onRestrictedOptionSelect: CelFilterBarProps['onRestrictedOptionSelect'];\n container?: PortalContainer;\n}) {\n const shape = resolveFilterShape(condition, schema) ?? columnDef.filterType;\n const mounted = useMounted();\n // Fixed locale for the server-rendered/first-paint value (the server can't\n // know the viewer's locale); the viewer's actual locale once mounted. Only\n // the 'date' shape's summary is locale-sensitive, but computed unconditionally\n // since hooks can't run after the early returns below.\n const locale = mounted ? undefined : 'en-US';\n\n // checkbox/radio always compose Combobox for their value editor (own trigger\n // + popup, per Monarch's standing directive for multi/single-select pickers)\n // rather than sharing the generic Popover the other shapes use below.\n if (shape === 'checkbox') {\n return (\n <CelCheckboxComboboxPill\n condition={condition}\n columnDef={columnDef}\n tree={tree}\n onChange={onChange}\n controller={controller}\n issues={issues}\n onRemove={onRemove}\n onRestrictedOptionSelect={onRestrictedOptionSelect}\n container={container}\n />\n );\n }\n if (shape === 'radio') {\n return (\n <CelRadioComboboxPill\n condition={condition}\n columnDef={columnDef}\n tree={tree}\n onChange={onChange}\n controller={controller}\n issues={issues}\n onRemove={onRemove}\n onRestrictedOptionSelect={onRestrictedOptionSelect}\n container={container}\n />\n );\n }\n\n function updateValue(value: CelFilterCondition['value']) {\n onChange(replaceCondition(tree, condition.id, c => ({ ...c, value })));\n }\n\n function updateOperator(operator: CelOperator) {\n const hadValue = condition.value !== undefined;\n const next = applyOperatorChange(condition, operator, shape);\n onChange(replaceCondition(tree, condition.id, () => next));\n // Switching operators can clear an incompatible value (e.g. an instant when\n // moving to a range operator) — reopen the value popover so the user isn't\n // left with a silently invalid pill they have to notice and click back into.\n if (hadValue && next.value === undefined) controller.beginEditing();\n }\n\n const allowedOperators = getAllowedOperators(columnDef);\n\n return (\n <Popover\n open={controller.popoverVisible}\n onOpenChange={open => {\n if (open) controller.beginEditing();\n else if (!controller.isDismissSuppressed()) controller.handlePopoverDismiss();\n }}\n >\n <ButtonGroup>\n <ButtonGroupText>{columnDef.title}</ButtonGroupText>\n <CelOperatorSegment\n columnTitle={columnDef.title}\n operator={condition.operator}\n allowedOperators={allowedOperators}\n hideOnSingleOperator={columnDef.hideOnSingleOperator}\n onChangeOperator={updateOperator}\n />\n {shape === 'multiText' && (\n <CelQuantifierSegment\n columnTitle={columnDef.title}\n value={readMultiTextCelValue(condition.value)}\n onChangeValue={updateValue}\n />\n )}\n <PopoverTrigger asChild>\n <Button variant=\"outline\" className=\"gap-1 font-normal\">\n <span className={cn(issues.length > 0 && 'text-destructive')}>\n {formatConditionSummary(condition, columnDef, locale)}\n </span>\n <Icon name=\"chevron-down\" size=\"sm\" className=\"text-muted-foreground\" />\n </Button>\n </PopoverTrigger>\n <Button variant=\"outline\" size=\"icon\" aria-label={`Remove ${columnDef.title} filter`} onClick={onRemove}>\n <Icon name=\"xmark\" />\n </Button>\n </ButtonGroup>\n <PopoverContent align=\"start\" className={shape === 'date' ? 'w-fit' : 'w-72'}>\n {shape === 'text' && (\n <CelTextValueEditor condition={condition} onChangeValue={updateValue} onCommit={controller.commit} />\n )}\n {shape === 'multiText' && <CelMultiTextValueEditor condition={condition} onChangeValue={updateValue} />}\n {shape === 'date' && <CelDateValueEditor condition={condition} onChangeValue={updateValue} />}\n {shape === 'map' && (\n <CelKeyValueValueEditor condition={condition} onChangeValue={updateValue} onCommit={controller.commit} />\n )}\n\n {issues.length > 0 && (\n <p className=\"text-body-sm text-destructive\">{issues.map(issue => issue.message).join(' ')}</p>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n\n// ── Operator segment ───────────────────────────────────\n// Shared between the Popover-based pill (text/multiText/date/map) and the\n// two Combobox-based pills below — always its own ButtonGroup segment,\n// never hidden inside the value editor.\n\nfunction CelOperatorSegment({\n columnTitle,\n operator,\n allowedOperators,\n hideOnSingleOperator,\n onChangeOperator,\n}: {\n columnTitle: string;\n operator: CelOperator;\n allowedOperators: CelOperator[];\n hideOnSingleOperator?: boolean;\n onChangeOperator: (operator: CelOperator) => void;\n}) {\n if (allowedOperators.length > 1) {\n return (\n <Select value={operator} onValueChange={value => onChangeOperator(value as CelOperator)}>\n {/* role=\"combobox\" doesn't pick up child text as its accessible name\n the way a plain button would — an explicit aria-label is required,\n not just a nicety. */}\n <SelectTrigger aria-label={`${columnTitle} operator`} className={SEGMENT_SELECT_TRIGGER_CLASSNAME}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent position=\"popper\">\n <SelectGroup>\n {allowedOperators.map(op => (\n <SelectItem key={op} value={op}>\n {getOperatorLabel(op)}\n </SelectItem>\n ))}\n </SelectGroup>\n </SelectContent>\n </Select>\n );\n }\n if (allowedOperators.length === 1 && !hideOnSingleOperator) {\n return (\n <ButtonGroupText className=\"text-muted-foreground font-normal\">\n {getOperatorLabel(allowedOperators[0])}\n </ButtonGroupText>\n );\n }\n return null;\n}\n\n// ── Quantifier segment ─────────────────────────────────\n// multiText-only: \"any of\" / \"all of\" across a condition's tokens. Its own\n// plain Select segment appended right after the operator — not a switcher\n// living inside the value popover — with no search (only two options).\n// Hidden until there's more than one token, since quantifier is meaningless\n// (and unvalidated) for zero or one.\n\nfunction CelQuantifierSegment({\n columnTitle,\n value,\n onChangeValue,\n}: {\n columnTitle: string;\n value: MultiTextCelValue;\n onChangeValue: (value: MultiTextCelValue) => void;\n}) {\n if (value.tokens.length <= 1) return null;\n\n return (\n <Select\n value={value.quantifier ?? 'any'}\n onValueChange={next => {\n if (next === 'any' || next === 'all') onChangeValue({ ...value, quantifier: next });\n }}\n >\n {/* role=\"combobox\" doesn't pick up child text as its accessible name\n the way a plain button would — an explicit aria-label is required,\n not just a nicety. */}\n <SelectTrigger aria-label={`${columnTitle} quantifier`} className={SEGMENT_SELECT_TRIGGER_CLASSNAME}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent position=\"popper\">\n <SelectGroup>\n <SelectItem value=\"any\">{getQuantifierLabel('any')}</SelectItem>\n <SelectItem value=\"all\">{getQuantifierLabel('all')}</SelectItem>\n </SelectGroup>\n </SelectContent>\n </Select>\n );\n}\n\n// ── Checkbox pill (Combobox, multi-select) ────────────\n// Same Combobox composition as FilterChip's searchable branch in\n// filter-bar.tsx — Monarch's standing pattern for multi-select pickers.\n// A restricted (disabled) option is never blocked at the primitive level\n// (Base UI's own `disabled` would silently swallow the click, same failure\n// mode Radix's Checkbox has); instead every selection change is diffed\n// against the previous value and a newly-picked disabled option is reverted\n// and redirected to `onRestrictedOptionSelect`.\n\nfunction CelCheckboxComboboxPill({\n condition,\n columnDef,\n tree,\n onChange,\n controller,\n issues,\n onRemove,\n onRestrictedOptionSelect,\n container,\n}: {\n condition: CelFilterCondition;\n columnDef: CelColumnDefinition;\n tree: CelFilterBarProps['tree'];\n onChange: CelFilterBarProps['onChange'];\n controller: CelConditionEditorController;\n issues: CompileResult['issues'];\n onRemove: () => void;\n onRestrictedOptionSelect: CelFilterBarProps['onRestrictedOptionSelect'];\n container?: PortalContainer;\n}) {\n const options = sortBy(columnDef.options ?? [], o => o.label);\n const value = isCheckboxCelValue(condition.value) ? condition.value : [];\n const selected = options.filter(option => value.includes(option.value));\n const allowedOperators = getAllowedOperators(columnDef);\n\n function updateOperator(operator: CelOperator) {\n onChange(replaceCondition(tree, condition.id, c => applyOperatorChange(c, operator, 'checkbox')));\n }\n\n function applySelection(nextSelected: CelColumnOption[]) {\n const current = new Set(value);\n const nextValues = new Set(nextSelected.map(option => option.value));\n for (const option of nextSelected) {\n if (!current.has(option.value) && option.disabled) {\n onRestrictedOptionSelect?.({ columnId: columnDef.id, value: option.value, label: option.label });\n nextValues.delete(option.value);\n }\n }\n onChange(replaceCondition(tree, condition.id, c => ({ ...c, value: Array.from(nextValues) })));\n const added = nextSelected.find(option => !current.has(option.value) && !option.disabled && option.operator);\n if (added?.operator) updateOperator(added.operator);\n }\n\n return (\n <Combobox\n items={options}\n itemToStringValue={(item: CelColumnOption) => item.label}\n multiple\n value={selected}\n onValueChange={(next: CelColumnOption[]) => applySelection(next)}\n open={controller.popoverVisible}\n onOpenChange={(open: boolean) => {\n if (open) controller.beginEditing();\n else if (!controller.isDismissSuppressed()) controller.handlePopoverDismiss();\n }}\n >\n <ButtonGroup>\n <ButtonGroupText>{columnDef.title}</ButtonGroupText>\n <CelOperatorSegment\n columnTitle={columnDef.title}\n operator={condition.operator}\n allowedOperators={allowedOperators}\n hideOnSingleOperator={columnDef.hideOnSingleOperator}\n onChangeOperator={updateOperator}\n />\n {/* role=\"combobox\" doesn't pick up child text as its accessible name\n the way a plain button would — an explicit aria-label is required,\n not just a nicety. */}\n <ComboboxTrigger\n aria-label={`${columnDef.title} value`}\n render={<Button variant=\"outline\" className=\"gap-1 font-normal [&>svg:last-child]:size-(--icon-sm)\" />}\n >\n <span className={cn(issues.length > 0 && 'text-destructive')}>\n {formatConditionSummary(condition, columnDef)}\n </span>\n </ComboboxTrigger>\n <Button variant=\"outline\" size=\"icon\" aria-label={`Remove ${columnDef.title} filter`} onClick={onRemove}>\n <Icon name=\"xmark\" />\n </Button>\n </ButtonGroup>\n <ComboboxContent container={container} className=\"min-w-64\" collisionAvoidance={{ side: 'none', align: 'shift' }}>\n <ComboboxInput showTrigger={false} placeholder={`Search ${columnDef.title.toLowerCase()}…`} />\n {selected.length > 0 && (\n <>\n <ComboboxSelectedChips>\n <ComboboxValue>\n {(items: CelColumnOption[]) => (\n <>\n {items.map(item => (\n <ComboboxChip key={item.value}>{item.label}</ComboboxChip>\n ))}\n </>\n )}\n </ComboboxValue>\n <ComboboxClearAll onClick={() => applySelection([])} />\n </ComboboxSelectedChips>\n <ComboboxSeparator />\n </>\n )}\n <ComboboxEmpty>No {columnDef.title.toLowerCase()} found.</ComboboxEmpty>\n <ComboboxList>\n {(item: CelColumnOption) => (\n <ComboboxItem key={item.value} value={item} className={cn(item.disabled && 'text-muted-foreground')}>\n {item.label}\n </ComboboxItem>\n )}\n </ComboboxList>\n {issues.length > 0 && (\n <p className=\"text-body-sm text-destructive\">{issues.map(issue => issue.message).join(' ')}</p>\n )}\n </ComboboxContent>\n </Combobox>\n );\n}\n\n// ── Radio pill (Combobox, single-select) ──────────────\n// Same primitive as the checkbox pill above, constrained to one selection by\n// omitting `multiple` — no chip strip (nothing to show but the one value,\n// already in the trigger), and a valid pick auto-commits (closes) like the\n// legacy RadioGroup did.\n\nfunction CelRadioComboboxPill({\n condition,\n columnDef,\n tree,\n onChange,\n controller,\n issues,\n onRemove,\n onRestrictedOptionSelect,\n container,\n}: {\n condition: CelFilterCondition;\n columnDef: CelColumnDefinition;\n tree: CelFilterBarProps['tree'];\n onChange: CelFilterBarProps['onChange'];\n controller: CelConditionEditorController;\n issues: CompileResult['issues'];\n onRemove: () => void;\n onRestrictedOptionSelect: CelFilterBarProps['onRestrictedOptionSelect'];\n container?: PortalContainer;\n}) {\n const options = sortBy(columnDef.options ?? [], o => o.label);\n const value = typeof condition.value === 'string' ? condition.value : '';\n const selected = options.find(option => option.value === value) ?? null;\n const allowedOperators = getAllowedOperators(columnDef);\n\n function updateOperator(operator: CelOperator) {\n onChange(replaceCondition(tree, condition.id, c => applyOperatorChange(c, operator, 'radio')));\n }\n\n function applySelection(option: CelColumnOption | null) {\n if (!option) return;\n if (option.disabled) {\n onRestrictedOptionSelect?.({ columnId: columnDef.id, value: option.value, label: option.label });\n return;\n }\n onChange(replaceCondition(tree, condition.id, c => ({ ...c, value: option.value })));\n if (option.operator) updateOperator(option.operator);\n controller.commit();\n }\n\n return (\n <Combobox\n items={options}\n itemToStringValue={(item: CelColumnOption) => item.label}\n value={selected}\n onValueChange={(next: CelColumnOption | null) => applySelection(next)}\n open={controller.popoverVisible}\n onOpenChange={(open: boolean) => {\n if (open) controller.beginEditing();\n else if (!controller.isDismissSuppressed()) controller.handlePopoverDismiss();\n }}\n >\n <ButtonGroup>\n <ButtonGroupText>{columnDef.title}</ButtonGroupText>\n <CelOperatorSegment\n columnTitle={columnDef.title}\n operator={condition.operator}\n allowedOperators={allowedOperators}\n hideOnSingleOperator={columnDef.hideOnSingleOperator}\n onChangeOperator={updateOperator}\n />\n {/* role=\"combobox\" doesn't pick up child text as its accessible name\n the way a plain button would — an explicit aria-label is required,\n not just a nicety. */}\n <ComboboxTrigger\n aria-label={`${columnDef.title} value`}\n render={<Button variant=\"outline\" className=\"gap-1 font-normal [&>svg:last-child]:size-(--icon-sm)\" />}\n >\n <span className={cn(issues.length > 0 && 'text-destructive')}>\n {formatConditionSummary(condition, columnDef)}\n </span>\n </ComboboxTrigger>\n <Button variant=\"outline\" size=\"icon\" aria-label={`Remove ${columnDef.title} filter`} onClick={onRemove}>\n <Icon name=\"xmark\" />\n </Button>\n </ButtonGroup>\n <ComboboxContent container={container} className=\"min-w-64\" collisionAvoidance={{ side: 'none', align: 'shift' }}>\n <ComboboxInput showTrigger={false} placeholder={`Search ${columnDef.title.toLowerCase()}…`} />\n <ComboboxEmpty>No {columnDef.title.toLowerCase()} found.</ComboboxEmpty>\n <ComboboxList>\n {(item: CelColumnOption) => (\n <ComboboxItem key={item.value} value={item} className={cn(item.disabled && 'text-muted-foreground')}>\n {item.label}\n </ComboboxItem>\n )}\n </ComboboxList>\n {issues.length > 0 && (\n <p className=\"text-body-sm text-destructive\">{issues.map(issue => issue.message).join(' ')}</p>\n )}\n </ComboboxContent>\n </Combobox>\n );\n}\n\n// ── Text value editor ─────────────────────────────────\n\nfunction CelTextValueEditor({\n condition,\n onChangeValue,\n onCommit,\n}: {\n condition: CelFilterCondition;\n onChangeValue: (value: string) => void;\n onCommit: () => void;\n}) {\n const value = typeof condition.value === 'string' ? condition.value : '';\n\n return (\n <Input\n autoFocus\n value={value}\n placeholder=\"Enter a value…\"\n onChange={e => onChangeValue(e.target.value)}\n onKeyDown={e => {\n if (e.key === 'Enter') onCommit();\n }}\n />\n );\n}\n\n// ── MultiText value editor ────────────────────────────\n\nfunction CelMultiTextValueEditor({\n condition,\n onChangeValue,\n}: {\n condition: CelFilterCondition;\n onChangeValue: (value: MultiTextCelValue) => void;\n}) {\n const value = readMultiTextCelValue(condition.value);\n const [draft, setDraft] = React.useState('');\n\n function addToken() {\n const token = draft.trim();\n if (!token || value.tokens.includes(token)) {\n setDraft('');\n return;\n }\n const nextTokens = [...value.tokens, token];\n // Write an explicit quantifier the moment it first becomes relevant\n // (2nd token). CelQuantifierSegment's Select displays `quantifier ?? 'any'`\n // as its value, so if the user's first pick were \"any of\" — the same as\n // that visual default — Radix would see no change and never fire\n // onValueChange, leaving quantifier stuck undefined and the\n // missing_quantifier issue stuck showing despite the pill saying \"any of\".\n const quantifier = nextTokens.length > 1 ? (value.quantifier ?? 'any') : value.quantifier;\n onChangeValue({ ...value, tokens: nextTokens, quantifier });\n setDraft('');\n }\n\n function removeToken(token: string) {\n onChangeValue({ ...value, tokens: value.tokens.filter(t => t !== token) });\n }\n\n return (\n <div className=\"flex flex-col gap-2\">\n {value.tokens.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {value.tokens.map(token => (\n <Badge key={token} variant=\"secondary\" className=\"gap-1\">\n {token}\n <button\n type=\"button\"\n aria-label={`Remove ${token}`}\n onClick={() => removeToken(token)}\n className=\"cursor-pointer\"\n >\n <Icon name=\"xmark\" size=\"xs\" />\n </button>\n </Badge>\n ))}\n </div>\n )}\n <Input\n autoFocus\n value={draft}\n placeholder=\"Type a value, press Enter…\"\n onChange={e => setDraft(e.target.value)}\n onKeyDown={e => {\n if (e.key === 'Enter') {\n e.preventDefault();\n addToken();\n } else if (e.key === 'Backspace' && draft === '' && value.tokens.length > 0) {\n removeToken(value.tokens[value.tokens.length - 1]);\n }\n }}\n />\n </div>\n );\n}\n\n// ── KeyValue value editor ─────────────────────────────\n\nfunction CelKeyValueValueEditor({\n condition,\n onChangeValue,\n onCommit,\n}: {\n condition: CelFilterCondition;\n onChangeValue: (value: MapKeyCelValue) => void;\n onCommit: () => void;\n}) {\n const value = readMapKeyCelValue(condition.value);\n const needsValue = condition.operator === 'has_value' || condition.operator === 'does_not_have_value';\n\n return (\n <div className=\"flex flex-col gap-2\">\n <InputGroup>\n <InputGroupAddon>\n <InputGroupText>Key</InputGroupText>\n </InputGroupAddon>\n <InputGroupInput\n autoFocus\n value={value.key}\n onChange={e => onChangeValue({ ...value, key: e.target.value })}\n onKeyDown={e => {\n if (e.key === 'Enter' && !needsValue) onCommit();\n }}\n />\n </InputGroup>\n {needsValue && (\n <InputGroup>\n <InputGroupAddon>\n <InputGroupText>Value</InputGroupText>\n </InputGroupAddon>\n <InputGroupInput\n value={value.value ?? ''}\n onChange={e => onChangeValue({ ...value, value: e.target.value })}\n onKeyDown={e => {\n if (e.key === 'Enter') onCommit();\n }}\n />\n </InputGroup>\n )}\n </div>\n );\n}\n\n// ── Date value editor ──────────────────────────────────\n\nfunction CelDateValueEditor({\n condition,\n onChangeValue,\n}: {\n condition: CelFilterCondition;\n onChangeValue: (value: DateCelValue) => void;\n}) {\n const value = readDateCelValue(condition.value);\n const operator = condition.operator;\n const relativeCapable = isDateRelativeOperator(operator);\n const isRange = isDateRangeOperator(operator);\n const showTime = !isDateWindowOperator(operator) && !isRange;\n const isRelative = isRelativeDateCelValue(value);\n\n function pickInstant(date: Date | undefined) {\n if (!date) return;\n const boundary = dateBoundaryForOperator(operator);\n const instant = formatCalendarDateUtc(date, showTime ? boundary : 'start');\n onChangeValue({ instant });\n }\n\n function pickRange(range: DateRange | undefined) {\n if (!range?.from) return;\n const start = calendarDayStartInstant(formatCalendarDateUtc(range.from, 'start'));\n const end = range.to ? formatCalendarDateUtc(range.to, 'end') : formatCalendarDateUtc(range.from, 'end');\n onChangeValue({ range: { start, end } });\n }\n\n function pickTime(timeOfDay: string) {\n if (!value.instant) return;\n onChangeValue({ instant: withTimeOfDay(value.instant, timeOfDay), hasTime: true });\n }\n\n return (\n <div className=\"flex flex-col gap-2\">\n {/* No wrapping border here — PopoverContent already supplies the pill's\n single outer border/ring. A second border on this row would double\n up against it. `border-r` on the sidebar alone gives the divider. */}\n <div className=\"flex\">\n {relativeCapable && (\n <div className=\"flex flex-col gap-1 border-r pr-2\">\n <p className=\"text-body-sm text-muted-foreground px-2 font-medium\">Quick select</p>\n {RELATIVE_DURATION_PRESET_VALUES.map(preset => (\n <Button\n key={preset}\n type=\"button\"\n variant={isRelative && value.preset === preset ? 'secondary' : 'ghost'}\n size=\"sm\"\n className=\"justify-start\"\n onClick={() => onChangeValue({ preset })}\n >\n {RELATIVE_PRESET_LABELS[preset]}\n </Button>\n ))}\n </div>\n )}\n {isRange ? (\n <Calendar\n mode=\"range\"\n selected={\n value.range\n ? { from: parseCalendarDate(value.range.start), to: parseCalendarDate(value.range.end) }\n : undefined\n }\n onSelect={pickRange}\n />\n ) : (\n <Calendar\n mode=\"single\"\n selected={isRelative ? undefined : parseCalendarDate(value.instant)}\n onSelect={pickInstant}\n />\n )}\n </div>\n {showTime && !isRelative && (\n <div className=\"flex w-full items-center gap-2\">\n <Label htmlFor=\"cel-date-time\" className=\"text-body-sm text-muted-foreground shrink-0\">\n Time (UTC)\n </Label>\n <Input\n id=\"cel-date-time\"\n type=\"time\"\n className=\"w-full\"\n value={readTimeOfDay(value.instant)}\n onChange={e => pickTime(e.target.value)}\n disabled={!value.instant}\n />\n </div>\n )}\n </div>\n );\n}\n\nexport { CelFilterBar };\n","import { useCallback, useRef, useState } from 'react';\n\nimport { ADD_FILTER_POPOVER_SUPPRESS_MS } from '@/lib/cel-filter/constants';\nimport type { PillActiveSurface } from '@/lib/cel-filter/types';\n\nexport type CelConditionEditorController = {\n isDraft: boolean;\n activeSurface: PillActiveSurface | null;\n popoverVisible: boolean;\n isDismissSuppressed: () => boolean;\n\n beginEditing: () => void;\n openSurface: (surface: PillActiveSurface) => void;\n closeSurface: () => void;\n commit: () => void;\n handlePopoverDismiss: () => void;\n toggleSurface: (surface: PillActiveSurface) => void;\n};\n\nexport type UseCelFilterEditorStateResult = {\n editingConditionId: string | null;\n activeSurface: PillActiveSurface | null;\n committedConditionIds: Set<string>;\n getController: (conditionId: string) => CelConditionEditorController;\n beginEditing: (id: string, surface?: PillActiveSurface) => void;\n suppressDismissFor: (id: string, ms?: number) => void;\n removeCondition: (id: string) => void;\n clearSuppress: () => void;\n};\n\n/**\n * Single source of truth for CEL filter draft/commit, active pill segment,\n * and Radix dismiss-suppression (post-add guard + segment switches).\n */\nexport function useCelFilterEditorState(initialCommittedIds: string[] = []): UseCelFilterEditorStateResult {\n const [editingConditionId, setEditingConditionId] = useState<string | null>(null);\n const [committedConditionIds, setCommittedConditionIds] = useState<Set<string>>(() => new Set(initialCommittedIds));\n const [activeSurface, setActiveSurface] = useState<PillActiveSurface | null>(null);\n\n const suppressCloseUntilRef = useRef<{ id: string; until: number } | null>(null);\n const segmentSwitchRef = useRef(false);\n\n const isDismissSuppressed = useCallback((id: string) => {\n const entry = suppressCloseUntilRef.current;\n return entry !== null && entry.id === id && Date.now() < entry.until;\n }, []);\n\n const commitCondition = useCallback((id: string) => {\n setCommittedConditionIds(prev => {\n if (prev.has(id)) {\n return prev;\n }\n const next = new Set(prev);\n next.add(id);\n return next;\n });\n setEditingConditionId(current => (current === id ? null : current));\n setActiveSurface(null);\n segmentSwitchRef.current = false;\n }, []);\n\n const beginEditing = useCallback((id: string, surface: PillActiveSurface = 'value') => {\n setEditingConditionId(id);\n setActiveSurface(surface);\n }, []);\n\n const openSurface = useCallback(\n (id: string, surface: PillActiveSurface) => {\n if (editingConditionId !== id) {\n beginEditing(id, surface);\n return;\n }\n setActiveSurface(surface);\n },\n [beginEditing, editingConditionId],\n );\n\n const closeSurface = useCallback(\n (id: string) => {\n if (editingConditionId === id) {\n setActiveSurface(null);\n }\n },\n [editingConditionId],\n );\n\n const handlePopoverDismiss = useCallback(\n (id: string) => {\n if (segmentSwitchRef.current) {\n segmentSwitchRef.current = false;\n return;\n }\n if (isDismissSuppressed(id)) {\n return;\n }\n suppressCloseUntilRef.current = null;\n commitCondition(id);\n },\n [commitCondition, isDismissSuppressed],\n );\n\n const toggleSurface = useCallback(\n (id: string, surface: PillActiveSurface) => {\n const isDraft = editingConditionId === id;\n const popoverVisible = isDraft && activeSurface !== null;\n\n if (isDraft && activeSurface === surface && popoverVisible) {\n closeSurface(id);\n return;\n }\n if (popoverVisible && activeSurface !== surface) {\n segmentSwitchRef.current = true;\n }\n openSurface(id, surface);\n },\n [activeSurface, closeSurface, editingConditionId, openSurface],\n );\n\n const suppressDismissFor = useCallback((id: string, ms = ADD_FILTER_POPOVER_SUPPRESS_MS) => {\n suppressCloseUntilRef.current = {\n id,\n until: Date.now() + ms,\n };\n }, []);\n\n const removeCondition = useCallback(\n (id: string) => {\n if (suppressCloseUntilRef.current?.id === id) {\n suppressCloseUntilRef.current = null;\n }\n setCommittedConditionIds(prev => {\n if (!prev.has(id)) {\n return prev;\n }\n const next = new Set(prev);\n next.delete(id);\n return next;\n });\n setEditingConditionId(current => (current === id ? null : current));\n if (editingConditionId === id) {\n setActiveSurface(null);\n segmentSwitchRef.current = false;\n }\n },\n [editingConditionId],\n );\n\n const clearSuppress = useCallback(() => {\n suppressCloseUntilRef.current = null;\n }, []);\n\n const getController = useCallback(\n (conditionId: string): CelConditionEditorController => {\n const isDraft = editingConditionId === conditionId;\n const surface = isDraft ? activeSurface : null;\n\n return {\n isDraft,\n activeSurface: surface,\n popoverVisible: isDraft && activeSurface !== null,\n isDismissSuppressed: () => isDismissSuppressed(conditionId),\n beginEditing: () => beginEditing(conditionId),\n openSurface: s => openSurface(conditionId, s),\n closeSurface: () => closeSurface(conditionId),\n commit: () => {\n suppressCloseUntilRef.current = null;\n commitCondition(conditionId);\n },\n handlePopoverDismiss: () => handlePopoverDismiss(conditionId),\n toggleSurface: s => toggleSurface(conditionId, s),\n };\n },\n [\n activeSurface,\n beginEditing,\n closeSurface,\n commitCondition,\n editingConditionId,\n handlePopoverDismiss,\n isDismissSuppressed,\n openSurface,\n toggleSurface,\n ],\n );\n\n return {\n editingConditionId,\n activeSurface,\n committedConditionIds,\n getController,\n beginEditing,\n suppressDismissFor,\n removeCondition,\n clearSuppress,\n };\n}\n","/**\n * Shared limits and defaults for the CEL filter builder. Values mirror the API\n * constraints (`maxNestingDepth = 50`, `maxRegexLen = 1000`).\n */\nimport type { RelativeDurationPreset } from './types';\n\n/**\n * Trusted relative date presets emitted as fixed `duration(...)` literals in\n * compiled CEL. Hours only — `duration()` rejects a `d` unit.\n */\nexport const RELATIVE_DURATION_PRESET_VALUES = [\n '24h',\n '168h',\n '720h',\n] as const satisfies readonly RelativeDurationPreset[];\n\nexport const RELATIVE_DURATION_PRESETS = new Set<string>(RELATIVE_DURATION_PRESET_VALUES);\n\nexport function isRelativeDurationPreset(value: string): value is RelativeDurationPreset {\n return RELATIVE_DURATION_PRESETS.has(value);\n}\n\n/** API recursion depth limit for nested parentheses. v1 UI is flat; the compiler enforces this defensively. */\nexport const MAX_NESTING_DEPTH = 50;\n\n/** Maximum length of a `matches` regex pattern accepted by the API. */\nexport const MAX_REGEX_LEN = 1000;\n\n/** Debounce for inline free-text (regex) validation inside an open popover. */\nexport const CEL_VALIDATION_DEBOUNCE_MS = 300;\n\n/** Default quantifier when a multiText condition has more than one token. */\nexport const DEFAULT_MULTI_TEXT_QUANTIFIER = 'any' as const;\n\n/**\n * After adding a filter from the dropdown, ignore outside-dismiss on the new\n * pill popover for this long. Covers the menu closing plus immediate pointer\n * movement that Radix treats as an outside interaction.\n */\nexport const ADD_FILTER_POPOVER_SUPPRESS_MS = 500;\n\n/** Keys handled by searchable CEL dropdown listboxes; others stop propagation from the search input. */\nexport const CEL_DROPDOWN_NAV_KEYS = [\n 'ArrowUp',\n 'ArrowDown',\n 'ArrowLeft',\n 'ArrowRight',\n 'Enter',\n 'Escape',\n 'Tab',\n] as const;\n","/**\n * Instant helpers for the CEL date filter.\n *\n * Stored values are RFC3339 UTC strings, and everything here manipulates them as\n * text rather than through `Date`, so a filter can never drift into the viewer's\n * local timezone. Tables render timestamps in UTC, so a UTC filter is what\n * agrees with the times shown in the table.\n */\n\n/** Which end of a day/minute an instant represents. */\nexport type DateBoundary = 'start' | 'end';\n\n/** How much of the instant the user has committed to: a calendar day, or a wall-clock minute. */\nexport type DateInstantGranularity = 'day' | 'minute';\n\n/** Time an `input[type=\"time\"]` shows for a boundary the user has not edited. */\nexport const BOUNDARY_TIME_OF_DAY: Record<DateBoundary, string> = {\n start: '00:00',\n end: '23:59',\n};\n\nconst CALENDAR_DAY_PATTERN = /^(\\d{4}-\\d{2}-\\d{2})/;\nconst MINUTE_PATTERN = /^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2})/;\nconst TIME_OF_DAY_PATTERN = /^\\d{4}-\\d{2}-\\d{2}T(\\d{2}:\\d{2})/;\n\nexport function calendarDayStartInstant(instant: string): string {\n const match = CALENDAR_DAY_PATTERN.exec(instant);\n return match ? `${match[1]}T00:00:00.000Z` : instant;\n}\n\n/**\n * Derives the inclusive upper bound of a stored instant. An upper bound covers\n * the whole unit the user selected: a day runs through 23:59:59.999, a minute\n * through :59.999 — the same rule, one unit finer.\n */\nexport function inclusiveEndInstant(instant: string, granularity: DateInstantGranularity): string {\n if (granularity === 'minute') {\n const minuteMatch = MINUTE_PATTERN.exec(instant);\n return minuteMatch ? `${minuteMatch[1]}:59.999Z` : instant;\n }\n const match = CALENDAR_DAY_PATTERN.exec(instant);\n return match ? `${match[1]}T23:59:59.999Z` : instant;\n}\n\n/** Derives inclusive end-of-day RFC3339 from a stored start instant. */\nexport function calendarDayEndInstant(startInstant: string): string {\n return inclusiveEndInstant(startInstant, 'day');\n}\n\nexport function startInstantFromEndOfDay(endInstant: string): string {\n const match = CALENDAR_DAY_PATTERN.exec(endInstant);\n return match ? `${match[1]}T00:00:00Z` : endInstant;\n}\n\n/** Strips the `:59.999` an inclusive minute bound was expanded with. */\nexport function startInstantFromEndOfMinute(endInstant: string): string {\n const match = MINUTE_PATTERN.exec(endInstant);\n return match ? `${match[1]}:00.000Z` : endInstant;\n}\n\nexport function isEndOfDayTimestamp(instant: string): boolean {\n return /T23:59:59(\\.\\d+)?Z$/.test(instant);\n}\n\nexport function isStartOfDayTimestamp(instant: string): boolean {\n return /T00:00:00(\\.0+)?Z$/.test(instant);\n}\n\n/**\n * True for an instant expanded to the end of its minute. End-of-day is also\n * end-of-minute, so callers that distinguish the two must test for day first.\n */\nexport function isEndOfMinuteTimestamp(instant: string): boolean {\n return /T\\d{2}:\\d{2}:59(\\.\\d+)?Z$/.test(instant);\n}\n\n/**\n * True when the date portion names a day that exists. `Date` rolls impossible\n * days over silently — Feb 31 becomes Mar 3 rather than failing — so a\n * round-trip through UTC is what separates a real day from a rolled-over one.\n */\nexport function isRealCalendarDay(instant: string): boolean {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(instant);\n if (!match) {\n return false;\n }\n const [year, month, day] = [Number(match[1]), Number(match[2]), Number(match[3])];\n const date = new Date(Date.UTC(year, month - 1, day));\n return date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day;\n}\n\n/** Reads the `HH:mm` an `input[type=\"time\"]` displays for a stored instant. */\nexport function readTimeOfDay(instant: string | undefined): string {\n if (!instant) {\n return '';\n }\n const match = TIME_OF_DAY_PATTERN.exec(instant);\n return match ? match[1] : '';\n}\n\n/** Replaces the time portion of an instant. Seconds are zeroed — the input is minute-granular. */\nexport function withTimeOfDay(instant: string, timeOfDay: string): string {\n const day = CALENDAR_DAY_PATTERN.exec(instant);\n const time = /^(\\d{2}):(\\d{2})/.exec(timeOfDay);\n if (!day || !time) {\n return instant;\n }\n return `${day[1]}T${time[1]}:${time[2]}:00.000Z`;\n}\n\n/**\n * Stamps a picked calendar day as a UTC instant. The picker hands back a local\n * `Date` whose Y/M/D is the day that was clicked; that day is stored as the\n * matching UTC day so the filter lines up with the UTC timestamps in the table.\n */\nexport function formatCalendarDateUtc(date: Date, boundary: DateBoundary): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const time = boundary === 'end' ? 'T23:59:59.999Z' : 'T00:00:00.000Z';\n return `${year}-${month}-${day}${time}`;\n}\n\n/** Parses a stored RFC3339 string back into a local Date carrying the calendar day. */\nexport function parseCalendarDate(value: string | undefined): Date | undefined {\n if (!value) {\n return undefined;\n }\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(value);\n if (!match) {\n return undefined;\n }\n return new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3]));\n}\n\n/**\n * Locale date for display, plus the UTC time when the instant carries a\n * user-picked one. `locale` defaults to the runtime's own locale (matching\n * plain `toLocaleDateString()`) — callers rendered during SSR should pass a\n * fixed locale explicitly (see `cel-filter-bar.tsx`'s `useMounted()` gating)\n * so the server-rendered/first-paint value doesn't hydration-mismatch against\n * the viewer's actual browser locale.\n */\nexport function formatInstantLabel(\n instant: string | undefined,\n { withTime = false, locale }: { withTime?: boolean; locale?: string } = {},\n): string {\n const date = parseCalendarDate(instant);\n if (!date) {\n return '';\n }\n const dateLabel = date.toLocaleDateString(locale);\n const timeOfDay = withTime ? readTimeOfDay(instant) : '';\n return timeOfDay ? `${dateLabel} ${timeOfDay} UTC` : dateLabel;\n}\n","/** Stable operator ids used in code and tests. UI labels come from `getOperatorLabel`. */\nexport type CelOperator =\n | 'is'\n | 'is_not'\n | 'contains'\n | 'does_not_contain'\n | 'starts_with'\n | 'ends_with'\n | 'matches'\n | 'is_before'\n | 'is_after'\n | 'is_on_or_before'\n | 'is_on_or_after'\n | 'is_between'\n | 'is_not_between'\n | 'key_exists'\n | 'key_does_not_exist'\n | 'has_value'\n | 'does_not_have_value';\n\nexport type CelFilterType = 'checkbox' | 'radio' | 'text' | 'multiText' | 'date' | 'keyValue' | 'static';\n\n/** When a valid compiled expression may be emitted to consumers (API, URL, etc.). */\nexport type CelEmitOn = 'change' | 'commit';\n\n/**\n * Resolved shape used by the compiler / dispatcher to pick a value variant and\n * operator set. Columns map to their `filterType`; map fields resolve to `map`.\n */\nexport type CelFilterShape = CelFilterType | 'map';\n\nexport type CelColumnOption = {\n /** Human-readable text shown in the UI and collapsed pill display. Never compiled into CEL. */\n label: string;\n /** Canonical CEL literal stored on the condition and emitted in compiled CEL. */\n value: string;\n /** When set, selecting this option also sets the condition operator (e.g. `'is_not'` for a negated choice). */\n operator?: CelOperator;\n /** When true, the option cannot be toggled; hosts may handle the click via `onRestrictedOptionSelect`. */\n disabled?: boolean;\n};\n\n/** Payload for clicks on disabled checkbox/radio options. */\nexport type CelRestrictedOptionSelectPayload = {\n columnId: string;\n value: string;\n label: string;\n};\n\nexport type CelColumnDefinition = {\n /** Must match the API column id when targeting server-side resources. */\n id: string;\n /** Display name in the add-filter menu. */\n title: string;\n /**\n * Section heading this column is listed under in the add-filter menu. Sections appear in the\n * order each group name first occurs in `columns`; columns without a group are listed last\n * under no heading. Omit on every column to get a single flat alphabetical list.\n *\n * Group names are searchable: a phrase matching one keeps that entire section, on top of any\n * columns matched by title.\n */\n group?: string;\n /** Lowercase natural plural for consolidated multi-value pill copy (e.g. \"2 control planes\"). */\n pluralTitle: string;\n filterType: CelFilterType;\n /** Enum columns (checkbox / radio); static options only in v1. */\n options?: CelColumnOption[];\n /** Optional override; defaults from `filterType`. */\n allowedOperators?: CelOperator[];\n /** When true, hides the operator UI when only one operator is allowed. Defaults to `false`. */\n hideOnSingleOperator?: boolean;\n /** Pre-fill value when the condition is first added. Skips the initial \"pick a value\" step. */\n defaultValue?: CelConditionValue;\n /** When a valid compiled expression may be emitted. Defaults by `filterType`. */\n emitOn?: CelEmitOn;\n};\n\n/** Host-provided schema describing which columns are filterable for a given filter bar. */\nexport type CelFilterSchema = {\n columns: CelColumnDefinition[];\n};\n\n// --- Value shapes -----------------------------------------------------------\n\nexport type CheckboxCelValue = string[];\n\nexport type RadioCelValue = string;\n\nexport type TextCelValue = string;\n\nexport type MultiTextCelValue = {\n tokens: string[];\n /** Required when `tokens.length > 1`; defaults to `any` in the UI when omitted. */\n quantifier?: 'any' | 'all';\n};\n\n/** Trusted preset durations emitted as fixed literals in compiled CEL. */\nexport type RelativeDurationPreset = '24h' | '168h' | '720h';\n\nexport type DateCelValue = {\n /** RFC3339 UTC; required for single-point comparators. Mutually exclusive with `preset`. */\n instant?: string;\n /** Required for the range operators (`is_between` / `is_not_between`). Mutually exclusive with `preset`. */\n range?: {\n start: string;\n end: string;\n };\n /** Relative duration preset; mutually exclusive with `instant` / `range`. */\n preset?: RelativeDurationPreset;\n /**\n * True once the user edits a boundary time. While false the operator's default\n * day boundary applies, so an untouched condition compiles exactly as it did\n * before times were selectable. Never set without `instant` / `range` — the\n * `isDateCelValue` guard keys off those fields. Never compiled into CEL; a\n * future parser would need to re-derive it from the instants in the expression.\n */\n hasTime?: boolean;\n};\n\nexport type MapKeyCelValue = {\n key: string;\n /** Required when operator is `has_value` / `does_not_have_value`. */\n value?: string;\n};\n\n/**\n * Union of all condition value shapes. The active variant is determined by the\n * condition's `columnId` + schema `filterType`, not a discriminant on the value.\n */\nexport type CelConditionValue =\n CheckboxCelValue | RadioCelValue | TextCelValue | MultiTextCelValue | DateCelValue | MapKeyCelValue;\n\n// --- Tree nodes -------------------------------------------------------------\n\n/**\n * v1 always `and`; the shape is forward-compatible with `or` and nesting.\n * See `CelFilterGroup.children`, kept recursive so a future nested/OR-group UI\n * is additive rather than a breaking type change.\n */\nexport type CelCombinator = 'and';\n\nexport type CelFilterGroup = {\n id: string;\n type: 'group';\n combinator: CelCombinator;\n /** Root group is `0`. */\n depth: number;\n children: CelFilterNode[];\n};\n\nexport type CelFilterCondition = {\n id: string;\n type: 'condition';\n columnId: string;\n operator: CelOperator;\n /** Undefined on a newly added row until the user edits. */\n value?: CelConditionValue;\n};\n\nexport type CelFilterNode = CelFilterGroup | CelFilterCondition;\n\nexport type CelFilterTree = {\n root: CelFilterGroup;\n};\n\n// --- Validation -------------------------------------------------------------\n\n/** Closed union — `validateCondition` and `compileCelFilterTree` emit only these codes. */\nexport type ValidationIssueCode =\n // incomplete\n | 'missing_column'\n | 'missing_value'\n | 'missing_key'\n | 'missing_tokens'\n | 'missing_quantifier'\n | 'missing_instant'\n | 'missing_range'\n | 'missing_duration'\n // invalid\n | 'unknown_column'\n | 'illegal_operator'\n | 'invalid_date_mode'\n | 'regex_too_long'\n | 'invalid_timestamp'\n | 'invalid_date_range'\n | 'nesting_depth_exceeded';\n\nexport type ValidationSeverity = 'incomplete' | 'invalid';\n\nexport type ValidationIssue = {\n code: ValidationIssueCode;\n message: string;\n severity: ValidationSeverity;\n nodeId: string;\n nodeType: 'condition' | 'group';\n /** Sub-target within the condition (e.g. `value`, `key`, `instant`). */\n field?: string;\n};\n\nexport type CompileStatus = 'valid' | 'incomplete' | 'invalid';\n\nexport type CompileResult = {\n status: CompileStatus;\n /** Present when `status === 'valid'` (may be `\"\"`). */\n expression?: string;\n issues: ValidationIssue[];\n /** True iff the raw compile status is `valid`; the API / parent emission gate. */\n isEmitReady: boolean;\n};\n\n// --- Validation meta (draft / commit tracking) ------------------------------\n\nexport type CelValidationMeta = {\n editingConditionId: string | null;\n committedConditionIds: Set<string>;\n};\n\n/** Which pill sub-surface is open: operator picker, multiText quantifier, or the value editor. */\nexport type PillActiveSurface = 'operator' | 'quantifier' | 'value';\n\n// --- Public builder API -----------------------------------------------------\n\nexport type CelFilterBarProps = {\n tree: CelFilterTree;\n onChange: (tree: CelFilterTree) => void;\n schema: CelFilterSchema;\n onCompileResultChange?: (result: CompileResult) => void;\n /** Invoked when the user clicks a disabled option (instead of toggling the filter value). */\n onRestrictedOptionSelect?: (payload: CelRestrictedOptionSelectPayload) => void;\n /** Default `false`. */\n showClearButton?: boolean;\n className?: string;\n};\n\n// --- Type guards ------------------------------------------------------------\n\nexport const isCelFilterGroup = (node: CelFilterNode): node is CelFilterGroup => node.type === 'group';\n\nexport const isCelFilterCondition = (node: CelFilterNode): node is CelFilterCondition => node.type === 'condition';\n\n/** Checkbox values are arrays of option value strings. */\nexport const isCheckboxCelValue = (value: unknown): value is CheckboxCelValue =>\n Array.isArray(value) && value.every(item => typeof item === 'string');\n\n/** Radio / text values are bare strings. */\nexport const isStringCelValue = (value: unknown): value is string => typeof value === 'string';\n\nexport const isMultiTextCelValue = (value: unknown): value is MultiTextCelValue =>\n typeof value === 'object' && value !== null && 'tokens' in value;\n\nexport const isDateCelValue = (value: unknown): value is DateCelValue => {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n if ('tokens' in value || 'key' in value) {\n return false;\n }\n return 'preset' in value || 'instant' in value || 'range' in value || Object.keys(value).length === 0;\n};\n\nexport const isMapKeyCelValue = (value: unknown): value is MapKeyCelValue =>\n typeof value === 'object' && value !== null && 'key' in value;\n","import {\n type DateCelValue,\n isDateCelValue,\n isMapKeyCelValue,\n isMultiTextCelValue,\n type MapKeyCelValue,\n type MultiTextCelValue,\n} from './types';\n\n/** Relative when a preset is set; preset and absolute fields are mutually exclusive. */\nexport function isRelativeDateCelValue(value: DateCelValue): boolean {\n return value.preset != null;\n}\n\nexport function readDateCelValue(value: unknown): DateCelValue {\n return isDateCelValue(value) ? value : {};\n}\n\nexport function readMapKeyCelValue(value: unknown): MapKeyCelValue {\n return isMapKeyCelValue(value) ? value : { key: '' };\n}\n\nexport function readMultiTextCelValue(value: unknown): MultiTextCelValue {\n return isMultiTextCelValue(value) ? value : { tokens: [] };\n}\n","/**\n * Escapes a user-provided string literal for safe embedding inside a CEL\n * double-quoted string. Callers wrap the result in `\"...\"` at the use site\n * (e.g. `column == \"${escapeCelString(value)}\"`).\n *\n * CEL generated output uses double-quoted strings only, so single quotes are\n * left untouched.\n */\nexport function escapeCelString(input: string): string {\n let out = '';\n\n for (const char of input) {\n switch (char) {\n case '\\\\':\n out += '\\\\\\\\';\n break;\n case '\"':\n out += '\\\\\"';\n break;\n case '\\n':\n out += '\\\\n';\n break;\n case '\\r':\n out += '\\\\r';\n break;\n case '\\t':\n out += '\\\\t';\n break;\n case '\\f':\n out += '\\\\f';\n break;\n case '\\v':\n out += '\\\\v';\n break;\n case '\\b':\n out += '\\\\b';\n break;\n case '\\0':\n out += '\\\\0';\n break;\n default:\n out += char;\n }\n }\n\n return out;\n}\n\n/** Convenience helper that escapes and wraps a value in double quotes. */\nexport function celStringLiteral(input: string): string {\n return `\"${escapeCelString(input)}\"`;\n}\n","/**\n * Operator metadata and CEL fragment generation.\n *\n * This is the single place that knows how `condition.operator` + value map to CEL\n * output. UI components never hand-write CEL — they read/write tree state and the\n * compiler walks it through here.\n */\nimport { type DateBoundary, inclusiveEndInstant } from '../date-utils';\nimport {\n type CelColumnDefinition,\n type CelFilterCondition,\n type CelFilterSchema,\n type CelFilterShape,\n type CelFilterType,\n type CelOperator,\n type DateCelValue,\n isDateCelValue,\n isMapKeyCelValue,\n type MapKeyCelValue,\n type MultiTextCelValue,\n} from '../types';\nimport { isRelativeDateCelValue } from '../value-utils';\nimport { celStringLiteral } from './escape-cel-string';\n\n/** Schema column ids that collide with CEL reserved words (in the CEL library leveraged), mapped to safe CEL identifiers. */\nconst RESERVED_COLUMN_CEL_IDENTIFIERS: Record<string, string> = {\n namespace: '__namespace__',\n};\n\nconst CEL_IDENTIFIER_TO_COLUMN_ID = Object.fromEntries(\n Object.entries(RESERVED_COLUMN_CEL_IDENTIFIERS).map(([columnId, celIdentifier]) => [celIdentifier, columnId]),\n);\n\nconst RESERVED_FIELD_OPERATOR_PATTERN = '(?=\\\\s*(?:in\\\\b|==|!=|<=|>=|<|>|\\\\.))';\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n// --- Allowed operator sets --------------------------------------------------\n\nconst ENUM_OPERATORS: CelOperator[] = ['is', 'is_not'];\nconst TEXT_OPERATORS: CelOperator[] = [\n 'is',\n 'is_not',\n 'contains',\n 'does_not_contain',\n 'starts_with',\n 'ends_with',\n 'matches',\n];\nconst DATE_OPERATORS: CelOperator[] = [\n 'is',\n 'is_not',\n 'is_before',\n 'is_after',\n 'is_on_or_before',\n 'is_on_or_after',\n 'is_between',\n 'is_not_between',\n];\nconst MAP_OPERATORS: CelOperator[] = ['key_exists', 'key_does_not_exist', 'has_value', 'does_not_have_value'];\n\n/** Date comparators legal with a relative preset. */\nconst DATE_RELATIVE_OPERATORS: CelOperator[] = ['is_before', 'is_after', 'is_on_or_before', 'is_on_or_after'];\n\n/** Date operators that span a whole calendar day rather than compare against one instant. */\nconst DATE_WINDOW_OPERATORS: CelOperator[] = ['is', 'is_not'];\n\n/** Date operators that take a start/end range instead of a single instant. */\nconst DATE_RANGE_OPERATORS: CelOperator[] = ['is_between', 'is_not_between'];\n\n/**\n * Comparators whose bound sits at the end of the selected day/minute: \"on or\n * before Jul 23\" runs through 23:59:59.999, and \"after Jul 23\" starts once that\n * same instant has passed.\n */\nconst DATE_END_BOUNDARY_OPERATORS: CelOperator[] = ['is_on_or_before', 'is_after'];\n\nconst MAP_VALUE_OPERATORS: CelOperator[] = ['has_value', 'does_not_have_value'];\n\n/** Returns the operators allowed for a resolved filter shape. */\nexport function getAllowedOperatorsForShape(shape: CelFilterShape): CelOperator[] {\n switch (shape) {\n case 'checkbox':\n case 'radio':\n case 'static':\n return ENUM_OPERATORS;\n case 'text':\n case 'multiText':\n return TEXT_OPERATORS;\n case 'date':\n return DATE_OPERATORS;\n case 'map':\n return MAP_OPERATORS;\n default:\n return [];\n }\n}\n\n/**\n * Returns the operators allowed for a column. `allowedOperators` on a column\n * definition overrides the default set derived from its filter type.\n */\nexport function getAllowedOperators(columnDef?: CelColumnDefinition): CelOperator[] {\n if (!columnDef) {\n return [];\n }\n if (columnDef.allowedOperators) {\n return columnDef.allowedOperators;\n }\n const shape = columnDef.filterType === 'keyValue' ? 'map' : columnDef.filterType;\n return getAllowedOperatorsForShape(shape);\n}\n\nexport function isDateRelativeOperator(operator: CelOperator): boolean {\n return DATE_RELATIVE_OPERATORS.includes(operator);\n}\n\n/** True for the date operators that match a whole calendar day and so take no time. */\nexport function isDateWindowOperator(operator: CelOperator): boolean {\n return DATE_WINDOW_OPERATORS.includes(operator);\n}\n\n/** True for the date operators whose value is a `range` rather than an `instant`. */\nexport function isDateRangeOperator(operator: CelOperator): boolean {\n return DATE_RANGE_OPERATORS.includes(operator);\n}\n\n/**\n * Which day boundary a date comparator compares against, and therefore the time\n * its input prefills with until the user edits it.\n */\nexport function dateBoundaryForOperator(operator: CelOperator): DateBoundary {\n return DATE_END_BOUNDARY_OPERATORS.includes(operator) ? 'end' : 'start';\n}\n\n// --- Schema resolution helpers ---------------------------------------------\n\nexport function resolveColumnDefinition(\n condition: Pick<CelFilterCondition, 'columnId'>,\n schema: CelFilterSchema,\n): CelColumnDefinition | undefined {\n if (!condition.columnId) {\n return undefined;\n }\n return schema.columns.find(column => column.id === condition.columnId);\n}\n\n/** Resolves the value/operator shape for a condition, or `undefined` for an unknown column. */\nexport function resolveFilterShape(\n condition: Pick<CelFilterCondition, 'columnId' | 'value'>,\n schema: CelFilterSchema,\n): CelFilterShape | undefined {\n const columnDef = resolveColumnDefinition(condition, schema);\n if (!columnDef) {\n return undefined;\n }\n if (columnDef.filterType === 'keyValue') {\n return 'map';\n }\n if (columnDef.filterType === 'static') {\n return Array.isArray(condition.value) ? 'checkbox' : 'radio';\n }\n return columnDef.filterType;\n}\n\n// --- Operator labels --------------------------------------------------------\n\nconst OPERATOR_LABELS: Record<CelOperator, string> = {\n is: 'is',\n is_not: 'is not',\n contains: 'contains',\n does_not_contain: 'does not contain',\n starts_with: 'starts with',\n ends_with: 'ends with',\n matches: 'matches',\n is_before: 'is before',\n is_after: 'is after',\n is_on_or_before: 'is on or before',\n is_on_or_after: 'is on or after',\n is_between: 'is between',\n is_not_between: 'is not between',\n key_exists: 'key exists',\n key_does_not_exist: 'key does not exist',\n has_value: 'has value',\n does_not_have_value: 'does not have value',\n};\n\nexport function getOperatorLabel(operator: CelOperator): string {\n return OPERATOR_LABELS[operator];\n}\n\nexport function getQuantifierLabel(quantifier: 'any' | 'all'): string {\n return quantifier === 'all' ? 'all of' : 'any of';\n}\n\n// --- Multi-instance ---------------------------------------------------------\n\nconst SINGLE_INSTANCE_FILTER_TYPES: Set<CelFilterType> = new Set(['checkbox', 'radio', 'static']);\n\nexport function allowsMultipleConditions(filterType: CelFilterType): boolean {\n return !SINGLE_INSTANCE_FILTER_TYPES.has(filterType);\n}\n\n// --- Default operator on add -----------------------------------------------\n\nexport function getDefaultOperator(filterType: CelFilterType): CelOperator {\n switch (filterType) {\n case 'checkbox':\n case 'radio':\n case 'text':\n case 'static':\n return 'is';\n case 'multiText':\n return 'contains';\n case 'date':\n return 'is';\n case 'keyValue':\n return 'key_exists';\n default:\n return 'is';\n }\n}\n\n// --- Operator change value retention ----------------------------------------\n\n/**\n * Applies the minimal value-retention rules when the operator changes on an\n * existing condition. Returns a new condition; does not mutate the input.\n *\n * For dates, the clearing rules here are the enforcement half of the date state\n * machine the date editor implements: clear when the value shape changes (range\n * operators vs single-instant ones), or when a relative value would become\n * illegal under `is`/`is_not`, and drop a picked time when moving to a\n * whole-day operator. Keep both in sync.\n */\nexport function applyOperatorChange(\n condition: CelFilterCondition,\n newOperator: CelOperator,\n shape: CelFilterShape | undefined,\n): CelFilterCondition {\n const next: CelFilterCondition = { ...condition, operator: newOperator };\n const oldOperator = condition.operator;\n\n if (shape === 'date') {\n const value = condition.value;\n const isRelative = isDateCelValue(value) && isRelativeDateCelValue(value);\n // `is_between` ↔ `is_not_between` keep the range; swapping between a range\n // operator and a single-instant one cannot reuse the value.\n const changesValueShape = isDateRangeOperator(oldOperator) !== isDateRangeOperator(newOperator);\n const relativeNeedsClear = isRelative && (newOperator === 'is' || newOperator === 'is_not');\n\n if (changesValueShape || relativeNeedsClear) {\n next.value = undefined;\n return next;\n }\n if (isDateCelValue(value) && value.hasTime && isDateWindowOperator(newOperator)) {\n const { hasTime: _hasTime, ...dayOnly } = value;\n next.value = dayOnly;\n }\n return next;\n }\n\n if (shape === 'map') {\n const value = condition.value;\n if (!isMapKeyCelValue(value)) {\n return next;\n }\n const bothValueOps = MAP_VALUE_OPERATORS.includes(oldOperator) && MAP_VALUE_OPERATORS.includes(newOperator);\n next.value = bothValueOps ? { key: value.key, value: value.value } : { key: value.key };\n return next;\n }\n\n // checkbox / radio / text / multiText: every operator uses the same value shape.\n return next;\n}\n\n// --- CEL fragment generation ------------------------------------------------\n\nexport type ConditionExpression = {\n /** Raw CEL fragment without any outer grouping parentheses. */\n expression: string;\n /** True when the fragment has a bare top-level `||` and must be parenthesized to join under `&&`. */\n needsGrouping: boolean;\n};\n\nconst atomic = (expression: string): ConditionExpression => ({ expression, needsGrouping: false });\n\n/**\n * Builds the CEL fragment for a single condition. Assumes the condition has\n * already passed validation; callers must not pass incomplete/invalid conditions.\n */\nexport function buildConditionExpression(\n condition: CelFilterCondition,\n shape: CelFilterShape,\n columnDef?: CelColumnDefinition,\n): ConditionExpression {\n if (shape === 'map') {\n return buildMapExpression(condition.columnId, condition.operator, condition.value as MapKeyCelValue);\n }\n\n const columnId = columnDef?.id ?? condition.columnId ?? '';\n const column = RESERVED_COLUMN_CEL_IDENTIFIERS[columnId] ?? columnId;\n\n switch (shape) {\n case 'checkbox':\n return buildCheckboxExpression(column, condition.operator, (condition.value as string[]) ?? []);\n case 'radio':\n return buildRadioExpression(column, condition.operator, String(condition.value ?? ''));\n case 'text':\n return atomic(buildTextTokenFragment(column, condition.operator, String(condition.value ?? '')));\n case 'multiText':\n return buildMultiTextExpression(column, condition.operator, condition.value as MultiTextCelValue);\n case 'date':\n return atomic(buildDateExpression(column, condition.operator, condition.value as DateCelValue));\n default:\n return atomic('');\n }\n}\n\nfunction buildCheckboxExpression(column: string, operator: CelOperator, values: string[]): ConditionExpression {\n const list = `${column} in [${values.map(celStringLiteral).join(', ')}]`;\n return atomic(operator === 'is_not' ? `!(${list})` : list);\n}\n\nfunction buildRadioExpression(column: string, operator: CelOperator, value: string): ConditionExpression {\n const literal = celStringLiteral(value);\n return atomic(operator === 'is_not' ? `${column} != ${literal}` : `${column} == ${literal}`);\n}\n\n/**\n * Builds the CEL fragment for a single text token. Single source of truth for\n * the text operator → CEL template mapping.\n *\n * `forcePositive` controls how the two negated operators (`is_not`,\n * `does_not_contain`) render:\n * - `false` (default): native negation (`col != \"x\"`, `!col.contains(\"x\")`).\n * Used for a lone token, where the negation lives on the token itself.\n * - `true`: the positive form (`col == \"x\"`, `col.contains(\"x\")`). Used when\n * composing multiple tokens, where the caller wraps the whole joined\n * expression in a single `!( … )` instead (see `buildMultiTextExpression`).\n */\nfunction buildTextTokenFragment(column: string, operator: CelOperator, value: string, forcePositive = false): string {\n const literal = celStringLiteral(value);\n switch (operator) {\n case 'is':\n return `${column} == ${literal}`;\n case 'is_not':\n return forcePositive ? `${column} == ${literal}` : `${column} != ${literal}`;\n case 'contains':\n return `${column}.contains(${literal})`;\n case 'does_not_contain':\n return forcePositive ? `${column}.contains(${literal})` : `!${column}.contains(${literal})`;\n case 'starts_with':\n return `${column}.startsWith(${literal})`;\n case 'ends_with':\n return `${column}.endsWith(${literal})`;\n case 'matches':\n return `${column}.matches(${literal})`;\n default:\n return '';\n }\n}\n\nfunction isNegatedTextOperator(operator: CelOperator): boolean {\n return operator === 'is_not' || operator === 'does_not_contain';\n}\n\nfunction buildMultiTextExpression(\n column: string,\n operator: CelOperator,\n value: MultiTextCelValue,\n): ConditionExpression {\n const tokens = value.tokens;\n\n if (tokens.length === 1) {\n return atomic(buildTextTokenFragment(column, operator, tokens[0]));\n }\n\n const connective = value.quantifier === 'all' ? ' && ' : ' || ';\n const joined = tokens.map(token => buildTextTokenFragment(column, operator, token, true)).join(connective);\n\n if (isNegatedTextOperator(operator)) {\n return atomic(`!(${joined})`);\n }\n\n // A bare top-level `||` (any quantifier) must be parenthesized when joined under `&&`.\n return { expression: joined, needsGrouping: value.quantifier !== 'all' };\n}\n\nconst DATE_RELATIVE_COMPARATOR_SYMBOLS: Partial<Record<CelOperator, string>> = {\n is_before: '<',\n is_after: '>',\n is_on_or_before: '<=',\n is_on_or_after: '>=',\n};\n\nfunction buildCalendarDayRange(column: string, startInstant: string, endInstant: string): string {\n const start = `timestamp(${celStringLiteral(startInstant)})`;\n const end = `timestamp(${celStringLiteral(endInstant)})`;\n return `${column} >= ${start} && ${column} <= ${end}`;\n}\n\nfunction buildDateExpression(column: string, operator: CelOperator, value: DateCelValue): string {\n if (isRelativeDateCelValue(value)) {\n const durationStr = value.preset ?? '';\n if (!durationStr) {\n return '';\n }\n const relativeSymbol = DATE_RELATIVE_COMPARATOR_SYMBOLS[operator] ?? '>';\n return `${column} ${relativeSymbol} now() - duration(${celStringLiteral(durationStr)})`;\n }\n\n if (isDateRangeOperator(operator) && value.range) {\n const range = buildCalendarDayRange(column, value.range.start, value.range.end);\n return operator === 'is_not_between' ? `!(${range})` : range;\n }\n\n const startInstant = value.instant ?? '';\n // `is` / `is_not` span a whole calendar day whatever the instant carries; the\n // comparators bound the minute the user picked once they have picked one.\n const granularity = value.hasTime && !isDateWindowOperator(operator) ? 'minute' : 'day';\n const endInstant = inclusiveEndInstant(startInstant, granularity);\n const startTimestamp = `timestamp(${celStringLiteral(startInstant)})`;\n const endTimestamp = `timestamp(${celStringLiteral(endInstant)})`;\n\n switch (operator) {\n case 'is':\n return buildCalendarDayRange(column, startInstant, endInstant);\n case 'is_not':\n return `!(${buildCalendarDayRange(column, startInstant, endInstant)})`;\n case 'is_before':\n return `${column} < ${startTimestamp}`;\n case 'is_on_or_before':\n return `${column} <= ${endTimestamp}`;\n case 'is_after':\n return `${column} > ${endTimestamp}`;\n case 'is_on_or_after':\n return `${column} >= ${startTimestamp}`;\n default:\n return `${column} == ${startTimestamp}`;\n }\n}\n\nfunction buildMapExpression(columnId: string, operator: CelOperator, value: MapKeyCelValue): ConditionExpression {\n const column = RESERVED_COLUMN_CEL_IDENTIFIERS[columnId] ?? columnId;\n const keyLiteral = celStringLiteral(value.key);\n\n switch (operator) {\n case 'key_exists':\n return atomic(`${keyLiteral} in ${column}`);\n case 'key_does_not_exist':\n return atomic(`!(${keyLiteral} in ${column})`);\n case 'has_value':\n return atomic(`${column}[${keyLiteral}] == ${celStringLiteral(value.value ?? '')}`);\n case 'does_not_have_value':\n return atomic(`${column}[${keyLiteral}] != ${celStringLiteral(value.value ?? '')}`);\n default:\n return atomic('');\n }\n}\n\n/** Maps parsed CEL aliases back to schema column ids when building the filter tree. */\nexport function denormalizeColumnIdWithReservedNames(columnId: string): string {\n return CEL_IDENTIFIER_TO_COLUMN_ID[columnId] ?? columnId;\n}\n\n/** Rewrites reserved schema column references in a CEL expression before parsing. */\nexport function normalizeColumnsWithReservedNames(expression: string): string {\n return Object.entries(RESERVED_COLUMN_CEL_IDENTIFIERS).reduce(\n (normalized, [columnId, celIdentifier]) =>\n normalized.replace(\n new RegExp(`\\\\b${escapeRegExp(columnId)}\\\\b${RESERVED_FIELD_OPERATOR_PATTERN}`, 'g'),\n celIdentifier,\n ),\n expression,\n );\n}\n\n/** Rewrites CEL aliases back to schema column names for API requests and external consumers. */\nexport function denormalizeColumnsWithReservedNames(expression: string): string {\n return Object.entries(RESERVED_COLUMN_CEL_IDENTIFIERS).reduce(\n (denormalized, [columnId, celIdentifier]) =>\n denormalized.replace(\n new RegExp(`\\\\b${escapeRegExp(celIdentifier)}\\\\b${RESERVED_FIELD_OPERATOR_PATTERN}`, 'g'),\n columnId,\n ),\n expression,\n );\n}\n","import { MAX_REGEX_LEN } from '../constants';\nimport { isRealCalendarDay } from '../date-utils';\nimport {\n type CelColumnDefinition,\n type CelFilterCondition,\n type CelFilterSchema,\n type CompileStatus,\n type DateCelValue,\n isDateCelValue,\n isMapKeyCelValue,\n isMultiTextCelValue,\n type MapKeyCelValue,\n type MultiTextCelValue,\n type ValidationIssue,\n type ValidationIssueCode,\n type ValidationSeverity,\n} from '../types';\nimport { isRelativeDateCelValue } from '../value-utils';\nimport { getAllowedOperators, isDateRangeOperator, isDateRelativeOperator, resolveColumnDefinition } from './operators';\n\n/** Derives the overall compile status from a set of issues (invalid beats incomplete beats valid). */\nexport function statusFromIssues(issues: ValidationIssue[]): CompileStatus {\n if (issues.some(issue => issue.severity === 'invalid')) {\n return 'invalid';\n }\n if (issues.some(issue => issue.severity === 'incomplete')) {\n return 'incomplete';\n }\n return 'valid';\n}\n\nconst SEVERITY_BY_CODE: Record<ValidationIssueCode, ValidationSeverity> = {\n missing_column: 'incomplete',\n missing_value: 'incomplete',\n missing_key: 'incomplete',\n missing_tokens: 'incomplete',\n missing_quantifier: 'incomplete',\n missing_instant: 'incomplete',\n missing_range: 'incomplete',\n missing_duration: 'incomplete',\n unknown_column: 'invalid',\n illegal_operator: 'invalid',\n invalid_date_mode: 'invalid',\n regex_too_long: 'invalid',\n invalid_timestamp: 'invalid',\n invalid_date_range: 'invalid',\n nesting_depth_exceeded: 'invalid',\n};\n\nconst MESSAGES: Record<ValidationIssueCode, string> = {\n missing_column: 'Select a column for this filter.',\n missing_value: 'Enter a value for this filter.',\n missing_key: 'Enter a key for this filter.',\n missing_tokens: 'Enter at least one value for this filter.',\n missing_quantifier: 'Choose whether to match any or all values.',\n missing_instant: 'Select a date for this filter.',\n missing_range: 'Select a start and end date for this filter.',\n missing_duration: 'Select a duration for this filter.',\n unknown_column: 'This column is not available for filtering.',\n illegal_operator: 'This operator is not allowed for this filter.',\n invalid_date_mode: 'This operator cannot be used with this date mode.',\n regex_too_long: `Pattern exceeds the maximum length of ${MAX_REGEX_LEN} characters.`,\n invalid_timestamp: 'Enter a valid date.',\n invalid_date_range: 'The start must be on or before the end.',\n nesting_depth_exceeded: 'This filter is nested too deeply.',\n};\n\n/** RFC3339 timestamp (date + time + Z or numeric offset). */\nconst RFC3339_RE = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})$/;\n\nfunction isValidRfc3339(value: string): boolean {\n return RFC3339_RE.test(value) && !Number.isNaN(Date.parse(value)) && isRealCalendarDay(value);\n}\n\ntype IssueInput = {\n condition: CelFilterCondition;\n code: ValidationIssueCode;\n field?: string;\n};\n\nfunction makeIssue({ condition, code, field }: IssueInput): ValidationIssue {\n return {\n code,\n message: MESSAGES[code],\n severity: SEVERITY_BY_CODE[code],\n nodeId: condition.id,\n nodeType: 'condition',\n field,\n };\n}\n\n/**\n * Validates a single condition against the provided schema. Returns an empty\n * array when the condition is complete and compilable.\n */\nexport function validateCondition(condition: CelFilterCondition, schema: CelFilterSchema): ValidationIssue[] {\n if (!condition.columnId) {\n return [makeIssue({ condition, code: 'missing_column', field: 'columnId' })];\n }\n const columnDef = resolveColumnDefinition(condition, schema);\n if (!columnDef) {\n return [makeIssue({ condition, code: 'unknown_column', field: 'columnId' })];\n }\n return validateColumnCondition(condition, columnDef);\n}\n\nfunction validateColumnCondition(condition: CelFilterCondition, columnDef: CelColumnDefinition): ValidationIssue[] {\n const allowed = getAllowedOperators(columnDef);\n\n if (!allowed.includes(condition.operator)) {\n return [makeIssue({ condition, code: 'illegal_operator', field: 'operator' })];\n }\n\n switch (columnDef.filterType) {\n case 'checkbox':\n case 'static':\n return validateCheckbox(condition);\n case 'radio':\n case 'text':\n return validateSingleString(condition, columnDef.filterType);\n case 'multiText':\n return validateMultiText(condition);\n case 'date':\n return validateDate(condition);\n case 'keyValue':\n return validateMapCondition(condition);\n default:\n return [];\n }\n}\n\nfunction validateCheckbox(condition: CelFilterCondition): ValidationIssue[] {\n const value = condition.value;\n if (!Array.isArray(value) || value.length === 0) {\n return [makeIssue({ condition, code: 'missing_value', field: 'value' })];\n }\n return [];\n}\n\nfunction validateSingleString(condition: CelFilterCondition, filterType: 'radio' | 'text'): ValidationIssue[] {\n const value = condition.value;\n if (typeof value !== 'string' || value === '') {\n return [makeIssue({ condition, code: 'missing_value', field: 'value' })];\n }\n if (filterType === 'text' && condition.operator === 'matches' && value.length > MAX_REGEX_LEN) {\n return [makeIssue({ condition, code: 'regex_too_long', field: 'pattern' })];\n }\n return [];\n}\n\nfunction validateMultiText(condition: CelFilterCondition): ValidationIssue[] {\n const value = condition.value;\n if (!isMultiTextCelValue(value) || value.tokens.length === 0) {\n return [makeIssue({ condition, code: 'missing_tokens', field: 'tokens' })];\n }\n\n const issues: ValidationIssue[] = [];\n const multi = value as MultiTextCelValue;\n\n if (multi.tokens.length > 1 && !multi.quantifier) {\n issues.push(makeIssue({ condition, code: 'missing_quantifier', field: 'quantifier' }));\n }\n\n if (condition.operator === 'matches' && multi.tokens.some(token => token.length > MAX_REGEX_LEN)) {\n issues.push(makeIssue({ condition, code: 'regex_too_long', field: 'pattern' }));\n }\n\n return issues;\n}\n\nfunction validateDate(condition: CelFilterCondition): ValidationIssue[] {\n const value = condition.value;\n\n if (!isDateCelValue(value)) {\n // Freshly added / undefined date condition — treat as a missing single-point instant.\n return [makeIssue({ condition, code: 'missing_instant', field: 'instant' })];\n }\n\n const date = value as DateCelValue;\n\n if (isRelativeDateCelValue(date)) {\n return validateRelativeDate(condition, date);\n }\n return validateAbsoluteDate(condition, date);\n}\n\nfunction validateAbsoluteDate(condition: CelFilterCondition, value: DateCelValue): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n\n if (isDateRangeOperator(condition.operator)) {\n const range = value.range;\n if (!range || !range.start || !range.end) {\n issues.push(makeIssue({ condition, code: 'missing_range', field: 'range' }));\n return issues;\n }\n if (!isValidRfc3339(range.start)) {\n issues.push(makeIssue({ condition, code: 'invalid_timestamp', field: 'start' }));\n }\n if (!isValidRfc3339(range.end)) {\n issues.push(makeIssue({ condition, code: 'invalid_timestamp', field: 'end' }));\n }\n if (issues.length === 0 && Date.parse(range.start) > Date.parse(range.end)) {\n issues.push(makeIssue({ condition, code: 'invalid_date_range', field: 'range' }));\n }\n return issues;\n }\n\n if (!value.instant) {\n issues.push(makeIssue({ condition, code: 'missing_instant', field: 'instant' }));\n return issues;\n }\n if (!isValidRfc3339(value.instant)) {\n issues.push(makeIssue({ condition, code: 'invalid_timestamp', field: 'instant' }));\n }\n return issues;\n}\n\nfunction validateRelativeDate(condition: CelFilterCondition, value: DateCelValue): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n\n if (!isDateRelativeOperator(condition.operator)) {\n issues.push(makeIssue({ condition, code: 'invalid_date_mode', field: 'value' }));\n return issues;\n }\n\n if (!value.preset) {\n issues.push(makeIssue({ condition, code: 'missing_duration', field: 'preset' }));\n }\n return issues;\n}\n\nfunction validateMapCondition(condition: CelFilterCondition): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n\n const value = isMapKeyCelValue(condition.value) ? (condition.value as MapKeyCelValue) : undefined;\n\n if (!value || value.key === '') {\n issues.push(makeIssue({ condition, code: 'missing_key', field: 'key' }));\n }\n\n const requiresValue = condition.operator === 'has_value' || condition.operator === 'does_not_have_value';\n if (requiresValue && (!value || !value.value)) {\n issues.push(makeIssue({ condition, code: 'missing_value', field: 'value' }));\n }\n\n return issues;\n}\n","/**\n * Applies draft/commit display rules to a raw compile result.\n *\n * Validation timing: a condition's issues are surfaced on its pill and in the\n * global panel only once it has been committed (popover closed) and is not\n * currently being edited. Group-level issues (e.g. nesting depth) always show.\n *\n * `isEmitReady` on the returned object is always `false` here — it is a\n * placeholder that `CelFilterBar` overrides via `computeIsEmitReady` before\n * calling `onCompileResultChange`. This is the single source of truth for the gate.\n */\nimport { type CelValidationMeta, type CompileResult } from '../types';\nimport { statusFromIssues } from './validate-condition';\n\nexport function applyDisplayRules(raw: CompileResult, meta: CelValidationMeta): CompileResult {\n const issues = raw.issues.filter(issue => {\n if (issue.nodeType === 'group') {\n return true;\n }\n if (issue.nodeId === meta.editingConditionId) {\n return false;\n }\n return meta.committedConditionIds.has(issue.nodeId);\n });\n\n const status = statusFromIssues(issues);\n const expression = status === 'valid' ? raw.expression : undefined;\n\n return {\n status,\n expression,\n issues,\n isEmitReady: false,\n };\n}\n","import { resolveFilterShape } from './compile/operators';\nimport type { CelColumnDefinition, CelEmitOn, CelFilterCondition, CelFilterSchema } from './types';\nimport { readMapKeyCelValue } from './value-utils';\n\nconst COMMIT_FILTER_TYPES = new Set<CelColumnDefinition['filterType']>(['text', 'multiText', 'keyValue', 'date']);\n\nexport function isMultiTextColumn(columnId: string, schema: CelFilterSchema): boolean {\n return schema.columns.find(column => column.id === columnId)?.filterType === 'multiText';\n}\n\n/** Returns when a column's valid value may be emitted; explicit `emitOn` overrides filterType defaults. */\nexport function getColumnEmitOn(columnDef: CelColumnDefinition): CelEmitOn {\n if (columnDef.emitOn) {\n return columnDef.emitOn;\n }\n return COMMIT_FILTER_TYPES.has(columnDef.filterType) ? 'commit' : 'change';\n}\n\n/** After operator change, keyValue may need the value field before the condition is complete. */\nexport function shouldOpenValueSurfaceAfterOperatorChange(\n condition: CelFilterCondition,\n schema: CelFilterSchema,\n): boolean {\n if (resolveFilterShape(condition, schema) !== 'map') {\n return false;\n }\n const requiresValue = condition.operator === 'has_value' || condition.operator === 'does_not_have_value';\n if (!requiresValue) {\n return false;\n }\n return !readMapKeyCelValue(condition.value).value?.trim();\n}\n","import { getColumnEmitOn } from '../schema-utils';\nimport {\n type CelColumnDefinition,\n type CelFilterCondition,\n type CelFilterSchema,\n type CelFilterTree,\n type CompileResult,\n isCelFilterCondition,\n type PillActiveSurface,\n} from '../types';\n\nexport type ComputeIsEmitReadyMeta = {\n activeSurface: PillActiveSurface | null;\n committedConditionIds: Set<string>;\n};\n\nfunction resolveEditingColumn(\n tree: CelFilterTree,\n schema: CelFilterSchema,\n editingConditionId: string,\n): CelColumnDefinition | undefined {\n const condition = tree.root.children.find(\n (child): child is CelFilterCondition => isCelFilterCondition(child) && child.id === editingConditionId,\n );\n return condition && schema.columns.find(column => column.id === condition.columnId);\n}\n\n/**\n * Gates API emission while a commit-mode condition is mid-edit. Only the\n * actively edited condition matters — one popover at a time.\n */\nexport function computeIsEmitReady(\n raw: CompileResult,\n editingConditionId: string | null,\n schema: CelFilterSchema,\n tree: CelFilterTree,\n meta: ComputeIsEmitReadyMeta,\n): boolean {\n if (raw.status !== 'valid') return false;\n if (!editingConditionId) return true;\n\n const columnDef = resolveEditingColumn(tree, schema, editingConditionId);\n // Unknown column or change-mode → nothing to gate, emit live.\n if (!columnDef || getColumnEmitOn(columnDef) === 'change') return true;\n\n // Commit-mode: emit only once the popover is closed and the draft committed.\n const popoverClosed = meta.activeSurface === null;\n return popoverClosed && meta.committedConditionIds.has(editingConditionId);\n}\n","/**\n * Compiles a CEL filter tree into a CEL string or structured validation issues.\n *\n * Pure logic — no React, no display rules. `CelFilterBar` composes\n * `applyDisplayRules(compileCelFilterTree(tree, schema), meta)`.\n */\nimport { MAX_NESTING_DEPTH } from '../constants';\nimport {\n type CelColumnDefinition,\n type CelFilterGroup,\n type CelFilterSchema,\n type CelFilterTree,\n type CompileResult,\n isCelFilterCondition,\n isCelFilterGroup,\n type ValidationIssue,\n} from '../types';\nimport {\n buildConditionExpression,\n type ConditionExpression,\n resolveColumnDefinition,\n resolveFilterShape,\n} from './operators';\nimport { statusFromIssues, validateCondition } from './validate-condition';\n\ntype GroupCompileResult = {\n issues: ValidationIssue[];\n fragments: ConditionExpression[];\n};\n\n/**\n * Combines a group's child fragments into a single fragment.\n *\n * v1 groups are always `&&`. A child fragment with a bare top-level `||`\n * (e.g. a multiText `any`) is parenthesized before joining so precedence is\n * preserved. The produced fragment reports whether *it* needs grouping when\n * placed under a parent `&&`:\n *\n * - 0 children → empty fragment.\n * - 1 child → propagated as-is so the parent decides on parens (a lone `||`\n * fragment must still be wrapped by whoever joins it under `&&`).\n * - >1 children → a pure `&&` chain, which never needs outer parens under `&&`.\n *\n * (If a future `||` group combinator ships, the connective and `needsGrouping`\n * become combinator-aware; today every group is `&&`.)\n */\nfunction combineGroupFragments(fragments: ConditionExpression[]): ConditionExpression {\n if (fragments.length === 0) {\n return { expression: '', needsGrouping: false };\n }\n if (fragments.length === 1) {\n return fragments[0];\n }\n return {\n expression: fragments\n .map(fragment => (fragment.needsGrouping ? `(${fragment.expression})` : fragment.expression))\n .join(' && '),\n needsGrouping: false,\n };\n}\n\nfunction compileGroup(group: CelFilterGroup, schema: CelFilterSchema): GroupCompileResult {\n const depthIssues: ValidationIssue[] =\n group.depth > MAX_NESTING_DEPTH\n ? [\n {\n code: 'nesting_depth_exceeded',\n message: 'This filter is nested too deeply.',\n severity: 'invalid',\n nodeId: group.id,\n nodeType: 'group',\n },\n ]\n : [];\n\n return group.children.reduce<GroupCompileResult>(\n (acc, child) => {\n if (isCelFilterGroup(child)) {\n const nested = compileGroup(child, schema);\n acc.issues.push(...nested.issues);\n if (nested.fragments.length > 0) {\n acc.fragments.push(combineGroupFragments(nested.fragments));\n }\n return acc;\n }\n\n if (isCelFilterCondition(child)) {\n const conditionIssues = validateCondition(child, schema);\n if (conditionIssues.length > 0) {\n acc.issues.push(...conditionIssues);\n return acc;\n }\n\n const shape = resolveFilterShape(child, schema);\n if (!shape) {\n return acc;\n }\n const columnDef: CelColumnDefinition | undefined = resolveColumnDefinition(child, schema);\n acc.fragments.push(buildConditionExpression(child, shape, columnDef));\n }\n\n return acc;\n },\n { issues: depthIssues, fragments: [] },\n );\n}\n\n/**\n * Walks the tree, joins root children with ` && `, and emits a CEL string when\n * everything is complete and valid. An empty root compiles to `\"\"` with status\n * `valid` (the API treats an empty filter as no filter).\n */\nexport function compileCelFilterTree(tree: CelFilterTree, schema: CelFilterSchema): CompileResult {\n const { issues, fragments } = compileGroup(tree.root, schema);\n const status = statusFromIssues(issues);\n\n if (status === 'valid') {\n return { status, expression: combineGroupFragments(fragments).expression, issues, isEmitReady: true };\n }\n\n return { status, issues, isEmitReady: false };\n}\n","/**\n * Tree factories and helpers for the CEL filter builder.\n */\nimport { getDefaultOperator } from './compile/operators';\nimport { isCelFilterCondition } from './types';\nimport type { CelFilterCondition, CelFilterSchema, CelFilterTree } from './types';\n\n/** Generates a stable unique id, falling back when `crypto.randomUUID` is unavailable. */\nexport function createCelNodeId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n return `cel-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Creates an empty tree whose root is a depth-0 `and` group with no children. */\nexport function createEmptyCelFilterTree(): CelFilterTree {\n return {\n root: {\n id: createCelNodeId(),\n type: 'group',\n combinator: 'and',\n depth: 0,\n children: [],\n },\n };\n}\n\nexport type CreateDefaultConditionParams = {\n schema: CelFilterSchema;\n columnId: string;\n};\n\n/**\n * Creates a new condition with the default operator for its column and an\n * undefined value (filled in by the user in the popover).\n */\nexport function createDefaultCondition({ schema, columnId }: CreateDefaultConditionParams): CelFilterCondition {\n const columnDef = schema.columns.find(column => column.id === columnId);\n if (!columnDef) {\n throw new Error(`createDefaultCondition: column \"${columnId}\" is not in schema.columns`);\n }\n\n return {\n id: createCelNodeId(),\n type: 'condition',\n columnId,\n operator: getDefaultOperator(columnDef.filterType),\n value: columnDef.defaultValue,\n };\n}\n\n/** Appends a condition to the root group's children. */\nexport function appendCondition(tree: CelFilterTree, condition: CelFilterCondition): CelFilterTree {\n return { root: { ...tree.root, children: [...tree.root.children, condition] } };\n}\n\n/** Replaces a root-level condition by id, applying `updater` to the existing condition. Root-level only — v1's UI never produces nested groups. */\nexport function replaceCondition(\n tree: CelFilterTree,\n conditionId: string,\n updater: (condition: CelFilterCondition) => CelFilterCondition,\n): CelFilterTree {\n return {\n root: {\n ...tree.root,\n children: tree.root.children.map(child =>\n isCelFilterCondition(child) && child.id === conditionId ? updater(child) : child,\n ),\n },\n };\n}\n\n/** Removes a root-level condition by id. */\nexport function removeConditionById(tree: CelFilterTree, conditionId: string): CelFilterTree {\n return {\n root: {\n ...tree.root,\n children: tree.root.children.filter(child => !(isCelFilterCondition(child) && child.id === conditionId)),\n },\n };\n}\n","import type { Cell, ColumnFilter, ColumnFiltersState, RowData } from '@tanstack/react-table';\n\nimport './table-meta';\nimport type { ColumnFilterDefinition, ColumnFilterValue } from './filter-types';\n\nfunction valueToString(value: unknown): string | undefined {\n if (value === undefined || value === null) return undefined;\n const normalized = String(value).trim();\n return normalized || undefined;\n}\n\nfunction stringArrayFromValue(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value.map(valueToString).filter((v): v is string => !!v);\n }\n const normalized = valueToString(value);\n return normalized ? [normalized] : [];\n}\n\n/** Flattens a scalar or array cell value into trimmed, non-empty strings — the\n * shape `celFilterConfig.onContextualFilter` and `mergeContextualIntoCelTree` want. */\nexport function columnFilterValueToStrings(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value.map(item => String(item).trim()).filter(Boolean);\n }\n const normalized = String(value ?? '').trim();\n return normalized ? [normalized] : [];\n}\n\nexport function hasContextualFilterValue(value: ColumnFilterValue | undefined): boolean {\n if (value === undefined) return false;\n if (typeof value === 'string') return value.trim() !== '';\n if (Array.isArray(value)) {\n return value.filter(item => typeof item === 'string' && item.trim() !== '').length > 0;\n }\n return !!(value.startDate ?? value.endDate);\n}\n\nfunction getDefaultContextualFilterValue<TData extends RowData, TValue>(\n cell: Cell<TData, TValue>,\n filter: ColumnFilterDefinition,\n): ColumnFilterValue | undefined {\n const value = cell.getValue();\n\n if (filter.type === 'checkbox' || filter.type === 'multiText') {\n const values = stringArrayFromValue(value);\n return values.length > 0 ? values : undefined;\n }\n\n if (filter.type === 'radio' || filter.type === 'text') {\n return valueToString(value);\n }\n\n return undefined;\n}\n\n/** Derives the contextual (right-click cell) column filter, or `undefined` if\n * the column has no `meta.filter` or no value can be derived. */\nexport function getContextualColumnFilter<TData extends RowData, TValue>(\n cell: Cell<TData, TValue>,\n): ColumnFilter | undefined {\n const meta = cell.column.columnDef.meta;\n const filter = meta?.filter;\n if (!filter) return undefined;\n\n const value = meta?.contextualFilterValue\n ? meta.contextualFilterValue(cell)\n : getDefaultContextualFilterValue(cell, filter);\n if (!hasContextualFilterValue(value)) return undefined;\n\n return { id: cell.column.id, value };\n}\n\n/** Derives the contextual (right-click cell) global-search term, or `undefined`\n * when the column has no `meta.contextualGlobalSearchValue`. */\nexport function getContextualGlobalSearch<TData extends RowData, TValue>(\n cell: Cell<TData, TValue>,\n): string | undefined {\n const globalSearchValue = cell.column.columnDef.meta?.contextualGlobalSearchValue;\n if (!globalSearchValue) return undefined;\n return valueToString(globalSearchValue(cell));\n}\n\n/**\n * Merges a contextual filter into `ColumnFiltersState`. Checkbox/multiText\n * filters union with any existing values for that column (deduped); every\n * other type replaces the column's filter outright.\n */\nexport function mergeColumnFilter(\n columnFilters: ColumnFiltersState,\n nextFilter: ColumnFilter,\n filterDefinition?: ColumnFilterDefinition,\n): ColumnFiltersState {\n const shouldMergeArrayValue = filterDefinition?.type === 'checkbox' || filterDefinition?.type === 'multiText';\n\n if (!shouldMergeArrayValue) {\n return [...columnFilters.filter(filter => filter.id !== nextFilter.id), nextFilter];\n }\n\n const nextValues = stringArrayFromValue(nextFilter.value);\n if (nextValues.length === 0) return columnFilters;\n\n const existingFilter = columnFilters.find(filter => filter.id === nextFilter.id);\n const existingValues = stringArrayFromValue(existingFilter?.value);\n const mergedValues = Array.from(new Set([...existingValues, ...nextValues]));\n\n if (existingFilter && mergedValues.length === existingValues.length) return columnFilters;\n\n return [...columnFilters.filter(filter => filter.id !== nextFilter.id), { id: nextFilter.id, value: mergedValues }];\n}\n\n/**\n * Counts active filter \"slots\" for UI badges (the Filter-button count and the\n * empty-view filter count). When `filter` is omitted, falls back to a\n * best-effort shape heuristic (ambiguous for `string` vs radio and `string[]`\n * vs multiText).\n */\nexport function getColumnFilterCount(filterValue: unknown, filter?: ColumnFilterDefinition): number {\n const isCheckboxValue = (value: unknown): value is string[] | undefined =>\n value === undefined || (Array.isArray(value) && value.every(item => typeof item === 'string'));\n const isRadioValue = (value: unknown): value is string | undefined =>\n value === undefined || typeof value === 'string';\n const isDateRangeValue = (value: unknown): value is { startDate: Date | null; endDate: Date | null } | undefined =>\n value === undefined || (typeof value === 'object' && value !== null && 'startDate' in value && 'endDate' in value);\n\n if (filter?.type === 'checkbox') {\n return isCheckboxValue(filterValue) ? (filterValue || []).length : 0;\n }\n\n if (filter?.type === 'radio') {\n return isRadioValue(filterValue) && filterValue !== undefined ? 1 : 0;\n }\n\n if (filter?.type === 'dateRange') {\n if (!isDateRangeValue(filterValue)) return 0;\n return Number(!!filterValue?.startDate) + Number(!!filterValue?.endDate);\n }\n\n if (isCheckboxValue(filterValue)) {\n return (filterValue || []).length;\n }\n\n if (isRadioValue(filterValue) && filterValue !== undefined) {\n return 1;\n }\n\n if (isDateRangeValue(filterValue)) {\n return Number(!!filterValue?.startDate) + Number(!!filterValue?.endDate);\n }\n\n return 0;\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport type { ColumnSizingState, OnChangeFn } from '@tanstack/react-table';\n\nexport const RESIZE_MIN = 40;\nexport const RESIZE_MAX = 500;\n/** Grid layout's \"unbounded\" max — not `Infinity` (mirrors the source constant exactly). Only relevant once grid mode ships. */\nexport const RESIZE_MAX_UNBOUNDED = Number.MAX_SAFE_INTEGER;\nexport const DEFAULT_COLUMN_SIZE = 150;\nconst FIT_CONTENT_PLACEHOLDER_SIZE = 400;\nconst PERSIST_DEBOUNCE_MS = 300;\n/** Grid layout's `fr` values are floored here to avoid zero/negative CSS Grid tracks. */\nexport const MIN_FR_VALUE = 0.01;\n\nexport interface UseTableColumnResizingOptions {\n initialSizing?: ColumnSizingState;\n onColumnSizingPersist?: (sizing: ColumnSizingState) => void;\n maxSize?: number;\n}\n\nexport function clampSizing(sizing: ColumnSizingState, maxSize = RESIZE_MAX): ColumnSizingState {\n return Object.entries(sizing).reduce<ColumnSizingState>(\n (acc, [colId, size]) => ({ ...acc, [colId]: Math.min(maxSize, Math.max(RESIZE_MIN, size)) }),\n {},\n );\n}\n\n/** A resize-start snapshot of the grid's flex/fixed classification — captured once per drag. */\nexport interface GridResizeSnapshotMeta {\n containerWidth: number;\n fixedTotal: number;\n flexIds: string[];\n mins: Record<string, number>;\n}\n\nexport interface ComputeGridResizeFrValuesOptions {\n resizingColumnId: string | false;\n deltaOffset?: number | null;\n visualOrder: string[];\n snapshotWidths: Record<string, number>;\n snapshotMeta: GridResizeSnapshotMeta;\n}\n\n/**\n * Redistributes flex-column `fr` values for a live grid-mode drag resize.\n * The dragged column grows/shrinks to `deltaOffset`; the space is absorbed\n * from flex columns to its right first, falling back to the left, while\n * columns on the frozen side keep their pre-drag snapshot width verbatim.\n * Every returned value is a pixel count (not a true proportional weight) —\n * a fresh per-drag redistribution, not a persisted ratio.\n */\nexport function computeGridResizeFrValues({\n resizingColumnId,\n deltaOffset,\n visualOrder,\n snapshotWidths,\n snapshotMeta,\n}: ComputeGridResizeFrValuesOptions): Record<string, number> {\n if (!resizingColumnId || deltaOffset == null || snapshotMeta.containerWidth <= 0) {\n return {};\n }\n\n const { fixedTotal, flexIds, mins, containerWidth } = snapshotMeta;\n const snapshotPx = snapshotWidths[resizingColumnId];\n if (!snapshotPx || !flexIds.includes(resizingColumnId)) {\n return {};\n }\n\n const desiredPx = Math.max(mins[resizingColumnId] ?? 0, snapshotPx + deltaOffset);\n const resizeIdx = visualOrder.indexOf(resizingColumnId);\n const otherFlexIds = flexIds.filter(colId => colId !== resizingColumnId);\n const rightFlexIds = otherFlexIds.filter(colId => visualOrder.indexOf(colId) > resizeIdx);\n const leftFlexIds = otherFlexIds.filter(colId => visualOrder.indexOf(colId) < resizeIdx);\n\n const absorbingIds = rightFlexIds.length > 0 ? rightFlexIds : leftFlexIds;\n const frozenIds = rightFlexIds.length > 0 ? leftFlexIds : rightFlexIds;\n const nextFr: Record<string, number> = {};\n\n for (const colId of frozenIds) {\n nextFr[colId] = snapshotWidths[colId] ?? MIN_FR_VALUE;\n }\n\n const frozenTotal = frozenIds.reduce((sum, colId) => sum + (snapshotWidths[colId] ?? 0), 0);\n const availableForAbsorbing = containerWidth - fixedTotal - desiredPx - frozenTotal;\n const absorbingSnapshotTotal = absorbingIds.reduce((sum, colId) => sum + (snapshotWidths[colId] ?? 0), 0);\n\n for (const colId of absorbingIds) {\n const snap = snapshotWidths[colId] ?? 0;\n const share = absorbingSnapshotTotal > 0 ? snap / absorbingSnapshotTotal : 1 / absorbingIds.length;\n const targetPx = Math.max(mins[colId] ?? 0, availableForAbsorbing * share);\n nextFr[colId] = Math.max(MIN_FR_VALUE, targetPx);\n }\n\n nextFr[resizingColumnId] = Math.max(MIN_FR_VALUE, desiredPx);\n return nextFr;\n}\n\nexport interface GridFlexSizingDefinition {\n flex?: number;\n min?: string;\n max?: string;\n}\n\nexport interface ResolveGridPersistedFrOptions {\n visualOrder: string[];\n persistedFr: Record<string, number>;\n columnSizing: ColumnSizingState;\n measuredMins: Record<string, number>;\n getGridSizing: (columnId: string) => GridFlexSizingDefinition | undefined;\n}\n\n/**\n * Reconciles persisted `fr` values (e.g. seeded from `initialColumnSizing`)\n * against each flex column's current min/max bounds — called while idle\n * (not mid-drag), since live drag values come from `computeGridResizeFrValues`.\n */\nexport function resolveGridPersistedFr({\n visualOrder,\n persistedFr,\n columnSizing,\n measuredMins,\n getGridSizing,\n}: ResolveGridPersistedFrOptions): Record<string, number> {\n const nextFr = { ...persistedFr };\n\n for (const colId of visualOrder) {\n const grid = getGridSizing(colId);\n if (!grid || grid.flex == null) continue;\n\n if (!nextFr[colId] && columnSizing[colId]) {\n nextFr[colId] = columnSizing[colId];\n }\n\n if (nextFr[colId]) {\n const minPx = measuredMins[colId] ?? (grid.min ? parseFloat(grid.min) || 0 : 0);\n const maxPx = grid.max ? parseFloat(grid.max) || Infinity : Infinity;\n nextFr[colId] = Math.max(minPx, Math.min(maxPx, nextFr[colId]));\n }\n }\n\n return nextFr;\n}\n\n/**\n * Column-resize state: clamped `[40, maxSize]` (default max 500), a\n * 300ms-debounced persist on drag, and immediate (debounce-cancelling)\n * persist from the three menu actions. \"Autosize\" in auto layout is a\n * 150⇄400 toggle, not real content measurement — real measurement only\n * exists in grid layout mode (not yet implemented on `DataTable`).\n */\nexport function useTableColumnResizing({\n initialSizing,\n onColumnSizingPersist,\n maxSize,\n}: UseTableColumnResizingOptions = {}) {\n const [columnSizing, setColumnSizing] = useState<ColumnSizingState>(() => clampSizing(initialSizing ?? {}, maxSize));\n const persistTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Re-syncs when `initialSizing`'s reference changes (e.g. an async-loaded\n // persisted sizing lands after mount) — but bails on a fresh-but-equal\n // object so a caller passing an inline literal doesn't clobber in-progress\n // resizes on every render. This is deliberately an effect, not derived\n // during render: `initialSizing` is an external (often async) value the\n // hook must adopt once, not on every render it happens to differ by\n // reference; the equality bailout is what keeps it from cascading.\n useEffect(() => {\n if (!initialSizing) return;\n const next = clampSizing(initialSizing, maxSize);\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setColumnSizing(prev => {\n const keys = Object.keys(next);\n if (Object.keys(prev).length !== keys.length) return next;\n return keys.every(k => prev[k] === next[k]) ? prev : next;\n });\n }, [initialSizing, maxSize]);\n\n useEffect(() => {\n return () => {\n if (persistTimerRef.current) clearTimeout(persistTimerRef.current);\n };\n }, []);\n\n const debouncedPersist = useCallback(\n (sizing: ColumnSizingState) => {\n if (persistTimerRef.current) clearTimeout(persistTimerRef.current);\n persistTimerRef.current = setTimeout(() => onColumnSizingPersist?.(sizing), PERSIST_DEBOUNCE_MS);\n },\n [onColumnSizingPersist],\n );\n\n const handleColumnSizingChange = useCallback<OnChangeFn<ColumnSizingState>>(\n updaterOrValue => {\n setColumnSizing(prev => {\n const raw = typeof updaterOrValue === 'function' ? updaterOrValue(prev) : updaterOrValue;\n const next = clampSizing(raw, maxSize);\n debouncedPersist(next);\n return next;\n });\n },\n [debouncedPersist, maxSize],\n );\n\n const cancelPendingPersist = useCallback(() => {\n if (persistTimerRef.current) {\n clearTimeout(persistTimerRef.current);\n persistTimerRef.current = null;\n }\n }, []);\n\n const handleAutosizeAll = useCallback(() => {\n cancelPendingPersist();\n setColumnSizing({});\n onColumnSizingPersist?.({});\n }, [cancelPendingPersist, onColumnSizingPersist]);\n\n const handleAutosizeColumn = useCallback(\n (columnId: string) => {\n cancelPendingPersist();\n setColumnSizing(prev => {\n const current = prev[columnId] ?? DEFAULT_COLUMN_SIZE;\n const next = { ...prev };\n next[columnId] = current <= DEFAULT_COLUMN_SIZE ? FIT_CONTENT_PLACEHOLDER_SIZE : DEFAULT_COLUMN_SIZE;\n onColumnSizingPersist?.(next);\n return next;\n });\n },\n [cancelPendingPersist, onColumnSizingPersist],\n );\n\n const handleResetColumnSize = useCallback(\n (columnId: string) => {\n cancelPendingPersist();\n setColumnSizing(prev => {\n const next = { ...prev };\n delete next[columnId];\n onColumnSizingPersist?.(next);\n return next;\n });\n },\n [cancelPendingPersist, onColumnSizingPersist],\n );\n\n return { columnSizing, handleColumnSizingChange, handleAutosizeAll, handleAutosizeColumn, handleResetColumnSize };\n}\n","import * as React from 'react';\nimport type { ColumnSizingState, OnChangeFn, RowData, Table } from '@tanstack/react-table';\n\nimport {\n findContentMinColumns,\n getGridColumnTemplate,\n measureMaxContentMins,\n snapshotResizeStart,\n} from '@/lib/data-table/grid-layout';\n\nimport {\n computeGridResizeFrValues,\n resolveGridPersistedFr,\n type GridResizeSnapshotMeta,\n} from './use-table-column-resizing';\nimport type { TableLayout } from '@/data-table/data-table-types';\n\nexport interface UseGridLayoutOptions<TData extends RowData> {\n layout: TableLayout;\n table: Table<TData>;\n /** Scroll container that owns the `[role=\"columnheader\"]` elements measured for resize snapshots. */\n tableBodyScrollRef: React.RefObject<HTMLDivElement | null>;\n displayableColumns: { id: string }[];\n columnOrdering: string[];\n gridMeasuredMins: Record<string, number>;\n setGridMeasuredMins: React.Dispatch<React.SetStateAction<Record<string, number>>>;\n handleColumnSizingChange: OnChangeFn<ColumnSizingState>;\n rawHandleAutosizeAll: () => void;\n rawHandleAutosizeColumn: (columnId: string) => void;\n rawHandleResetColumnSize: (columnId: string) => void;\n}\n\nexport interface UseGridLayoutReturn {\n gridTemplateColumns: string | undefined;\n /** Attach to the grid root `<div role=\"table\">` — the live `--col-fr-*` writer effect reads this directly. */\n gridRootRef: React.RefObject<HTMLDivElement | null>;\n gridVisualColumnOrder: React.RefObject<string[]>;\n gridPersistedFr: React.RefObject<Record<string, number>>;\n gridSnapshotWidths: React.RefObject<Record<string, number>>;\n clearGridFr: (columnId?: string) => void;\n measureContentMins: () => void;\n handleAutosizeAll: () => void;\n handleAutosizeColumn: (columnId: string) => void;\n handleResetColumnSize: (columnId: string) => void;\n}\n\n/**\n * Owns everything `layout=\"grid\"` needs beyond the base column-sizing state:\n * the `gridTemplateColumns` CSS generation, content-min measurement, and the\n * live drag-resize visual feedback. The last of these is a deliberate escape\n * hatch from React's render cycle — `columnResizeMode: 'onEnd'` in grid mode\n * means TanStack's own `columnSizing` state doesn't update until a drag ends,\n * so the only way to show 60fps visual feedback during the drag is to write\n * the `--col-fr-<id>` CSS custom property (which `getGridColumnTemplate`'s\n * `minmax(..., var(--col-fr-<id>, <flex>fr))` tracks already reference)\n * directly via `style.setProperty`, bypassing React state entirely.\n *\n * Deliberate improvement over the legacy source this was ported from: the\n * grid root element is held via `gridRootRef` (a real ref, attached directly\n * to the grid root) instead of re-querying\n * `tableBodyScrollRef.current?.querySelector('[role=\"table\"]')` on every\n * render — a plain `ref` object's `.current` is already kept correctly in\n * sync with whichever DOM node is mounted at that JSX position by React\n * itself, remounts included, so this is a strictly cheaper way to read the\n * same always-current value, not a behavior change.\n */\nexport function useGridLayout<TData extends RowData>({\n layout,\n table,\n tableBodyScrollRef,\n displayableColumns,\n columnOrdering,\n gridMeasuredMins,\n setGridMeasuredMins,\n handleColumnSizingChange,\n rawHandleAutosizeAll,\n rawHandleAutosizeColumn,\n rawHandleResetColumnSize,\n}: UseGridLayoutOptions<TData>): UseGridLayoutReturn {\n const isGrid = layout === 'grid';\n\n const gridRootRef = React.useRef<HTMLDivElement>(null);\n const gridSnapshotWidths = React.useRef<Record<string, number>>({});\n const gridVisualColumnOrder = React.useRef<string[]>([]);\n const gridPersistedFr = React.useRef<Record<string, number>>({});\n const gridSnapshotMeta = React.useRef<GridResizeSnapshotMeta>({\n containerWidth: 0,\n fixedTotal: 0,\n flexIds: [],\n mins: {},\n });\n const prevResizingColumn = React.useRef<string | false>(false);\n const prevResizingForCorrection = React.useRef<string | false>(false);\n\n const clearGridFr = React.useCallback(\n (columnId?: string) => {\n if (!isGrid) return;\n const tableEl = gridRootRef.current;\n if (columnId) {\n delete gridPersistedFr.current[columnId];\n tableEl?.style.removeProperty(`--col-fr-${columnId}`);\n } else {\n for (const colId of Object.keys(gridPersistedFr.current)) {\n tableEl?.style.removeProperty(`--col-fr-${colId}`);\n }\n gridPersistedFr.current = {};\n }\n gridSnapshotWidths.current = {};\n },\n [isGrid],\n );\n\n const headerGroups = table.getHeaderGroups();\n\n // Only ever reads `headerGroups[0]` — correct as long as grouped/nested\n // column headers aren't in use (Monarch doesn't expose that feature today;\n // the auto-mode `totalTableWidth` memo in `data-table.tsx` makes the same\n // assumption). A genuinely multi-level header would need this to\n // reconcile against the leaf row instead — out of scope here.\n //\n // Computes the visual column order alongside the template (not just the\n // template alone) so the companion effect below can sync\n // `gridVisualColumnOrder` without redoing this derivation — a ref can't be\n // written during render, so the write itself happens in that effect.\n const gridTemplate = React.useMemo(() => {\n if (!isGrid) return undefined;\n\n const firstGroup = headerGroups[0];\n if (!firstGroup) return undefined;\n\n const displayableIds = new Set(displayableColumns.map(c => c.id));\n const visibleHeaders = firstGroup.headers.filter(h => displayableIds.has(h.column.id));\n\n return {\n visualOrder: visibleHeaders.map(h => h.column.id),\n template: getGridColumnTemplate({\n headers: visibleHeaders.map(h => ({\n columnId: h.column.id,\n size: h.column.getSize(),\n grid: h.column.columnDef.meta?.grid,\n })),\n gridMeasuredMins,\n }),\n };\n }, [isGrid, headerGroups, displayableColumns, gridMeasuredMins]);\n\n const gridTemplateColumns = gridTemplate?.template;\n\n // Declared before every other effect below so it commits first within the\n // same layout-effect phase — those effects read `gridVisualColumnOrder.current`\n // assuming it already reflects the latest `gridTemplate`.\n React.useLayoutEffect(() => {\n if (gridTemplate) gridVisualColumnOrder.current = gridTemplate.visualOrder;\n }, [gridTemplate]);\n\n const resizingColumn = table.getState().columnSizingInfo.isResizingColumn;\n\n // Snapshot each header's pre-drag width the moment a resize starts — the\n // live drag math (`computeGridResizeFrValues`, below) redistributes space\n // relative to this snapshot, not to the column's ever-changing live size.\n React.useLayoutEffect(() => {\n if (resizingColumn && !prevResizingColumn.current) {\n const headers = tableBodyScrollRef.current?.querySelectorAll('[role=\"columnheader\"]');\n if (headers) {\n const result = snapshotResizeStart({\n headers,\n visualOrder: gridVisualColumnOrder.current,\n getColumnGrid: colId => table.getColumn(colId)?.columnDef.meta?.grid,\n tableEl: gridRootRef.current,\n });\n if (result) {\n Object.assign(gridSnapshotWidths.current, result.widths);\n gridSnapshotMeta.current = result.meta;\n }\n }\n }\n prevResizingColumn.current = resizingColumn || false;\n }, [resizingColumn, table, tableBodyScrollRef]);\n\n const measureContentMins = React.useCallback(() => {\n const tableEl = gridRootRef.current;\n const headers = tableBodyScrollRef.current?.querySelectorAll('[role=\"columnheader\"]');\n const visualOrder = gridVisualColumnOrder.current;\n if (!tableEl || !headers || visualOrder.length !== headers.length) return;\n\n const getColumnGrid = (colId: string) => table.getColumn(colId)?.columnDef.meta?.grid;\n const columnsToMeasure = findContentMinColumns(visualOrder, getColumnGrid);\n if (columnsToMeasure.length === 0) return;\n\n const newMins = measureMaxContentMins(tableEl, headers, visualOrder, columnsToMeasure, getColumnGrid);\n setGridMeasuredMins(prev => {\n const keys = Object.keys(newMins);\n if (keys.length === Object.keys(prev).length && keys.every(k => Math.abs((prev[k] ?? 0) - newMins[k]) < 0.5)) {\n return prev;\n }\n return newMins;\n });\n }, [table, tableBodyScrollRef, setGridMeasuredMins]);\n\n const rowCount = table.getRowCount();\n const tableRows = table.getRowModel().rows;\n const contentMinKey = displayableColumns.map(c => c.id).join(',');\n React.useLayoutEffect(() => {\n if (!isGrid || resizingColumn) return;\n measureContentMins();\n }, [isGrid, resizingColumn, rowCount, contentMinKey, tableRows, measureContentMins]);\n\n React.useEffect(() => {\n if (!isGrid) return;\n const scrollEl = tableBodyScrollRef.current;\n if (!scrollEl) return;\n const observer = new ResizeObserver(() => {\n if (!table.getState().columnSizingInfo.isResizingColumn) {\n measureContentMins();\n }\n });\n observer.observe(scrollEl);\n return () => observer.disconnect();\n }, [isGrid, measureContentMins, table, tableBodyScrollRef]);\n\n // No dependency array — deliberately runs after every render. This is the\n // safety net that keeps `--col-fr-*` alive across anything that could\n // invalidate it (a remount, a key change elsewhere in the tree); narrowing\n // the deps would silently reintroduce that fragility via a missed run\n // instead of a stale DOM query. During an active drag it also writes the\n // live, not-yet-committed `fr` values directly — see the hook doc comment.\n React.useLayoutEffect(() => {\n if (!isGrid) return;\n const tableEl = gridRootRef.current;\n if (!tableEl) return;\n\n const { isResizingColumn, deltaOffset } = table.getState().columnSizingInfo;\n\n if (isResizingColumn && deltaOffset != null) {\n const nextFr = computeGridResizeFrValues({\n resizingColumnId: isResizingColumn,\n deltaOffset,\n visualOrder: gridVisualColumnOrder.current,\n snapshotWidths: gridSnapshotWidths.current,\n snapshotMeta: gridSnapshotMeta.current,\n });\n\n for (const [colId, fr] of Object.entries(nextFr)) {\n tableEl.style.setProperty(`--col-fr-${colId}`, `${fr}fr`);\n gridPersistedFr.current[colId] = fr;\n }\n } else {\n gridPersistedFr.current = resolveGridPersistedFr({\n visualOrder: gridVisualColumnOrder.current,\n persistedFr: gridPersistedFr.current,\n columnSizing: table.getState().columnSizing,\n measuredMins: gridMeasuredMins,\n getGridSizing: colId => {\n const grid = table.getColumn(colId)?.columnDef.meta?.grid;\n return grid && 'flex' in grid ? grid : undefined;\n },\n });\n }\n\n for (const [colId, fr] of Object.entries(gridPersistedFr.current)) {\n tableEl.style.setProperty(`--col-fr-${colId}`, `${fr}fr`);\n }\n });\n\n // Also no dependency array — gated internally by `prevResizingForCorrection`\n // to fire exactly once, on the falling edge of `resizingColumn`. Reconciles\n // the fr-as-px approximation above back into TanStack's real `columnSizing`\n // state once a drag ends, using each column's actual rendered width.\n React.useLayoutEffect(() => {\n const wasResizing = prevResizingForCorrection.current;\n prevResizingForCorrection.current = resizingColumn || false;\n if (!isGrid || resizingColumn || !wasResizing) return;\n\n const headers = tableBodyScrollRef.current?.querySelectorAll('[role=\"columnheader\"]');\n const visualOrder = gridVisualColumnOrder.current;\n if (!headers || visualOrder.length !== headers.length) return;\n\n const corrected: Record<string, number> = {};\n Array.from(headers).forEach((header, idx) => {\n const colId = visualOrder[idx];\n if (!colId) return;\n const grid = table.getColumn(colId)?.columnDef.meta?.grid;\n if (grid && 'flex' in grid && grid.flex != null) {\n corrected[colId] = Math.round(header.getBoundingClientRect().width);\n }\n });\n if (Object.keys(corrected).length > 0) {\n handleColumnSizingChange(prev => ({ ...prev, ...corrected }));\n }\n });\n\n const handleAutosizeAll = React.useCallback(() => {\n clearGridFr();\n rawHandleAutosizeAll();\n }, [clearGridFr, rawHandleAutosizeAll]);\n\n const handleAutosizeColumn = React.useCallback(\n (columnId: string) => {\n clearGridFr(columnId);\n rawHandleAutosizeColumn(columnId);\n },\n [clearGridFr, rawHandleAutosizeColumn],\n );\n\n const handleResetColumnSize = React.useCallback(\n (columnId: string) => {\n clearGridFr(columnId);\n rawHandleResetColumnSize(columnId);\n },\n [clearGridFr, rawHandleResetColumnSize],\n );\n\n const prevColumnOrderingRef = React.useRef(columnOrdering);\n React.useEffect(() => {\n const prev = prevColumnOrderingRef.current;\n prevColumnOrderingRef.current = columnOrdering;\n if (isGrid && prev.length > 0 && prev.join(',') !== columnOrdering.join(',')) {\n gridSnapshotWidths.current = {};\n gridPersistedFr.current = {};\n handleAutosizeAll();\n }\n }, [isGrid, columnOrdering, handleAutosizeAll]);\n\n return {\n gridTemplateColumns,\n gridRootRef,\n gridVisualColumnOrder,\n gridPersistedFr,\n gridSnapshotWidths,\n clearGridFr,\n measureContentMins,\n handleAutosizeAll,\n handleAutosizeColumn,\n handleResetColumnSize,\n };\n}\n","import type { GridResizeSnapshotMeta } from '@/hooks/use-table-column-resizing';\n\nimport type { GridColumnSizing } from './table-meta';\n\nexport type GetColumnGrid = (columnId: string) => GridColumnSizing | undefined;\n\nexport interface GridSnapshotInput {\n headers: NodeListOf<Element>;\n visualOrder: string[];\n getColumnGrid: GetColumnGrid;\n}\n\nexport interface GridResizeSnapshot {\n widths: Record<string, number>;\n fixedTotal: number;\n flexIds: string[];\n mins: Record<string, number>;\n needsMaxContentMeasure: string[];\n}\n\nexport function computeGridResizeSnapshot({\n headers,\n visualOrder,\n getColumnGrid,\n}: GridSnapshotInput): GridResizeSnapshot {\n let fixedTotal = 0;\n const flexIds: string[] = [];\n const mins: Record<string, number> = {};\n const widths: Record<string, number> = {};\n const needsMaxContentMeasure: string[] = [];\n\n Array.from(headers).forEach((header, idx) => {\n const columnId = visualOrder[idx];\n if (!columnId) return;\n const px = header.getBoundingClientRect().width;\n widths[columnId] = px;\n const grid = getColumnGrid(columnId);\n if (grid && 'flex' in grid && grid.flex != null) {\n flexIds.push(columnId);\n const minVal = grid.min;\n if (minVal && minVal !== 'max-content' && minVal !== 'min-content') {\n mins[columnId] = parseFloat(minVal) || 0;\n } else if (minVal === 'max-content' || minVal === 'min-content') {\n needsMaxContentMeasure.push(columnId);\n }\n } else {\n fixedTotal += px;\n }\n });\n\n return { widths, fixedTotal, flexIds, mins, needsMaxContentMeasure };\n}\n\nexport function measureMaxContentMins(\n tableEl: HTMLElement,\n headers: NodeListOf<Element>,\n visualOrder: string[],\n columnsToMeasure: string[],\n getColumnGrid: GetColumnGrid,\n): Record<string, number> {\n const mins: Record<string, number> = {};\n if (columnsToMeasure.length === 0) return mins;\n\n const origTemplate = tableEl.style.gridTemplateColumns;\n tableEl.style.gridTemplateColumns = visualOrder.map(() => 'max-content').join(' ');\n\n Array.from(headers).forEach((header, idx) => {\n const colId = visualOrder[idx];\n if (colId && columnsToMeasure.includes(colId)) {\n let measured = header.getBoundingClientRect().width;\n const grid = getColumnGrid(colId);\n if (grid && 'minCap' in grid && grid.minCap) {\n measured = Math.min(measured, parseFloat(grid.minCap) || measured);\n }\n mins[colId] = measured;\n }\n });\n\n tableEl.style.gridTemplateColumns = origTemplate;\n return mins;\n}\n\nexport interface GridTemplateInput {\n headers: { columnId: string; size: number; grid?: GridColumnSizing }[];\n gridMeasuredMins: Record<string, number>;\n}\n\n/**\n * The live rendered width comes from the `--col-fr-<id>` CSS custom property,\n * not the static `flex` number.\n *\n * A capped flex column (`grid.max` set) does NOT wrap that var in `min()` —\n * `fr` cannot be mixed with a length inside `min()`/`max()`/`clamp()` (they\n * require same-typed arguments), so `min(160px, var(--col-fr-id, 1fr))` is\n * invalid CSS. An invalid track invalidates the *entire*\n * `grid-template-columns` declaration, silently collapsing every column\n * (confirmed in a real browser, not just jsdom string assertions — the\n * legacy source this was ported from has the same construct and was never\n * verified against real Grid layout either). Instead, a capped column's max\n * is the literal `grid.max` value — a fixed ceiling, not itself live-resizable.\n */\nexport function getGridColumnTemplate({ headers, gridMeasuredMins }: GridTemplateInput): string {\n return headers\n .map(h => {\n const { grid } = h;\n if (!grid) return `${h.size}px`;\n if ('fixed' in grid && grid.fixed) return grid.fixed;\n if ('flex' in grid && grid.flex != null) {\n const varName = `--col-fr-${h.columnId}`;\n const measuredMin = gridMeasuredMins[h.columnId];\n const min = measuredMin != null ? `${measuredMin}px` : (grid.min ?? 'auto');\n const max = grid.max ?? `var(${varName}, ${grid.flex}fr)`;\n return `minmax(${min}, ${max})`;\n }\n return `${h.size}px`;\n })\n .join(' ');\n}\n\nexport function findContentMinColumns(visualOrder: string[], getColumnGrid: GetColumnGrid): string[] {\n return visualOrder.filter(colId => {\n const grid = getColumnGrid(colId);\n return grid && 'flex' in grid && grid.flex != null && (grid.min === 'max-content' || grid.min === 'min-content');\n });\n}\n\nexport interface SnapshotResizeStartInput {\n headers: NodeListOf<Element>;\n visualOrder: string[];\n getColumnGrid: GetColumnGrid;\n tableEl: HTMLElement | null;\n}\n\nexport interface SnapshotResizeStartResult {\n widths: Record<string, number>;\n meta: GridResizeSnapshotMeta;\n}\n\nexport function snapshotResizeStart({\n headers,\n visualOrder,\n getColumnGrid,\n tableEl,\n}: SnapshotResizeStartInput): SnapshotResizeStartResult | null {\n if (!headers || visualOrder.length !== headers.length) return null;\n\n const snapshot = computeGridResizeSnapshot({ headers, visualOrder, getColumnGrid });\n\n if (tableEl && snapshot.needsMaxContentMeasure.length > 0) {\n const measuredMins = measureMaxContentMins(\n tableEl,\n headers,\n visualOrder,\n snapshot.needsMaxContentMeasure,\n getColumnGrid,\n );\n Object.assign(snapshot.mins, measuredMins);\n }\n\n const containerWidth = tableEl?.getBoundingClientRect().width ?? 0;\n\n return {\n widths: snapshot.widths,\n meta: {\n containerWidth,\n fixedTotal: snapshot.fixedTotal,\n flexIds: snapshot.flexIds,\n mins: snapshot.mins,\n },\n };\n}\n","import * as React from 'react';\n\nimport type { DataTableFilterVisibilityConfig } from '@/data-table/data-table-types';\n\nexport interface UseFilterVisibilityReturn {\n /** Whether the Filter toggle button should render at all (renders unless the prop is `false`). */\n showFilterToggle: boolean;\n /** Resolved visible/hidden state of the filter row. */\n filterRowVisible: boolean;\n setFilterRowVisible: (visible: boolean) => void;\n}\n\nexport function useFilterVisibility(\n filterVisibility: boolean | DataTableFilterVisibilityConfig | undefined,\n): UseFilterVisibilityReturn {\n const config = typeof filterVisibility === 'object' ? filterVisibility : undefined;\n const [innerVisible, setInnerVisible] = React.useState(config?.defaultVisible ?? false);\n\n const showFilterToggle = filterVisibility !== false;\n const filterRowVisible = config?.visible ?? innerVisible;\n const setFilterRowVisible = config?.onVisibleChange ?? setInnerVisible;\n\n return { showFilterToggle, filterRowVisible, setFilterRowVisible };\n}\n","'use client';\n\nimport type * as React from 'react';\n\nimport { Alert, AlertDescription } from '@upbound/monarch-core';\nimport { Button } from '@upbound/monarch-core';\nimport { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from '@upbound/monarch-core';\nimport { Icon } from '@upbound/monarch-core';\nimport { IconTile } from '@upbound/monarch-core';\nimport type { IconName } from '@upbound/monarch-core';\nimport { cn } from '@/lib/utils';\nimport type { TableDataState } from '@/lib/data-table/utils';\n\n/**\n * Monarch-native equivalent of TableWrapper's `EmptyConfig` — same four\n * states (error / empty / filtered-empty), rebuilt on Monarch's `Empty`\n * compound API instead of a single props-driven component. Two deliberate\n * adaptations: `icon` takes a Monarch `IconName` (no FontAwesome dependency),\n * and `action` is a rendered node rather than a `ComponentType` reference.\n * `details` has no native `Empty` slot — it composes `Alert` instead.\n */\nexport type DataTableEmptyConfig = {\n icon?: IconName;\n header?: React.ReactNode;\n subheader?: React.ReactNode;\n details?: React.ReactNode;\n action?: React.ReactNode;\n className?: string;\n wrapperClassName?: string;\n};\n\nexport type DataTableEmptyView = {\n empty?: DataTableEmptyConfig;\n error?: DataTableEmptyConfig;\n filter?: DataTableEmptyConfig;\n};\n\nexport const defaultErrorConfig: DataTableEmptyConfig = {\n icon: 'circle-exclamation',\n header: 'Something went wrong',\n subheader: \"We couldn't load this data. Try again in a moment.\",\n};\n\nexport const defaultEmptyConfig: DataTableEmptyConfig = {\n icon: 'inbox',\n header: 'No results',\n subheader: \"There's nothing here yet.\",\n};\n\nexport const defaultNoFilterFoundConfig: DataTableEmptyConfig = {\n icon: 'magnifying-glass',\n header: 'No matching results',\n subheader: 'Try adjusting your search or filters.',\n};\n\nexport function DataTableEmptyView({\n emptyView,\n tableState,\n filterCount,\n resetFilters,\n className,\n}: {\n emptyView?: DataTableEmptyView;\n /** `'success'`/`'loading'` render nothing here — the table body handles those. */\n tableState: TableDataState;\n filterCount: number;\n resetFilters: () => void;\n className?: string;\n}) {\n const isFilteredEmpty = tableState === 'empty' && filterCount > 0;\n const config =\n tableState === 'error'\n ? (emptyView?.error ?? defaultErrorConfig)\n : tableState === 'empty'\n ? isFilteredEmpty\n ? (emptyView?.filter ?? defaultNoFilterFoundConfig)\n : (emptyView?.empty ?? defaultEmptyConfig)\n : null;\n\n // Mirrors a quirk in the source: an error config without its own\n // `wrapperClassName` falls back to the *empty* config's, not its own type's default.\n const wrapperClassName =\n tableState === 'error'\n ? (emptyView?.error?.wrapperClassName ?? emptyView?.empty?.wrapperClassName)\n : config?.wrapperClassName;\n\n const defaultAction =\n isFilteredEmpty && !config?.action ? (\n <Button variant=\"outline\" size=\"sm\" onClick={resetFilters}>\n <Icon name=\"xmark\" />\n Clear filters\n </Button>\n ) : null;\n\n return (\n <div className={cn('flex size-full flex-col justify-center p-6', wrapperClassName, className)}>\n {config && (\n // The error state ignores its own config's `className` for outer\n // padding, matching the source's forced `pt-0` on that branch.\n <Empty className={tableState === 'error' ? 'pt-0' : config.className}>\n <EmptyHeader>\n {config.icon && (\n <EmptyMedia>\n <IconTile variant=\"branded\">\n <Icon name={config.icon} />\n </IconTile>\n </EmptyMedia>\n )}\n {config.header && <EmptyTitle>{config.header}</EmptyTitle>}\n {config.subheader && <EmptyDescription>{config.subheader}</EmptyDescription>}\n </EmptyHeader>\n {(config.details || config.action || defaultAction) && (\n <EmptyContent>\n {config.details && (\n <Alert>\n <AlertDescription>{config.details}</AlertDescription>\n </Alert>\n )}\n {config.action ?? defaultAction}\n </EmptyContent>\n )}\n </Empty>\n )}\n </div>\n );\n}\n","'use client';\n\nimport { Icon, Toggle } from '@upbound/monarch-core';\n\nexport type FilterToggleProps = {\n /** Whether the filter row is currently visible. */\n pressed: boolean;\n onPressedChange: (pressed: boolean) => void;\n /** Active filter count shown as `(count)`. Omitted when `0` or `undefined`. */\n count?: number;\n};\n\nexport function FilterToggle({ pressed, onPressedChange, count }: FilterToggleProps) {\n return (\n <Toggle\n variant=\"outline\"\n pressed={pressed}\n onPressedChange={onPressedChange}\n aria-label=\"Toggle filters\"\n className=\"shrink-0 gap-1.5\"\n >\n <Icon name=\"filter\" data-icon=\"inline-start\" />\n Filter\n {!!count && <span className=\"tabular-nums\">({count})</span>}\n </Toggle>\n );\n}\n","'use client';\n\nimport { Button } from '@upbound/monarch-core';\nimport { Icon } from '@upbound/monarch-core';\nimport { Label } from '@upbound/monarch-core';\nimport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n} from '@upbound/monarch-core';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@upbound/monarch-core';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@upbound/monarch-core';\nimport { getPaginationInfo } from '@/lib/data-table/utils';\nimport { useMounted } from '@/hooks/use-mounted';\n\nexport type RowCountRelation = 'eq' | 'gt';\n\n/** Pass `true` for defaults, `false` to disable the footer entirely (handled by the caller, not this component), or an object to toggle individual parts. */\nexport type DataTablePaginationConfig =\n | boolean\n | {\n /** Shows \"Showing 1 to 20 of 25 results\". @default true */\n summary?: boolean;\n /** Shows the first/previous/next/last icon buttons. @default true */\n arrows?: boolean;\n /** Shows numeric page buttons alongside the arrows. @default false */\n numbers?: boolean;\n /** Shows the rows-per-page selector. @default true */\n pageSizeSelector?: boolean;\n /** Options offered in the rows-per-page selector. @default [10, 20, 30, 40, 50, 60, 70, 80, 90, 100] */\n pageSizeOptions?: number[];\n };\n\nconst DEFAULT_PAGINATION_CONFIG = {\n summary: true,\n arrows: true,\n numbers: false,\n pageSizeSelector: true,\n pageSizeOptions: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100],\n};\nconst PAGE_SIZE_SELECT_ID = 'table-page-size-select';\n\nfunction getPageSizeOptions(pageSizeOptions: number[]): number[] {\n return Array.from(new Set(pageSizeOptions))\n .filter(option => option > 0)\n .sort((a, b) => a - b);\n}\n\nfunction getEffectivePageSize(pageSize: number, pageSizeOptions: number[]): number {\n if (pageSizeOptions.length === 0 || pageSizeOptions.includes(pageSize)) return pageSize;\n return pageSizeOptions.reduce(\n (closest, option) => (Math.abs(option - pageSize) < Math.abs(closest - pageSize) ? option : closest),\n pageSizeOptions[0],\n );\n}\n\n/** Dedupes/sorts `pageSizeOptions`, and snaps `pageSize` to the nearest option when it isn't one (ties go to the lower value). */\nexport function normalizePageSizeOptions(pageSize: number, pageSizeOptions: number[]) {\n const normalizedPageSizeOptions = getPageSizeOptions(pageSizeOptions);\n return { normalizedPageSizeOptions, effectivePageSize: getEffectivePageSize(pageSize, normalizedPageSizeOptions) };\n}\n\nexport type DataTablePaginationProps = {\n pageIndex: number;\n pageSize: number;\n rowCount: number;\n /** `'gt'` renders \"N+ results\" with an explanatory tooltip, for an inexact/server-estimated count. @default 'eq' */\n rowCountRelation?: RowCountRelation;\n paginationConfig?: DataTablePaginationConfig;\n /** Called with the 1-based page number the user navigated to. */\n onPageChange: (page: number) => void;\n onPageSizeChange: (pageSize: number) => void;\n};\n\nexport function DataTablePagination({\n pageIndex,\n pageSize,\n rowCount,\n rowCountRelation = 'eq',\n paginationConfig = true,\n onPageChange,\n onPageSizeChange,\n}: DataTablePaginationProps) {\n const isRowCountExact = rowCountRelation === 'eq';\n const resolved =\n typeof paginationConfig === 'object'\n ? { ...DEFAULT_PAGINATION_CONFIG, ...paginationConfig }\n : DEFAULT_PAGINATION_CONFIG;\n\n const { normalizedPageSizeOptions, effectivePageSize } = normalizePageSizeOptions(pageSize, resolved.pageSizeOptions);\n const { visiblePages, pageCount, itemStart, itemEnd } = getPaginationInfo(pageIndex, rowCount, effectivePageSize);\n const currentPage = pageIndex + 1;\n const mounted = useMounted();\n // Fixed locale for the server-rendered/first-paint value (the server can't\n // know the viewer's locale); the viewer's actual locale once mounted — per\n // Monarch's \"use locale-aware formatting\" content principle for counts.\n const locale = mounted ? undefined : 'en-US';\n\n return (\n <div data-testid=\"table-footer\" className=\"flex items-center justify-between px-2 pt-4\">\n {resolved.summary ? (\n <div className=\"text-body text-muted-foreground\" data-testid=\"table-pagination-summary\">\n Showing <span className=\"text-foreground font-medium\">{itemStart.toLocaleString(locale)}</span> to{' '}\n <span className=\"text-foreground font-medium\">{itemEnd.toLocaleString(locale)}</span> of{' '}\n <span className=\"text-foreground font-medium\">\n {rowCount.toLocaleString(locale)}\n {!isRowCountExact && '+'}\n </span>{' '}\n results\n {!isRowCountExact && (\n <Tooltip>\n <TooltipTrigger className=\"ml-1 align-middle\">\n <Icon name=\"circle-info\" size=\"sm\" />\n </TooltipTrigger>\n <TooltipContent>Add filters or refine your search to reduce the result set.</TooltipContent>\n </Tooltip>\n )}\n </div>\n ) : (\n <div />\n )}\n\n <div className=\"flex items-center gap-4\">\n {resolved.pageSizeSelector && (\n <div className=\"flex items-center gap-2\">\n <Label htmlFor={PAGE_SIZE_SELECT_ID} className=\"font-semibold\">\n Rows per page\n </Label>\n <Select value={String(effectivePageSize)} onValueChange={value => onPageSizeChange(Number(value))}>\n <SelectTrigger id={PAGE_SIZE_SELECT_ID} size=\"sm\" className=\"w-18\" data-testid=\"table-page-size-select\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent align=\"end\">\n <SelectGroup>\n {normalizedPageSizeOptions.map(option => (\n <SelectItem key={option} value={String(option)}>\n {option}\n </SelectItem>\n ))}\n </SelectGroup>\n </SelectContent>\n </Select>\n </div>\n )}\n\n {pageCount > 1 && (resolved.arrows || resolved.numbers) && (\n <Pagination className=\"mx-0 w-auto justify-end\">\n <PaginationContent>\n {resolved.arrows && (\n <PaginationItem>\n <Button\n variant=\"outline\"\n size=\"icon\"\n aria-label=\"Go to first page\"\n disabled={currentPage <= 1}\n onClick={() => onPageChange(1)}\n >\n <Icon name=\"chevrons-left\" className=\"cn-rtl-flip\" />\n </Button>\n </PaginationItem>\n )}\n {resolved.arrows && (\n <PaginationItem>\n <Button\n variant=\"outline\"\n size=\"icon\"\n aria-label=\"Go to previous page\"\n disabled={currentPage <= 1}\n onClick={() => onPageChange(currentPage - 1)}\n >\n <Icon name=\"chevron-left\" className=\"cn-rtl-flip\" />\n </Button>\n </PaginationItem>\n )}\n {resolved.numbers &&\n visiblePages.map((page, index) =>\n page === undefined ? (\n <PaginationItem key={`ellipsis-${index}`}>\n <PaginationEllipsis />\n </PaginationItem>\n ) : (\n <PaginationItem key={page}>\n <PaginationLink\n href=\"#\"\n size=\"icon\"\n isActive={page === currentPage}\n onClick={(e: React.MouseEvent) => {\n e.preventDefault();\n onPageChange(page);\n }}\n >\n {page}\n </PaginationLink>\n </PaginationItem>\n ),\n )}\n {resolved.arrows && (\n <PaginationItem>\n <Button\n variant=\"outline\"\n size=\"icon\"\n aria-label=\"Go to next page\"\n disabled={currentPage >= pageCount}\n onClick={() => onPageChange(currentPage + 1)}\n >\n <Icon name=\"chevron-right\" className=\"cn-rtl-flip\" />\n </Button>\n </PaginationItem>\n )}\n {resolved.arrows && (\n <PaginationItem>\n <Button\n variant=\"outline\"\n size=\"icon\"\n aria-label=\"Go to last page\"\n disabled={currentPage >= pageCount}\n onClick={() => onPageChange(pageCount)}\n >\n <Icon name=\"chevrons-right\" className=\"cn-rtl-flip\" />\n </Button>\n </PaginationItem>\n )}\n </PaginationContent>\n </Pagination>\n )}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport {\n flexRender,\n type Cell,\n type Column,\n type ColumnFilter,\n type Header,\n type HeaderGroup,\n type Row,\n type RowData,\n type SortDirection,\n} from '@tanstack/react-table';\n\nimport { ContextMenu, ContextMenuTrigger } from '@upbound/monarch-core';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@upbound/monarch-core';\nimport { Icon } from '@upbound/monarch-core';\nimport { Skeleton } from '@upbound/monarch-core';\nimport {\n Table as BaseTable,\n TableBody as BaseTableBody,\n TableCell as BaseTableCell,\n TableHead as BaseTableHead,\n TableHeader as BaseTableHeader,\n TableRow as BaseTableRow,\n} from '@upbound/monarch-core';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@upbound/monarch-core';\nimport { cn } from '@/lib/utils';\nimport { getContextualColumnFilter, getContextualGlobalSearch } from '@/lib/data-table/contextual-filters';\nimport { isFilterOnlyColumn, type TableDataState } from '@/lib/data-table/utils';\nimport type { StickyHeaderConfig, TableLayout } from './data-table-types';\nimport { CellContextualFilter, type ContextualMenuAction } from './cell-contextual-filter';\n\n// ── Column pinning ─────────────────────────────────────\n\n/** Matches `TableHeader`'s own background (table.tsx) — pinned/sticky header cells need this instead of `bg-card` so they don't stand out as a different (white) shade from the rest of the grey header row. */\nconst HEADER_SURFACE_BG = 'bg-[color-mix(in_oklch,var(--muted)_50%,var(--card))]';\n\n/**\n * Grid mode (`layout=\"grid\"`) renders `<div role=\"...\">` markup instead of\n * `<table>/<thead>/<tbody>/<tr>/<th>/<td>`, so it can't reuse those elements'\n * own visual classes from `table.tsx`. These mirror them exactly — keep in\n * sync with `TableHead`/`TableCell`/`TableRow` in `table.tsx` (`@upbound/monarch-core`).\n */\nconst TABLE_HEAD_CLASSES =\n 'text-body-sm text-muted-foreground h-10 px-4 text-left align-middle font-medium whitespace-nowrap has-[[role=checkbox]]:pr-0';\nconst TABLE_CELL_CLASSES = 'px-4 py-2 align-middle whitespace-nowrap has-[[role=checkbox]]:pr-0';\nconst TABLE_ROW_CLASSES =\n 'hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted border-b motion-safe:transition-colors';\n\n/**\n * Renders the table root: `<Table>` (a native `<table>`) for `layout=\"auto\"`,\n * or a `<div role=\"table\">` grid container for `layout=\"grid\"` — the only\n * element with an actual `display:grid` + `grid-template-columns`. Every\n * nested rowgroup/row adopts these tracks via `grid-cols-subgrid` instead of\n * recomputing its own column widths.\n */\nexport function DataTableRoot({\n layout = 'auto',\n gridTemplateColumns,\n gridRootRef,\n className,\n style,\n children,\n}: {\n layout?: TableLayout;\n gridTemplateColumns?: string;\n /** Grid mode only — the live drag-resize CSS-var writer reads this ref directly. */\n gridRootRef?: React.RefObject<HTMLDivElement | null>;\n className?: string;\n style?: React.CSSProperties;\n children: React.ReactNode;\n}) {\n if (layout === 'grid') {\n return (\n <div\n ref={gridRootRef}\n role=\"table\"\n className={cn('text-body grid w-full', className)}\n style={{ ...style, gridTemplateColumns }}\n >\n {children}\n </div>\n );\n }\n return (\n <BaseTable className={className} style={style}>\n {children}\n </BaseTable>\n );\n}\n\n/** Sticky positioning + edge-border classes for a pinned column cell (header or body), either side. */\nfunction getColumnPinningProps<TData extends RowData, TValue>(\n column: Column<TData, TValue>,\n surface: 'header' | 'body' = 'body',\n): { className: string; style: React.CSSProperties } {\n const isPinned = column.getIsPinned();\n if (!isPinned) return { className: '', style: {} };\n\n const isLastLeft = isPinned === 'left' && column.getIsLastColumn('left');\n const isFirstRight = isPinned === 'right' && column.getIsFirstColumn('right');\n\n return {\n className: cn(\n 'sticky',\n surface === 'header' ? HEADER_SURFACE_BG : 'bg-card',\n isLastLeft && 'border-r-2 border-r-border',\n isFirstRight && 'border-l-2 border-l-border',\n ),\n style: {\n left: isPinned === 'left' ? `${column.getStart('left')}px` : undefined,\n right: isPinned === 'right' ? `${column.getAfter('right')}px` : undefined,\n width: column.getSize(),\n },\n };\n}\n\n// ── Sort indicator ──────────────────────────────────────\n\nfunction DataTableSortIcon({ sortOrder }: { sortOrder: SortDirection | false }) {\n if (!sortOrder) return null;\n return (\n <Icon\n name={sortOrder === 'asc' ? 'arrow-up' : 'arrow-down'}\n size=\"xs\"\n className=\"text-primary group-hover/col-actions:text-foreground group-data-[state=open]/col-actions:text-foreground mr-0.5 shrink-0\"\n />\n );\n}\n\n// ── Column actions dropdown ─────────────────────────────\n// The dropdown's trigger is the whole header label (name + sort icon +\n// ellipsis) — see `HeaderCellContent` — so this only builds the menu content.\n\nfunction ColumnActionsMenuItems<TData extends RowData, TValue>({\n header,\n onAutosizeAll,\n onAutosizeColumn,\n layout = 'auto',\n}: {\n header: Header<TData, TValue>;\n onAutosizeAll: () => void;\n onAutosizeColumn: (columnId: string) => void;\n layout?: TableLayout;\n}) {\n const isGrid = layout === 'grid';\n const canSort = header.column.getCanSort();\n const canResize = header.column.getCanResize();\n const canHide = header.column.getCanHide();\n const canPin = !isGrid && header.column.getCanPin();\n\n return (\n <DropdownMenuContent align=\"start\" className=\"w-45\">\n {canSort && (\n <>\n <DropdownMenuItem\n disabled={header.column.getIsSorted() === 'asc'}\n onClick={() => header.column.toggleSorting(false)}\n >\n <Icon name=\"arrow-up\" />\n Sort ascending\n </DropdownMenuItem>\n <DropdownMenuItem\n disabled={header.column.getIsSorted() === 'desc'}\n onClick={() => header.column.toggleSorting(true)}\n >\n <Icon name=\"arrow-down\" />\n Sort descending\n </DropdownMenuItem>\n {!!header.column.getIsSorted() && (\n <DropdownMenuItem onClick={() => header.column.clearSorting()}>\n <Icon name=\"xmark\" />\n Remove sorting\n </DropdownMenuItem>\n )}\n </>\n )}\n\n {canResize && (\n <>\n {canSort && <DropdownMenuSeparator />}\n {!isGrid && (\n <DropdownMenuItem onClick={() => onAutosizeColumn(header.column.id)}>\n <Icon name=\"arrows-left-right\" />\n Autosize column\n </DropdownMenuItem>\n )}\n <DropdownMenuItem onClick={() => onAutosizeAll()}>\n <Icon name=\"table-columns\" />\n {isGrid ? 'Reset all columns' : 'Autosize all columns'}\n </DropdownMenuItem>\n </>\n )}\n\n {(canHide || canPin) && (\n <>\n {(canSort || canResize) && <DropdownMenuSeparator />}\n {canHide && (\n <DropdownMenuItem onClick={() => header.column.toggleVisibility()}>\n <Icon name=\"eye-slash\" />\n Hide column\n </DropdownMenuItem>\n )}\n {canPin &&\n (header.column.getIsPinned() ? (\n <DropdownMenuItem onClick={() => header.column.pin(false)}>\n <Icon name=\"thumbtack\" />\n Unpin column\n </DropdownMenuItem>\n ) : (\n <DropdownMenuItem onClick={() => header.column.pin('left')}>\n <Icon name=\"thumbtack\" />\n Pin column\n </DropdownMenuItem>\n ))}\n </>\n )}\n </DropdownMenuContent>\n );\n}\n\n// ── Header cell content ─────────────────────────────────\n\nfunction HeaderCellContent<TData extends RowData, TValue>({\n header,\n canResize,\n isActionColumn,\n isGroupedColumn,\n shouldShowActionsMenu,\n onAutosizeAll,\n onAutosizeColumn,\n onResetColumnSize,\n layout = 'auto',\n}: {\n header: Header<TData, TValue>;\n canResize: boolean;\n isActionColumn: boolean;\n isGroupedColumn: boolean;\n shouldShowActionsMenu: boolean;\n onAutosizeAll: () => void;\n onAutosizeColumn: (columnId: string) => void;\n onResetColumnSize: (columnId: string) => void;\n layout?: TableLayout;\n}) {\n const resizeHandler = header.getResizeHandler();\n const headerTitle = typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : '';\n const sorted = header.column.getIsSorted();\n\n // One trigger for the whole label — name, sort icon, and the ellipsis all\n // live inside it, in that order, so the ellipsis always sits immediately\n // next to whichever of the two (sort icon, else name) renders last. The\n // named group (`col-actions`) is scoped to this button specifically, so it\n // doesn't fight the header cell's own (unnamed) `group` that drives the\n // resize handle's hover reveal.\n const labelButton = (\n <button\n type=\"button\"\n aria-label={\n shouldShowActionsMenu ? (headerTitle ? `${headerTitle} column actions` : 'Column actions') : undefined\n }\n className={cn(\n 'group/col-actions text-muted-foreground -mx-2 -my-1 flex min-w-0 items-center gap-1 truncate rounded-md px-2 py-1 text-left font-medium motion-safe:transition-colors',\n sorted && 'text-primary',\n shouldShowActionsMenu\n ? 'hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 cursor-pointer'\n : 'cursor-default',\n )}\n >\n <DataTableSortIcon sortOrder={sorted} />\n <span className=\"min-w-0 truncate\">{flexRender(header.column.columnDef.header, header.getContext())}</span>\n\n {shouldShowActionsMenu && (\n <Icon\n size=\"sm\"\n name=\"ellipsis\"\n className=\"ml-1 shrink-0 opacity-0 transition-none group-hover/col-actions:opacity-100 group-focus-visible/col-actions:opacity-100 group-data-[state=open]/col-actions:opacity-100\"\n />\n )}\n </button>\n );\n\n const label = shouldShowActionsMenu ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>{labelButton}</DropdownMenuTrigger>\n <ColumnActionsMenuItems\n header={header}\n onAutosizeAll={onAutosizeAll}\n onAutosizeColumn={onAutosizeColumn}\n layout={layout}\n />\n </DropdownMenu>\n ) : (\n labelButton\n );\n\n return (\n <>\n <div className=\"flex min-w-0 flex-1 items-center gap-1\">\n <div className=\"min-w-0 flex-1\">\n {!isActionColumn &&\n !isGroupedColumn &&\n (headerTitle ? (\n <Tooltip>\n <TooltipTrigger asChild>{label}</TooltipTrigger>\n <TooltipContent>{headerTitle}</TooltipContent>\n </Tooltip>\n ) : (\n label\n ))}\n </div>\n </div>\n\n {canResize && (\n <button\n type=\"button\"\n aria-label=\"Resize column\"\n className=\"hover:border-primary absolute top-0 right-0 z-10 h-full w-2 cursor-col-resize border-r border-transparent opacity-0 group-hover:opacity-100 hover:opacity-100 motion-safe:transition-opacity\"\n onMouseDown={resizeHandler}\n onDoubleClick={e => {\n e.preventDefault();\n onResetColumnSize(header.column.id);\n }}\n />\n )}\n </>\n );\n}\n\n// ── Header ───────────────────────────────────────────────\n\nconst DEFAULT_STICKY_HEADER_OFFSET_PX = 0;\nconst DEFAULT_STICKY_HEADER_ROW_HEIGHT_PX = 40;\n\nexport function DataTableHeader<TData extends RowData>({\n headerGroups,\n onAutosizeAll,\n onAutosizeColumn,\n onResetColumnSize,\n stickyHeader,\n layout = 'auto',\n}: {\n headerGroups: HeaderGroup<TData>[];\n onAutosizeAll: () => void;\n onAutosizeColumn: (columnId: string) => void;\n /** Called when the user double-clicks the resize separator to reset a column to its default size. */\n onResetColumnSize: (columnId: string) => void;\n stickyHeader?: StickyHeaderConfig;\n layout?: TableLayout;\n}) {\n const isGrid = layout === 'grid';\n const stickyHeaderOffset =\n typeof stickyHeader === 'object'\n ? (stickyHeader?.offset ?? DEFAULT_STICKY_HEADER_OFFSET_PX)\n : DEFAULT_STICKY_HEADER_OFFSET_PX;\n const stickyHeaderRowHeight =\n typeof stickyHeader === 'object'\n ? (stickyHeader?.rowHeight ?? DEFAULT_STICKY_HEADER_ROW_HEIGHT_PX)\n : DEFAULT_STICKY_HEADER_ROW_HEIGHT_PX;\n\n const renderHeaders = (headerGroup: HeaderGroup<TData>, headerGroupIndex: number) => {\n const visibleHeaders = headerGroup.headers.filter(header => !isFilterOnlyColumn(header.column));\n\n return visibleHeaders.map((header, headerIndex) => {\n const meta = header.column.columnDef.meta;\n const isActionColumn = !!meta?.actions;\n const isGroupedColumn = header.column.getIsGrouped();\n const canSort = header.column.getCanSort();\n // Grid mode's last column has no right-side flex neighbor to absorb a\n // resize into (`computeGridResizeFrValues` prefers the right side) —\n // dragging it would try to grow the grid past its container.\n const isLastColumn = isGrid && headerIndex === visibleHeaders.length - 1;\n const canResize = header.column.getCanResize() && !isLastColumn;\n const canHide = header.column.getCanHide();\n const canPin = !isGrid && header.column.getCanPin();\n const shouldShowActionsMenu = !isGroupedColumn && !isActionColumn && (canSort || canResize || canHide || canPin);\n const stickyTopPx = stickyHeader ? stickyHeaderOffset + headerGroupIndex * stickyHeaderRowHeight : undefined;\n const isPinned = !isGrid && header.column.getIsPinned();\n const pinning = isGrid ? { className: '', style: {} } : getColumnPinningProps(header.column, 'header');\n\n const content = (\n <HeaderCellContent\n header={header}\n canResize={canResize}\n isActionColumn={isActionColumn}\n isGroupedColumn={isGroupedColumn}\n shouldShowActionsMenu={shouldShowActionsMenu}\n onAutosizeAll={onAutosizeAll}\n onAutosizeColumn={onAutosizeColumn}\n onResetColumnSize={onResetColumnSize}\n layout={layout}\n />\n );\n\n const cellClassName = cn(\n 'group relative overflow-visible text-left',\n !!stickyHeader && cn(HEADER_SURFACE_BG, 'sticky z-20'),\n pinning.className,\n isPinned && 'z-30',\n );\n\n if (isGrid) {\n return (\n <div\n key={header.id}\n role=\"columnheader\"\n className={cn(TABLE_HEAD_CLASSES, cellClassName, 'flex items-center whitespace-normal')}\n style={{\n minWidth: header.column.columnDef.minSize,\n ...(stickyTopPx !== undefined ? { top: stickyTopPx } : {}),\n }}\n >\n {content}\n </div>\n );\n }\n\n return (\n <BaseTableHead\n key={header.id}\n className={cn(cellClassName, 'whitespace-normal')}\n style={{\n ...pinning.style,\n minWidth: header.column.columnDef.minSize,\n maxWidth: header.column.columnDef.maxSize,\n ...(!isPinned ? { width: header.column.getSize() } : {}),\n ...(stickyTopPx !== undefined ? { top: stickyTopPx } : {}),\n }}\n >\n {content}\n </BaseTableHead>\n );\n });\n };\n\n if (isGrid) {\n return (\n <div\n role=\"rowgroup\"\n className={cn('col-span-full grid grid-cols-subgrid', HEADER_SURFACE_BG, !!stickyHeader && 'sticky z-20')}\n style={stickyHeader ? { top: stickyHeaderOffset } : undefined}\n >\n {headerGroups.map((headerGroup, headerGroupIndex) => (\n <div key={headerGroup.id} role=\"row\" className=\"col-span-full grid grid-cols-subgrid border-b\">\n {renderHeaders(headerGroup, headerGroupIndex)}\n </div>\n ))}\n </div>\n );\n }\n\n return (\n <BaseTableHeader>\n {headerGroups.map((headerGroup, headerGroupIndex) => (\n <BaseTableRow key={headerGroup.id}>{renderHeaders(headerGroup, headerGroupIndex)}</BaseTableRow>\n ))}\n </BaseTableHeader>\n );\n}\n\n// ── Row ──────────────────────────────────────────────────\n\nexport type DataTableRowProps = React.HTMLAttributes<HTMLElement> & {\n hoverable?: boolean;\n disabled?: boolean;\n layout?: TableLayout;\n};\n\nexport const DataTableRow = React.forwardRef<HTMLElement, DataTableRowProps>(\n ({ hoverable, disabled, className, layout = 'auto', ...props }, ref) => {\n const classes = cn(\n 'break-all',\n hoverable && 'cursor-pointer',\n disabled && 'cursor-not-allowed opacity-80',\n className,\n );\n\n if (layout === 'grid') {\n return (\n <div\n ref={ref as React.Ref<HTMLDivElement>}\n role=\"row\"\n className={cn(TABLE_ROW_CLASSES, 'col-span-full grid grid-cols-subgrid', classes)}\n {...props}\n />\n );\n }\n\n return <BaseTableRow ref={ref as React.Ref<HTMLTableRowElement>} className={classes} {...props} />;\n },\n);\nDataTableRow.displayName = 'DataTableRow';\n\n// ── Cell ─────────────────────────────────────────────────\n\nexport function DataTableCell<TData extends RowData, TValue>({\n cell,\n className,\n showContextualFilter,\n onContextCell,\n onContextSearch,\n contextualMenuActions,\n layout = 'auto',\n}: {\n cell: Cell<TData, TValue>;\n className?: string;\n showContextualFilter?: boolean;\n onContextCell?: (filter: ColumnFilter, cell: Cell<TData, TValue>) => void;\n onContextSearch?: (searchTerm: string, cell: Cell<TData, TValue>) => void;\n contextualMenuActions?: ContextualMenuAction<TData, TValue>[];\n layout?: TableLayout;\n}) {\n const isGrid = layout === 'grid';\n const meta = cell.column.columnDef.meta;\n const isActions = !!meta?.actions;\n const shouldTruncate = !isActions;\n const isPinned = !isGrid && cell.column.getIsPinned();\n const pinning = isGrid ? { className: '', style: {} } : getColumnPinningProps(cell.column);\n const shouldShowContextualMenu = !!showContextualFilter && !!onContextCell && !isActions;\n const contextualGlobalSearch = shouldShowContextualMenu ? getContextualGlobalSearch(cell) : undefined;\n const contextualFilter = shouldShowContextualMenu ? getContextualColumnFilter(cell) : undefined;\n const content = flexRender(cell.column.columnDef.cell, cell.getContext());\n\n const cellClassName = cn(\n isActions && 'text-right',\n shouldTruncate && 'overflow-hidden text-ellipsis whitespace-nowrap',\n isGrid && 'flex items-center',\n pinning.className,\n isPinned && 'z-10',\n className,\n );\n\n const cellElement = isGrid ? (\n <div\n role=\"cell\"\n className={cn(TABLE_CELL_CLASSES, cellClassName)}\n style={{ minWidth: cell.column.columnDef.minSize }}\n >\n {content}\n </div>\n ) : (\n <BaseTableCell\n className={cellClassName}\n style={{\n ...pinning.style,\n ...(!isPinned ? { width: cell.column.getSize() } : {}),\n minWidth: cell.column.columnDef.minSize,\n maxWidth: cell.column.columnDef.maxSize,\n }}\n >\n {content}\n </BaseTableCell>\n );\n\n if (!shouldShowContextualMenu || !onContextCell) return cellElement;\n\n return (\n <ContextMenu>\n <ContextMenuTrigger asChild>{cellElement}</ContextMenuTrigger>\n <CellContextualFilter\n filter={contextualFilter}\n globalSearch={contextualGlobalSearch}\n cell={cell}\n onContextCell={onContextCell}\n onContextSearch={onContextSearch}\n contextualMenuActions={contextualMenuActions}\n />\n </ContextMenu>\n );\n}\n\n// ── Group row ────────────────────────────────────────────\n\nexport function DataTableGroupRow({\n groupLabel,\n colSpan,\n layout = 'auto',\n}: {\n groupLabel: string;\n colSpan: number;\n layout?: TableLayout;\n}) {\n if (layout === 'grid') {\n return (\n <div role=\"row\" className=\"bg-muted/50 hover:bg-muted/50 col-span-full grid grid-cols-subgrid\">\n <div\n role=\"cell\"\n style={{ gridColumn: `span ${colSpan}` }}\n className=\"text-foreground border-b px-4 py-2 font-semibold whitespace-nowrap\"\n >\n {groupLabel}\n </div>\n </div>\n );\n }\n return (\n <BaseTableRow className=\"bg-muted/50 hover:bg-muted/50\">\n <BaseTableCell colSpan={colSpan} className=\"text-foreground border-b font-semibold whitespace-nowrap\">\n {groupLabel}\n </BaseTableCell>\n </BaseTableRow>\n );\n}\n\n// ── Skeleton (loading) rows ──────────────────────────────\n\nexport type SkeletonColumn = { id: string; size?: number; minSize?: number; maxSize?: number };\n\nexport function DataTableSkeletonBody({\n rowCount = 10,\n columns,\n renderCell,\n layout = 'auto',\n}: {\n rowCount?: number;\n columns: SkeletonColumn[];\n renderCell?: (columnId: string) => React.ReactNode | undefined;\n layout?: TableLayout;\n}) {\n const isGrid = layout === 'grid';\n const rows = Array.from({ length: rowCount }).map((_, rowIndex) => (\n <DataTableRow key={`skeleton-row-${rowIndex}`} layout={layout}>\n {columns.map(col =>\n isGrid ? (\n <div\n key={`skeleton-col-${col.id}-row-${rowIndex}`}\n role=\"cell\"\n className={cn(TABLE_CELL_CLASSES, 'flex items-center overflow-hidden')}\n style={{ minWidth: col.minSize }}\n >\n {renderCell?.(col.id) ?? <Skeleton className=\"h-4 w-full\" />}\n </div>\n ) : (\n <BaseTableCell\n key={`skeleton-col-${col.id}-row-${rowIndex}`}\n style={{ width: col.size, minWidth: col.minSize, maxWidth: col.maxSize }}\n >\n {renderCell?.(col.id) ?? <Skeleton className=\"h-4 w-full\" />}\n </BaseTableCell>\n ),\n )}\n </DataTableRow>\n ));\n\n if (isGrid) {\n return (\n <div role=\"rowgroup\" className=\"col-span-full grid grid-cols-subgrid\" data-testid=\"table-skeleton-loader\">\n {rows}\n </div>\n );\n }\n\n return <BaseTableBody data-testid=\"table-skeleton-loader\">{rows}</BaseTableBody>;\n}\n\n// ── Expanded row ─────────────────────────────────────────\n\nexport function DataTableExpandedRow({\n colSpan,\n show,\n children,\n layout = 'auto',\n}: {\n colSpan: number;\n show?: boolean;\n children: React.ReactNode;\n layout?: TableLayout;\n}) {\n if (!show) return null;\n if (layout === 'grid') {\n return (\n <div role=\"row\" className=\"col-span-full grid grid-cols-subgrid\">\n <div role=\"cell\" style={{ gridColumn: `span ${colSpan}` }} className=\"bg-card p-0 align-top whitespace-normal\">\n {children}\n </div>\n </div>\n );\n }\n return (\n <BaseTableRow className=\"hover:bg-transparent\">\n <BaseTableCell colSpan={colSpan} className=\"bg-card p-0 align-top whitespace-normal\">\n {children}\n </BaseTableCell>\n </BaseTableRow>\n );\n}\n\n// ── Body ─────────────────────────────────────────────────\n\nexport function DataTableBody<TData extends RowData>({\n tableRows,\n tableState,\n columns,\n skeletonRowCount,\n renderSkeletonCell,\n onRowRender,\n renderExpandedRow,\n showContextualFilter,\n onContextCell,\n onContextSearch,\n contextualMenuActions,\n layout = 'auto',\n}: {\n tableRows: Row<TData>[];\n tableState: TableDataState;\n columns: Column<TData, unknown>[];\n skeletonRowCount?: number;\n renderSkeletonCell?: (columnId: string) => React.ReactNode | undefined;\n onRowRender?: (row: TData) => DataTableRowProps;\n renderExpandedRow?: (row: TData) => React.ReactNode;\n showContextualFilter?: boolean;\n onContextCell?: (filter: ColumnFilter, cell: Cell<TData, unknown>) => void;\n onContextSearch?: (searchTerm: string, cell: Cell<TData, unknown>) => void;\n contextualMenuActions?: ContextualMenuAction<TData, unknown>[];\n layout?: TableLayout;\n}) {\n const isGrid = layout === 'grid';\n const visibleColumns = columns.filter(column => !isFilterOnlyColumn(column));\n const colSpan = visibleColumns.length;\n\n if (tableState === 'loading') {\n const skeletonColumns: SkeletonColumn[] = visibleColumns.map(c => ({\n id: c.id,\n size: c.columnDef.size,\n minSize: c.columnDef.minSize,\n maxSize: c.columnDef.maxSize,\n }));\n return (\n <DataTableSkeletonBody\n columns={skeletonColumns}\n rowCount={skeletonRowCount}\n renderCell={renderSkeletonCell}\n layout={layout}\n />\n );\n }\n\n const rows = tableRows.map(row => {\n if (row.getIsGrouped?.()) {\n const groupLabel =\n row.groupingValue ?? (row.groupingColumnId ? row.getGroupingValue?.(row.groupingColumnId) : undefined);\n return <DataTableGroupRow key={row.id} groupLabel={String(groupLabel ?? '')} colSpan={colSpan} layout={layout} />;\n }\n\n const isExpanded = !!(renderExpandedRow && row.getIsExpanded?.());\n const expandedRow = renderExpandedRow ? renderExpandedRow(row.original) : null;\n\n return (\n <React.Fragment key={row.id}>\n <DataTableRow\n {...(onRowRender ? onRowRender(row.original) : {})}\n data-expanded={isExpanded || undefined}\n layout={layout}\n >\n {row\n .getVisibleCells()\n .filter(cell => !isFilterOnlyColumn(cell.column))\n .map(cell => (\n <DataTableCell\n key={cell.id}\n cell={cell}\n showContextualFilter={showContextualFilter}\n onContextCell={onContextCell}\n onContextSearch={onContextSearch}\n contextualMenuActions={contextualMenuActions}\n layout={layout}\n />\n ))}\n </DataTableRow>\n <DataTableExpandedRow colSpan={colSpan} show={isExpanded} layout={layout}>\n {expandedRow}\n </DataTableExpandedRow>\n </React.Fragment>\n );\n });\n\n if (isGrid) {\n return (\n <div role=\"rowgroup\" className=\"col-span-full grid grid-cols-subgrid\">\n {rows}\n </div>\n );\n }\n\n return <BaseTableBody>{rows}</BaseTableBody>;\n}\n","'use client';\n\nimport * as React from 'react';\nimport type { Column, ColumnFiltersState, RowData } from '@tanstack/react-table';\n\nimport { ActiveFilter, FilterBar, type FilterDefinition, type FilterOption, type FilterValue } from '@/filter-bar';\nimport {\n isCheckboxColumnFilter,\n isDateRangeColumnFilter,\n isMultiTextColumnFilter,\n isRadioColumnFilter,\n type ColumnFilterDefinition,\n type ColumnFilterOption,\n type ColumnFilterValue,\n} from '@/lib/data-table/filter-types';\nimport { isFilterOnlyColumn } from '@/lib/data-table/utils';\n\nexport type ViewFilterProps<TData extends RowData> = {\n columns: Column<TData, unknown>[];\n columnFilters: ColumnFiltersState;\n onColumnFiltersChange: React.Dispatch<React.SetStateAction<ColumnFiltersState>>;\n className?: string;\n};\n\nfunction toFilterOption(opt: string | ColumnFilterOption): FilterOption {\n return typeof opt === 'string' ? { value: opt, label: opt } : { value: opt.value, label: opt.label };\n}\n\n/** Maps a column's `meta.filter` (the `ColumnFilterDefinition` vocabulary) onto Monarch `FilterBar`'s own `FilterDefinition` shape. */\nfunction toFilterBarDefinition(key: string, filter: ColumnFilterDefinition): FilterDefinition & { order?: number } {\n const base = { key, label: filter.title, order: filter.order };\n\n if (isCheckboxColumnFilter(filter)) {\n const options = 'options' in filter && filter.options ? filter.options : [];\n return {\n ...base,\n type: 'checkbox',\n options: options.map(toFilterOption),\n searchable: filter.searchable ?? true,\n };\n }\n if (isRadioColumnFilter(filter)) {\n return {\n ...base,\n type: 'radio',\n options: filter.options.map(toFilterOption),\n searchable: filter.searchable ?? true,\n };\n }\n if (isDateRangeColumnFilter(filter)) {\n return { ...base, type: 'date', includeTime: filter.includeTime };\n }\n if (isMultiTextColumnFilter(filter)) {\n return { ...base, type: 'multiText', placeholder: filter.placeholder };\n }\n return { ...base, type: 'text', placeholder: filter.placeholder };\n}\n\n/** The empty value a filter starts at the moment it's added, before the user picks anything. */\nfunction emptyValueFor(filter: ColumnFilterDefinition): ColumnFilterValue {\n if (isCheckboxColumnFilter(filter)) return [];\n if (isRadioColumnFilter(filter)) return undefined;\n if (isDateRangeColumnFilter(filter)) return { startDate: null, endDate: null };\n if (isMultiTextColumnFilter(filter)) return [];\n return undefined;\n}\n\n/**\n * The plain (non-CEL) filter row — a thin state adapter over Monarch's\n * `FilterBar`, mirroring TableWrapper's own `ViewFilter` (itself just a\n * `FilterBar` adapter, not a hand-rolled UI). Every `meta.filter` shape\n * (checkbox, radio, dateRange, text, multiText) gets a chip here, mapped onto\n * the matching `FilterBar` chip type — checkbox and radio chips are\n * searchable by default (opt out per column via `meta.filter.searchable:\n * false`). CEL-based filtering (`celFilterConfig`) is the richer,\n * operator-driven tier this is not meant to replace.\n */\nexport function ViewFilter<TData extends RowData>({\n columns,\n columnFilters,\n onColumnFiltersChange,\n className,\n}: ViewFilterProps<TData>) {\n const filterableColumns = React.useMemo(\n () =>\n columns\n .filter(column => !isFilterOnlyColumn(column) && column.getCanFilter())\n .flatMap(column => {\n const filter = column.columnDef.meta?.filter;\n return filter ? [{ key: column.id, filter }] : [];\n }),\n [columns],\n );\n\n const filterDefinitions = React.useMemo<(FilterDefinition & { order?: number })[]>(\n () =>\n filterableColumns\n .map(({ key, filter }) => toFilterBarDefinition(key, filter))\n .sort((a, b) => {\n if (a.order == null && b.order == null) return 0;\n if (a.order == null) return 1;\n if (b.order == null) return -1;\n return a.order - b.order;\n }),\n [filterableColumns],\n );\n\n const emptyValueByKey = React.useMemo(\n () => new Map(filterableColumns.map(({ key, filter }) => [key, emptyValueFor(filter)])),\n [filterableColumns],\n );\n\n const activeFilters = React.useMemo<ActiveFilter[]>(\n () => columnFilters.map(filter => ({ key: filter.id, value: filter.value as FilterValue | undefined })),\n [columnFilters],\n );\n\n return (\n <FilterBar\n className={className}\n filters={filterDefinitions}\n activeFilters={activeFilters}\n onAddFilter={key =>\n onColumnFiltersChange(prev => [...prev.filter(f => f.id !== key), { id: key, value: emptyValueByKey.get(key) }])\n }\n onRemoveFilter={key => onColumnFiltersChange(prev => prev.filter(f => f.id !== key))}\n onChangeFilter={(key, value) =>\n onColumnFiltersChange(prev => [...prev.filter(f => f.id !== key), { id: key, value }])\n }\n />\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport { type DateRange } from 'react-day-picker';\nimport { Icon } from '@upbound/monarch-core';\n\nimport { cn, sortBy } from '@/lib/utils';\nimport { Badge } from '@upbound/monarch-core';\nimport { Button } from '@upbound/monarch-core';\nimport { ButtonGroup, ButtonGroupText } from '@upbound/monarch-core';\nimport { Calendar } from '@upbound/monarch-core';\nimport {\n Combobox,\n ComboboxChip,\n ComboboxClearAll,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxInput,\n ComboboxItem,\n ComboboxList,\n ComboboxSelectedChips,\n ComboboxSeparator,\n ComboboxTrigger,\n ComboboxValue,\n} from '@upbound/monarch-core';\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n} from '@upbound/monarch-core';\nimport { Input } from '@upbound/monarch-core';\nimport { Label } from '@upbound/monarch-core';\nimport { Popover, PopoverContent, PopoverTrigger } from '@upbound/monarch-core';\n\n// ── Types ─────────────────────────────────────────────\n\ntype FilterType = 'checkbox' | 'radio' | 'text' | 'multiText' | 'date';\n\ninterface FilterOption {\n value: string;\n label: string;\n icon?: React.ReactNode;\n}\n\ninterface FilterDefinitionBase {\n key: string;\n label: string;\n}\n\ninterface CheckboxFilterDefinition extends FilterDefinitionBase {\n type?: 'checkbox';\n options: FilterOption[];\n /**\n * When `true`, the chip's value popup becomes a searchable Combobox\n * (multi-select with a search input). Use for long option lists where a\n * basic dropdown becomes hard to scan. When `false` or omitted, the chip\n * uses the standard checkbox dropdown.\n */\n searchable?: boolean;\n}\n\ninterface RadioFilterDefinition extends FilterDefinitionBase {\n type: 'radio';\n options: FilterOption[];\n /** Same searchable-Combobox swap as `CheckboxFilterDefinition`, constrained to a single selection. */\n searchable?: boolean;\n}\n\ninterface TextFilterDefinition extends FilterDefinitionBase {\n type: 'text';\n placeholder?: string;\n}\n\ninterface MultiTextFilterDefinition extends FilterDefinitionBase {\n type: 'multiText';\n placeholder?: string;\n}\n\ninterface DateFilterDefinition extends FilterDefinitionBase {\n type: 'date';\n /**\n * `true` always shows Start/End time inputs, `false` never shows them,\n * and omitted auto-detects from whether the current value already carries\n * a non-midnight time component.\n */\n includeTime?: boolean;\n}\n\ntype FilterDefinition =\n | CheckboxFilterDefinition\n | RadioFilterDefinition\n | TextFilterDefinition\n | MultiTextFilterDefinition\n | DateFilterDefinition;\n\ntype CheckboxFilterValue = string[];\ntype RadioFilterValue = string;\ntype TextFilterValue = string;\ntype MultiTextFilterValue = string[];\ntype DateFilterValue = { startDate: Date | null; endDate: Date | null };\ntype FilterValue = CheckboxFilterValue | RadioFilterValue | TextFilterValue | MultiTextFilterValue | DateFilterValue;\n\ninterface ActiveFilter {\n key: string;\n value?: FilterValue;\n}\n\n// ── Value helpers ─────────────────────────────────────\n\nfunction asCheckboxValue(value: FilterValue | undefined): CheckboxFilterValue {\n return Array.isArray(value) ? value : [];\n}\n\nfunction asRadioValue(value: FilterValue | undefined): RadioFilterValue {\n return typeof value === 'string' ? value : '';\n}\n\nfunction asTextValue(value: FilterValue | undefined): TextFilterValue {\n return typeof value === 'string' ? value : '';\n}\n\nfunction asMultiTextValue(value: FilterValue | undefined): MultiTextFilterValue {\n return Array.isArray(value) ? value : [];\n}\n\nfunction asDateValue(value: FilterValue | undefined): DateFilterValue {\n if (value && typeof value === 'object' && !Array.isArray(value)) return value as DateFilterValue;\n return { startDate: null, endDate: null };\n}\n\nfunction hasExplicitTime(date: Date | null): boolean {\n if (!date) return false;\n return date.getHours() !== 0 || date.getMinutes() !== 0;\n}\n\nfunction formatTimeForInput(date: Date | null): string {\n if (!date) return '';\n return `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`;\n}\n\nfunction applyTimeToDate(date: Date, time: string): Date {\n const [hours, minutes] = time.split(':').map(Number);\n const next = new Date(date);\n next.setHours(hours || 0, minutes || 0, 0, 0);\n return next;\n}\n\nfunction formatDateLabel(date: Date): string {\n return date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });\n}\n\n/** Merges the internal ref FilterBar uses to track its own root node with\n * any ref a consumer passes to `FilterBar` itself. */\nfunction composeRefs<T>(...refs: Array<React.Ref<T> | null | undefined>) {\n return (node: T | null) => {\n for (const ref of refs) {\n if (typeof ref === 'function') ref(node);\n else if (ref) (ref as React.RefObject<T | null>).current = node;\n }\n };\n}\n\ntype PortalContainer = React.ComponentProps<typeof ComboboxContent>['container'];\n\n// ── FilterBar ─────────────────────────────────────────\n\ninterface FilterBarProps extends React.ComponentProps<'div'> {\n filters: FilterDefinition[];\n activeFilters: ActiveFilter[];\n onAddFilter: (key: string) => void;\n onRemoveFilter: (key: string) => void;\n onChangeFilter: (key: string, value: FilterValue) => void;\n}\n\nfunction hasOrder(filter: FilterDefinition): boolean {\n return typeof (filter as { order?: unknown }).order === 'number';\n}\n\nfunction FilterBar({\n filters,\n activeFilters,\n onAddFilter,\n onRemoveFilter,\n onChangeFilter,\n className,\n children,\n ref,\n ...props\n}: FilterBarProps) {\n const usedKeys = new Set(activeFilters.map(f => f.key));\n const remainingFilters = filters.filter(f => !usedKeys.has(f.key));\n const availableFilters = filters.some(hasOrder) ? remainingFilters : sortBy(remainingFilters, f => f.label);\n const shouldShowFilters = availableFilters.length > 0 || activeFilters.length > 0;\n\n // Tracks the most recently added filter so its chip can open its value\n // popup immediately, without waiting for a second click.\n const [pendingOpenKey, setPendingOpenKey] = React.useState<string | null>(null);\n\n function handleAddFilter(key: string) {\n onAddFilter(key);\n setPendingOpenKey(key);\n }\n\n // Ref for the FilterBar's own root node, used to anchor Combobox popups.\n // Helps rendering correctly the popup when rendered inside a modal Dialog/Sheet.\n const containerRef = React.useRef<HTMLDivElement>(null);\n\n return (\n <div\n data-slot=\"filter-bar\"\n data-visible-filters={shouldShowFilters}\n className={cn('flex flex-wrap items-center gap-2', className)}\n ref={composeRefs(containerRef, ref)}\n {...props}\n >\n {/* Add filter button */}\n {availableFilters.length > 0 && (\n <Combobox\n items={availableFilters}\n itemToStringValue={(item: FilterDefinition) => item.label}\n itemToStringLabel={(item: FilterDefinition) => item.label}\n onValueChange={(filter: FilterDefinition | null) => {\n if (filter) handleAddFilter(filter.key);\n }}\n >\n {/* role=\"combobox\" doesn't pick up child text as its accessible name the\n way a plain button would — an explicit aria-label is required, not\n just a nicety. */}\n <ComboboxTrigger aria-label=\"Add filter\" render={<Button variant=\"outline\" />}>\n <Icon name=\"plus\" data-icon=\"inline-start\" />\n Add filter\n </ComboboxTrigger>\n <ComboboxContent container={containerRef} align=\"start\" className=\"w-48\">\n <ComboboxInput showTrigger={false} placeholder=\"Search filters…\" />\n <ComboboxEmpty>No filters found.</ComboboxEmpty>\n <ComboboxList>\n {(filter: FilterDefinition) => (\n <ComboboxItem key={filter.key} value={filter}>\n {filter.label}\n </ComboboxItem>\n )}\n </ComboboxList>\n </ComboboxContent>\n </Combobox>\n )}\n\n {/* Active filter chips */}\n {activeFilters.map(active => {\n const definition = filters.find(f => f.key === active.key);\n if (!definition) return null;\n return (\n <FilterChip\n key={active.key}\n definition={definition}\n value={active.value}\n autoOpen={active.key === pendingOpenKey}\n container={containerRef}\n onChangeValue={value => onChangeFilter(active.key, value)}\n onRemove={() => onRemoveFilter(active.key)}\n />\n );\n })}\n\n {/* Children (count, actions) — sit immediately after the last chip\n with the same `gap-2` spacing. With the parent's `flex-wrap`, a\n long row of chips will push the action onto the next line instead\n of stretching across an empty horizontal void. */}\n {children}\n </div>\n );\n}\n\n// ── FilterChip (dispatcher) ────────────────────────────\n\ninterface FilterChipProps {\n definition: FilterDefinition;\n value: FilterValue | undefined;\n /** Opens the chip's value popup as soon as it mounts — used right after the filter is added. */\n autoOpen?: boolean;\n /** Portals a searchable checkbox/radio chip's Combobox popup here instead of the default `document.body` — see `FilterBar`'s own `containerRef` for why. */\n container?: PortalContainer;\n onChangeValue: (value: FilterValue) => void;\n onRemove: () => void;\n}\n\nfunction FilterChip({ definition, value, autoOpen, container, onChangeValue, onRemove }: FilterChipProps) {\n const type = definition.type ?? 'checkbox';\n\n switch (type) {\n case 'checkbox':\n return (\n <CheckboxFilterChip\n definition={definition as CheckboxFilterDefinition}\n value={value}\n autoOpen={autoOpen}\n container={container}\n onChangeValue={onChangeValue}\n onRemove={onRemove}\n />\n );\n case 'radio':\n return (\n <RadioFilterChip\n definition={definition as RadioFilterDefinition}\n value={value}\n autoOpen={autoOpen}\n container={container}\n onChangeValue={onChangeValue}\n onRemove={onRemove}\n />\n );\n case 'text':\n return (\n <TextFilterChip\n definition={definition as TextFilterDefinition}\n value={value}\n autoOpen={autoOpen}\n onChangeValue={onChangeValue}\n onRemove={onRemove}\n />\n );\n case 'multiText':\n return (\n <MultiTextFilterChip\n definition={definition as MultiTextFilterDefinition}\n value={value}\n autoOpen={autoOpen}\n onChangeValue={onChangeValue}\n onRemove={onRemove}\n />\n );\n case 'date':\n return (\n <DateFilterChip\n definition={definition as DateFilterDefinition}\n value={value}\n autoOpen={autoOpen}\n onChangeValue={onChangeValue}\n onRemove={onRemove}\n />\n );\n }\n}\n\n// ── Shared chip chrome ─────────────────────────────────\n\nfunction FilterChipRemoveButton({ label, onRemove }: { label: string; onRemove: () => void }) {\n return (\n <Button variant=\"outline\" size=\"icon\" aria-label={`Remove ${label} filter`} onClick={onRemove}>\n <Icon name=\"xmark\" />\n </Button>\n );\n}\n\n// ── Checkbox chip ──────────────────────────────────────\n\nfunction CheckboxFilterChip({\n definition,\n value,\n autoOpen,\n container,\n onChangeValue,\n onRemove,\n}: {\n definition: CheckboxFilterDefinition;\n value: FilterValue | undefined;\n autoOpen?: boolean;\n container?: PortalContainer;\n onChangeValue: (value: FilterValue) => void;\n onRemove: () => void;\n}) {\n const { label, searchable = false } = definition;\n const options = sortBy(definition.options, o => o.label);\n const values = asCheckboxValue(value);\n const displayLabel =\n values.length === 0\n ? 'Any'\n : values.length === 1\n ? (options.find(o => o.value === values[0])?.label ?? values[0])\n : `${values.length} selected`;\n\n function toggle(optionValue: string) {\n const next = values.includes(optionValue) ? values.filter(v => v !== optionValue) : [...values, optionValue];\n onChangeValue(next);\n }\n\n return (\n <ButtonGroup>\n <ButtonGroupText>{label}</ButtonGroupText>\n {searchable ? (\n <Combobox\n items={options}\n itemToStringValue={(item: FilterOption) => item.label}\n multiple\n defaultOpen={autoOpen}\n value={options.filter(o => values.includes(o.value))}\n onValueChange={(selected: FilterOption[]) => onChangeValue(selected.map(s => s.value))}\n >\n <ComboboxTrigger\n render={<Button variant=\"outline\" className=\"gap-1 font-normal [&>svg:last-child]:size-(--icon-sm)\" />}\n >\n <span className={values.length === 0 ? 'text-muted-foreground' : ''}>{displayLabel}</span>\n </ComboboxTrigger>\n <ComboboxContent\n container={container}\n className=\"min-w-64\"\n collisionAvoidance={{ side: 'none', align: 'shift' }}\n >\n <ComboboxInput showTrigger={false} placeholder={`Search ${label.toLowerCase()}…`} />\n {values.length > 0 && (\n <>\n <ComboboxSelectedChips>\n <ComboboxValue>\n {(selected: FilterOption[]) => (\n <>\n {selected.map(item => (\n <ComboboxChip key={item.value}>{item.label}</ComboboxChip>\n ))}\n </>\n )}\n </ComboboxValue>\n <ComboboxClearAll onClick={() => onChangeValue([])} />\n </ComboboxSelectedChips>\n <ComboboxSeparator />\n </>\n )}\n <ComboboxEmpty>No {label.toLowerCase()} found.</ComboboxEmpty>\n <ComboboxList>\n {(item: FilterOption) => (\n <ComboboxItem key={item.value} value={item}>\n {item.icon}\n {item.label}\n </ComboboxItem>\n )}\n </ComboboxList>\n </ComboboxContent>\n </Combobox>\n ) : (\n <DropdownMenu defaultOpen={autoOpen}>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" className=\"gap-1 font-normal\">\n <span className={values.length === 0 ? 'text-muted-foreground' : ''}>{displayLabel}</span>\n <Icon name=\"chevron-down\" size=\"sm\" className=\"text-muted-foreground\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-48\">\n {options.map(opt => (\n <DropdownMenuCheckboxItem\n key={opt.value}\n checked={values.includes(opt.value)}\n onCheckedChange={() => toggle(opt.value)}\n >\n {opt.icon}\n {opt.label}\n </DropdownMenuCheckboxItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n <FilterChipRemoveButton label={label} onRemove={onRemove} />\n </ButtonGroup>\n );\n}\n\n// ── Radio chip ─────────────────────────────────────────\n\nfunction RadioFilterChip({\n definition,\n value,\n autoOpen,\n container,\n onChangeValue,\n onRemove,\n}: {\n definition: RadioFilterDefinition;\n value: FilterValue | undefined;\n autoOpen?: boolean;\n container?: PortalContainer;\n onChangeValue: (value: FilterValue) => void;\n onRemove: () => void;\n}) {\n const { label, searchable = false } = definition;\n const options = sortBy(definition.options, o => o.label);\n const selectedValue = asRadioValue(value);\n const displayLabel = selectedValue ? (options.find(o => o.value === selectedValue)?.label ?? selectedValue) : 'Any';\n const selected = options.find(o => o.value === selectedValue) ?? null;\n\n return (\n <ButtonGroup>\n <ButtonGroupText>{label}</ButtonGroupText>\n {searchable ? (\n <Combobox\n items={options}\n itemToStringValue={(item: FilterOption) => item.label}\n defaultOpen={autoOpen}\n value={selected}\n onValueChange={(next: FilterOption | null) => onChangeValue(next?.value ?? '')}\n >\n <ComboboxTrigger\n render={<Button variant=\"outline\" className=\"gap-1 font-normal [&>svg:last-child]:size-(--icon-sm)\" />}\n >\n <span className={selectedValue ? '' : 'text-muted-foreground'}>{displayLabel}</span>\n </ComboboxTrigger>\n <ComboboxContent\n container={container}\n className=\"min-w-64\"\n collisionAvoidance={{ side: 'none', align: 'shift' }}\n >\n <ComboboxInput showTrigger={false} placeholder={`Search ${label.toLowerCase()}…`} />\n <ComboboxEmpty>No {label.toLowerCase()} found.</ComboboxEmpty>\n <ComboboxList>\n {(item: FilterOption) => (\n <ComboboxItem key={item.value} value={item}>\n {item.icon}\n {item.label}\n </ComboboxItem>\n )}\n </ComboboxList>\n </ComboboxContent>\n </Combobox>\n ) : (\n <DropdownMenu defaultOpen={autoOpen}>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" className=\"gap-1 font-normal\">\n <span className={selectedValue ? '' : 'text-muted-foreground'}>{displayLabel}</span>\n <Icon name=\"chevron-down\" size=\"sm\" className=\"text-muted-foreground\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-48\">\n <DropdownMenuRadioGroup value={selectedValue} onValueChange={onChangeValue}>\n {options.map(opt => (\n <DropdownMenuRadioItem key={opt.value} value={opt.value}>\n {opt.icon}\n {opt.label}\n </DropdownMenuRadioItem>\n ))}\n </DropdownMenuRadioGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n <FilterChipRemoveButton label={label} onRemove={onRemove} />\n </ButtonGroup>\n );\n}\n\n// ── Text chip ──────────────────────────────────────────\n\nfunction TextFilterChip({\n definition,\n value,\n autoOpen,\n onChangeValue,\n onRemove,\n}: {\n definition: TextFilterDefinition;\n value: FilterValue | undefined;\n autoOpen?: boolean;\n onChangeValue: (value: FilterValue) => void;\n onRemove: () => void;\n}) {\n const { label, placeholder } = definition;\n const text = asTextValue(value);\n const [open, setOpen] = React.useState(!!autoOpen);\n\n return (\n <ButtonGroup>\n <ButtonGroupText>{label}</ButtonGroupText>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button variant=\"outline\" className=\"gap-1 font-normal\">\n <span className={text ? '' : 'text-muted-foreground'}>{text || 'Any'}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\">\n <Input\n autoFocus\n value={text}\n placeholder={placeholder ?? 'Enter a value…'}\n onChange={e => onChangeValue(e.target.value)}\n onKeyDown={e => {\n if (e.key === 'Enter') setOpen(false);\n }}\n />\n </PopoverContent>\n </Popover>\n <FilterChipRemoveButton label={label} onRemove={onRemove} />\n </ButtonGroup>\n );\n}\n\n// ── MultiText chip ─────────────────────────────────────\n\nfunction MultiTextFilterChip({\n definition,\n value,\n autoOpen,\n onChangeValue,\n onRemove,\n}: {\n definition: MultiTextFilterDefinition;\n value: FilterValue | undefined;\n autoOpen?: boolean;\n onChangeValue: (value: FilterValue) => void;\n onRemove: () => void;\n}) {\n const { label, placeholder } = definition;\n const tokens = asMultiTextValue(value);\n const [draft, setDraft] = React.useState('');\n const displayLabel = tokens.length === 0 ? 'Any' : tokens.length === 1 ? tokens[0] : `${tokens.length} values`;\n\n function addToken() {\n const token = draft.trim();\n if (!token || tokens.includes(token)) {\n setDraft('');\n return;\n }\n onChangeValue([...tokens, token]);\n setDraft('');\n }\n\n function removeToken(token: string) {\n onChangeValue(tokens.filter(t => t !== token));\n }\n\n return (\n <ButtonGroup>\n <ButtonGroupText>{label}</ButtonGroupText>\n <Popover defaultOpen={autoOpen}>\n <PopoverTrigger asChild>\n <Button variant=\"outline\" className=\"gap-1 font-normal\">\n <span className={tokens.length === 0 ? 'text-muted-foreground' : ''}>{displayLabel}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\">\n <div className=\"flex flex-col gap-2\">\n {tokens.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {tokens.map(token => (\n <Badge key={token} variant=\"secondary\" className=\"gap-1\">\n {token}\n <button\n type=\"button\"\n aria-label={`Remove ${token}`}\n onClick={() => removeToken(token)}\n className=\"cursor-pointer\"\n >\n <Icon name=\"xmark\" size=\"xs\" />\n </button>\n </Badge>\n ))}\n </div>\n )}\n <Input\n autoFocus\n value={draft}\n placeholder={placeholder ?? 'Type a value, press Enter…'}\n onChange={e => setDraft(e.target.value)}\n onKeyDown={e => {\n if (e.key === 'Enter') {\n e.preventDefault();\n addToken();\n } else if (e.key === 'Backspace' && draft === '' && tokens.length > 0) {\n removeToken(tokens[tokens.length - 1]);\n }\n }}\n />\n </div>\n </PopoverContent>\n </Popover>\n <FilterChipRemoveButton label={label} onRemove={onRemove} />\n </ButtonGroup>\n );\n}\n\n// ── Date chip ──────────────────────────────────────────\n\nfunction DateFilterChip({\n definition,\n value,\n autoOpen,\n onChangeValue,\n onRemove,\n}: {\n definition: DateFilterDefinition;\n value: FilterValue | undefined;\n autoOpen?: boolean;\n onChangeValue: (value: FilterValue) => void;\n onRemove: () => void;\n}) {\n const { label, includeTime } = definition;\n const { startDate, endDate } = asDateValue(value);\n const showTimeInputs = includeTime ?? (hasExplicitTime(startDate) || hasExplicitTime(endDate));\n\n const displayLabel = !startDate\n ? 'Any'\n : !endDate || startDate.getTime() === endDate.getTime()\n ? formatDateLabel(startDate)\n : `${formatDateLabel(startDate)} – ${formatDateLabel(endDate)}`;\n\n function pickRange(range: DateRange | undefined) {\n if (!range?.from) {\n onChangeValue({ startDate: null, endDate: null });\n return;\n }\n onChangeValue({ startDate: range.from, endDate: range.to ?? range.from });\n }\n\n function pickStartTime(time: string) {\n if (!startDate) return;\n onChangeValue({ startDate: applyTimeToDate(startDate, time), endDate });\n }\n\n function pickEndTime(time: string) {\n if (!endDate) return;\n onChangeValue({ startDate, endDate: applyTimeToDate(endDate, time) });\n }\n\n return (\n <ButtonGroup>\n <ButtonGroupText>{label}</ButtonGroupText>\n <Popover defaultOpen={autoOpen}>\n <PopoverTrigger asChild>\n <Button variant=\"outline\" className=\"gap-1 font-normal\">\n <span className={startDate ? '' : 'text-muted-foreground'}>{displayLabel}</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-fit\">\n <div className=\"flex flex-col gap-2\">\n <Calendar\n mode=\"range\"\n selected={{ from: startDate ?? undefined, to: endDate ?? undefined }}\n onSelect={pickRange}\n />\n {showTimeInputs && (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex w-full items-center gap-2\">\n <Label\n htmlFor={`${definition.key}-start-time`}\n className=\"text-body-sm text-muted-foreground w-10 shrink-0\"\n >\n Start\n </Label>\n <Input\n id={`${definition.key}-start-time`}\n type=\"time\"\n className=\"w-full\"\n value={formatTimeForInput(startDate)}\n onChange={e => pickStartTime(e.target.value)}\n disabled={!startDate}\n />\n </div>\n <div className=\"flex w-full items-center gap-2\">\n <Label\n htmlFor={`${definition.key}-end-time`}\n className=\"text-body-sm text-muted-foreground w-10 shrink-0\"\n >\n End\n </Label>\n <Input\n id={`${definition.key}-end-time`}\n type=\"time\"\n className=\"w-full\"\n value={formatTimeForInput(endDate)}\n onChange={e => pickEndTime(e.target.value)}\n disabled={!endDate}\n />\n </div>\n </div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n <FilterChipRemoveButton label={label} onRemove={onRemove} />\n </ButtonGroup>\n );\n}\n\nexport {\n FilterBar,\n FilterChip,\n type FilterType,\n type FilterDefinition,\n type CheckboxFilterDefinition,\n type RadioFilterDefinition,\n type TextFilterDefinition,\n type MultiTextFilterDefinition,\n type DateFilterDefinition,\n type ActiveFilter,\n type FilterOption,\n type FilterValue,\n type CheckboxFilterValue,\n type RadioFilterValue,\n type TextFilterValue,\n type MultiTextFilterValue,\n type DateFilterValue,\n type FilterBarProps,\n};\n","/**\n * Non-CEL column filter definitions — the `meta.filter` vocabulary consumed by\n * contextual (right-click cell) filtering and by the plain filter bar.\n * Mirrors TableWrapper's `Filters/types.ts` shapes; `id` is omitted here since\n * it comes from the owning `ColumnDef.id`, not the filter definition itself.\n */\n\nexport type ColumnFilterType = 'checkbox' | 'radio' | 'dateRange' | 'text' | 'multiText';\n\nexport type ColumnFilterOption = {\n label: string;\n value: string;\n disabled?: boolean;\n children?: ColumnFilterOption[];\n};\n\nexport type FetchColumnFilterOptionsArgs = {\n query: string;\n page: number;\n signal: AbortSignal;\n};\n\nexport type FetchColumnFilterOptionsResult = {\n items: ColumnFilterOption[];\n hasMore: boolean;\n};\n\nexport type FetchColumnFilterOptions = (args: FetchColumnFilterOptionsArgs) => Promise<FetchColumnFilterOptionsResult>;\n\ntype ColumnFilterBase = {\n title: string;\n type: ColumnFilterType;\n order?: number;\n};\n\ntype StaticCheckboxColumnFilter = ColumnFilterBase & {\n type: 'checkbox';\n options: string[] | ColumnFilterOption[];\n fetchFilterOptions?: never;\n /** Whether the chip's value popup is a searchable Combobox. Defaults to `true`. */\n searchable?: boolean;\n};\n\ntype AsyncCheckboxColumnFilter = ColumnFilterBase & {\n type: 'checkbox';\n fetchFilterOptions: FetchColumnFilterOptions;\n options?: never;\n /** Whether the chip's value popup is a searchable Combobox. Defaults to `true`. */\n searchable?: boolean;\n};\n\nexport type CheckboxColumnFilter = StaticCheckboxColumnFilter | AsyncCheckboxColumnFilter;\n\nexport type RadioColumnFilter = ColumnFilterBase & {\n type: 'radio';\n options: string[] | ColumnFilterOption[];\n /** Whether the chip's value popup is a searchable Combobox. Defaults to `true`. */\n searchable?: boolean;\n};\n\nexport type DateRangeColumnFilter = ColumnFilterBase & {\n type: 'dateRange';\n /** When true, always show time inputs. When false, never show them. When omitted, auto-detect from value. */\n includeTime?: boolean;\n};\n\nexport type TextColumnFilter = ColumnFilterBase & {\n type: 'text';\n placeholder?: string;\n};\n\nexport type MultiTextColumnFilter = ColumnFilterBase & {\n type: 'multiText';\n /** Defaults to comma (`,`) when omitted. */\n delimiter?: string;\n description?: string;\n placeholder?: string;\n};\n\nexport type ColumnFilterDefinition =\n CheckboxColumnFilter | DateRangeColumnFilter | RadioColumnFilter | TextColumnFilter | MultiTextColumnFilter;\n\nexport type CheckboxColumnFilterValue = string[] | undefined;\nexport type RadioColumnFilterValue = string | undefined;\nexport type DateRangeColumnFilterValue = { startDate: Date | null; endDate: Date | null } | undefined;\nexport type TextColumnFilterValue = string | undefined;\nexport type MultiTextColumnFilterValue = string[] | undefined;\n\nexport type ColumnFilterValue =\n | CheckboxColumnFilterValue\n | RadioColumnFilterValue\n | DateRangeColumnFilterValue\n | TextColumnFilterValue\n | MultiTextColumnFilterValue;\n\nexport const isDateRangeColumnFilter = (definition: ColumnFilterDefinition): definition is DateRangeColumnFilter =>\n definition.type === 'dateRange';\n\nexport const isRadioColumnFilter = (definition: ColumnFilterDefinition): definition is RadioColumnFilter =>\n definition.type === 'radio';\n\nexport const isCheckboxColumnFilter = (definition: ColumnFilterDefinition): definition is CheckboxColumnFilter =>\n definition.type === 'checkbox';\n\nexport const isTextColumnFilter = (definition: ColumnFilterDefinition): definition is TextColumnFilter =>\n definition.type === 'text';\n\nexport const isMultiTextColumnFilter = (definition: ColumnFilterDefinition): definition is MultiTextColumnFilter =>\n definition.type === 'multiText';\n\nexport const isCheckboxColumnFilterValue = (value: unknown): value is CheckboxColumnFilterValue =>\n value === undefined || (Array.isArray(value) && value.every(item => typeof item === 'string'));\n\nexport const isRadioColumnFilterValue = (value: unknown): value is RadioColumnFilterValue =>\n value === undefined || typeof value === 'string';\n\nexport const isDateRangeColumnFilterValue = (value: unknown): value is DateRangeColumnFilterValue =>\n value === undefined || (typeof value === 'object' && value !== null && 'startDate' in value && 'endDate' in value);\n","import { cn } from '@/lib/utils';\n\nfunction SectionHeader({ className, children, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"section-header\"\n className={cn('flex w-full items-start justify-between gap-4', className)}\n {...props}\n >\n {children}\n </div>\n );\n}\n\nfunction SectionHeaderContent({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"section-header-content\" className={cn('flex flex-col gap-1', className)} {...props} />;\n}\n\nfunction SectionHeaderTitle({ className, ...props }: React.ComponentProps<'h2'>) {\n return <h2 data-slot=\"section-header-title\" className={cn('text-h3 text-foreground', className)} {...props} />;\n}\n\nfunction SectionHeaderDescription({ className, ...props }: React.ComponentProps<'p'>) {\n return (\n <p data-slot=\"section-header-description\" className={cn('text-body text-muted-foreground', className)} {...props} />\n );\n}\n\nfunction SectionHeaderMeta({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"section-header-meta\"\n className={cn(\n 'text-body text-muted-foreground flex flex-wrap items-center gap-4',\n \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-(--icon-default)\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction SectionHeaderActions({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"section-header-actions\" className={cn('flex items-center gap-2', className)} {...props} />;\n}\n\nfunction SectionHeaderTabs({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"section-header-tabs\" className={cn('border-b', className)} {...props} />;\n}\n\nexport {\n SectionHeader,\n SectionHeaderContent,\n SectionHeaderTitle,\n SectionHeaderDescription,\n SectionHeaderMeta,\n SectionHeaderActions,\n SectionHeaderTabs,\n};\n"],"mappings":"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","names":["_a","getColumnPinning","Fragment","jsx","jsxs","Button","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","Icon","React","jsx","mins","hrs","days","id","jsx","jsxs","DropdownMenu","DropdownMenuTrigger","Button","Icon","DropdownMenuContent","DropdownMenuItem","React","React","Icon","Button","useCallback","useState","useState","useCallback","Fragment","jsx","jsxs","Button","Icon","Icon","InputGroup","InputGroupAddon","InputGroupInput","useCallback","useEffect","useRef","useState","_a","useState","useRef","useEffect","useCallback","React","_a","React","Button","Icon","jsx","jsxs","Button","Icon","Icon","jsx","jsxs","Button","Icon","Label","Select","SelectContent","SelectGroup","SelectItem","SelectTrigger","SelectValue","Tooltip","TooltipContent","TooltipTrigger","jsx","jsxs","Tooltip","TooltipTrigger","Icon","TooltipContent","Label","Select","SelectTrigger","SelectValue","SelectContent","SelectGroup","SelectItem","Button","React","flexRender","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","Icon","Tooltip","TooltipContent","TooltipTrigger","Fragment","jsx","jsxs","Icon","DropdownMenuContent","DropdownMenuItem","flexRender","DropdownMenu","DropdownMenuTrigger","Tooltip","TooltipTrigger","TooltipContent","React","React","Icon","Badge","Button","ButtonGroup","ButtonGroupText","Calendar","Combobox","ComboboxChip","ComboboxClearAll","ComboboxContent","ComboboxEmpty","ComboboxInput","ComboboxItem","ComboboxList","ComboboxSelectedChips","ComboboxSeparator","ComboboxTrigger","ComboboxValue","DropdownMenu","DropdownMenuCheckboxItem","DropdownMenuContent","DropdownMenuTrigger","Input","Label","Popover","PopoverContent","PopoverTrigger","Fragment","jsx","jsxs","Combobox","ComboboxTrigger","Button","Icon","ComboboxContent","ComboboxInput","ComboboxEmpty","ComboboxList","ComboboxItem","ButtonGroup","ButtonGroupText","ComboboxSelectedChips","ComboboxValue","ComboboxChip","ComboboxClearAll","ComboboxSeparator","DropdownMenu","DropdownMenuTrigger","DropdownMenuContent","DropdownMenuCheckboxItem","_a","Popover","PopoverTrigger","PopoverContent","Input","Badge","Calendar","Label","jsx","jsx","Fragment","jsx","jsxs","_a","_b","InputGroup","InputGroupAddon","Icon","InputGroupInput"]}