import * as react_jsx_runtime from 'react/jsx-runtime'; import { FilterFieldRuntimeContext } from '../../lib/column-filter-context.js'; import * as React from 'react'; import { ColumnDef } from '../data-table/types.js'; import { useTableState } from '../data-table/use-table-state.js'; import { DataListViewType } from '../../lib/data-list-view.js'; import { c as DataListViewRenderKind } from '../../data-list-view-registry-BBKzJxGS.js'; import { DataListDisplayOptions } from '../../lib/data-list-display-options.js'; import { ActiveFilter, SortRule, ConditionalRule, FilterFieldDef } from '../../lib/table-properties-types.js'; import { ListPageBoardColumnDef } from './list-page-board-template.js'; import { OpenTablePropertiesHandle } from '../../lib/list-page-table-properties.js'; import '../../lib/column-filter-person-options.js'; import '../../lib/column-cell-kind.js'; import '../../lib/row-height.js'; /** Derive `FilterFieldDef[]` from a hub's column defs — preferred to hand-writing both. */ declare function columnsToFilterFields(cols: ColumnDef[]): FilterFieldDef[]; /** Field definitions for the drawer's Sort / Group / Columns panels — excludes utility columns. */ declare function columnsToFieldDefinitions(cols: ColumnDef[]): { key: string; label: string; sortable: boolean; }[]; /** * Structured bulk-action definition. `HubTable` renders one button per entry * inside the floating bulk-action bar when the row selection is non-empty. * * `onSelect` receives the **actual selected `TRow` objects** (filtered from * the source `rows` by `getRowId`). Consumers don't see the underlying * `Set` — they just react to typed rows. * * `variant`: * - `"default"` (omit) → outline button — Archive, Export, Tag, etc. * - `"destructive"` → red destructive button — Delete, Remove, etc. */ interface BulkAction> { /** Stable id (used as React key). */ id: string; /** Visible button label. */ label: string; /** Font Awesome glyph (e.g. `"fa-box-archive"`). Rendered as ``. */ icon?: string; /** Optional `aria-label` override. Defaults to `label`. Always set explicitly when `label` is too terse for AT. */ ariaLabel?: string; /** Optional tooltip shown on hover/focus. Defaults to `label`. */ tooltip?: string; /** Fired with the actual selected `TRow` objects (already resolved by `getRowId`). */ onSelect: (selectedRows: TRow[]) => void; /** `"destructive"` renders as a red destructive button. Default `"default"` (outline). */ variant?: "default" | "destructive"; /** Disable the action without removing it from the bar. */ disabled?: boolean; } /** Subset of `TablePropertiesDrawerButton` props that `HubTable` owns. Exposed so renderers * that build a custom toolbar (e.g. dashboard with an extra Edit-layout button) can splat * this back into their own ``. */ interface HubDrawerToolbarProps { totalRows: number; filterFields: FilterFieldDef[]; fieldDefinitions: { key: string; label: string; sortable: boolean; }[]; resolveColumnLabel: (key: string) => string; displayOptions: DataListDisplayOptions; onDisplayOptionsChange: (patch: Partial) => void; conditionalRules: ConditionalRule[]; onAddConditionalRule: (rule: Omit) => void; onRemoveConditionalRule: (id: string) => void; onUpdateConditionalRule: (id: string, patch: Partial) => void; currentView: DataListViewType; onViewChange?: (v: DataListViewType) => void; supportedViewTypes: readonly DataListViewType[]; lifecycleTabLabel: string; /** * Edit-mode rename support — forwarded to `TablePropertiesDrawerButton` / * `TablePropertiesDrawer`. When the hub client provides this pair, the * Properties drawer renders an editable Name input on its main panel so the * drawer becomes the single rename surface (no separate "Rename view" dialog * needed). Omit both to keep the legacy read-only header. */ viewName?: string; onViewNameChange?: (name: string) => void; boardGroupByColumnOptions?: { key: string; label: string; }[]; renderFilterOptionValue?: (fieldKey: string, value: string) => React.ReactNode; filterFieldContext?: Record; pagination?: boolean; onPaginationChange?: (v: boolean) => void; showViewCounts?: boolean; onShowViewCountsChange?: (v: boolean) => void; } /** Everything a non-table renderer needs. The pre-composed `toolbar` includes search + * filter chips + the Properties button; the renderer just wraps it around its body with * `toolbarShell`. For dashboards or other layouts that own their own toolbar, use * `drawerToolbarProps` to assemble a custom ``. */ interface HubTableRendererArgs> { state: ReturnType>; toolbar: React.ReactNode; toolbarShell: (body: React.ReactNode) => React.ReactNode; drawerToolbarProps: HubDrawerToolbarProps; displayOptions: DataListDisplayOptions; patchDisplay: (patch: Partial) => void; } /** Hubs provide one renderer per `DataListViewRenderKind` they implement. The `data-table` * kind is handled internally by `HubTable` (do not override unless you genuinely need a * different table surface). Missing kinds render `` — clear empty * state, never a silent dashboard fallback. */ type HubTableRenderers> = Partial) => React.ReactNode>>; interface HubTableHandle extends OpenTablePropertiesHandle { drawerToolbarProps: HubDrawerToolbarProps | null; } /** * Spec emitted by `` when the user clicks "Create view" in the * 2-step "Add view" creation drawer. The drawer is wired to a SECOND * ephemeral `useTableState` instance inside `HubTable` (separate from the * active view's live state), so the user can configure filters / sort / * columns / etc. without polluting the current view; the configured values * arrive here on commit. * * Hub clients typically forward `spec` to `seedTableStateLifecycle` so the * new tab restores these values on its first mount. */ interface CreatedViewSpec { name: string; viewType: DataListViewType; filters: ActiveFilter[]; sortRules: SortRule[]; colOrder: string[]; /** Persisted shape is an array; pass `Array.from(state.hiddenCols)` when constructing. */ hiddenCols: string[]; groupBy: string | null; conditionalRules: ConditionalRule[]; displayOptions: DataListDisplayOptions; } interface HubTableProps> { /** Full row dataset (already scoped/filtered by the hub client, e.g. by URL nav). */ rows: TRow[]; /** Column defs — `filter` blocks here become Properties drawer filter fields automatically. */ columns: ColumnDef[]; /** Active view from the `ListPageTemplate` tab. */ view: DataListViewType; onViewChange?: (v: DataListViewType) => void; /** * Active view's name + commit handler — when both are provided, the Properties * drawer renders an editable Name input on its main panel (in addition to the * 2-step "Create new view" creation surface). Hubs typically bind this to the * active `ViewTab.label` and an `updateTab({ label })` callback. */ viewName?: string; onViewNameChange?: (name: string) => void; /** * Allowlist passed to `TablePropertiesDrawerButton` so Properties cannot offer unsupported views. * Defaults to {@link TABLE_ONLY_HUB_SUPPORTED_VIEWS} when omitted — opt into * {@link FULL_HUB_SUPPORTED_VIEWS} when the product asks for list/board/dashboard/folder views. */ supportedViewTypes?: readonly DataListViewType[]; /** Used by `ListPageViewNotConfigured` when a supported view has no renderer. */ hubLabel: string; /** Shown below "Properties" in the drawer header. */ lifecycleTabLabel: string; /** Toolbar search input aria-label. */ searchAriaLabel: string; getRowId: (row: TRow) => string | number; getRowSelectionLabel: (row: TRow) => string; defaultSort: { key: string; dir: "asc" | "desc"; }; /** DataTable empty state. Defaults to a muted "No records match your filters." */ emptyState?: React.ReactNode; /** Per-view renderers (everything other than `view === "table"`). */ renderers: HubTableRenderers; /** * Structured bulk-action definitions (Polaris IndexTable parity). When set * (and the active selection is non-empty), `HubTable` renders one button * per entry inside the floating bulk-action bar — using `Button` / * `` from the DS — and resolves `onSelect` with the actual selected * `TRow` objects. Use this in preference to {@link bulkActionsSlot}; the * slot remains for fully-custom toolbar bodies. */ bulkActions?: BulkAction[]; /** * Escape hatch for bulk-action toolbars that need bespoke UI (custom * dropdowns, segmented controls, etc.). Receives the row id set and the * filtered row bag. Prefer {@link bulkActions} for normal button rows. */ bulkActionsSlot?: (selected: Set) => React.ReactNode; /** Board-view group-by column options for the Properties drawer. */ boardGroupByColumnOptions?: { key: string; label: string; }[]; /** Initial display options (toolbar search visibility, calendar panel, etc.). */ displayOptionsInit?: DataListDisplayOptions; /** Custom renderer for filter option values (e.g. status chips). */ renderFilterOptionValue?: (fieldKey: string, value: string) => React.ReactNode; /** DataTable: enable "Group by" feature. Default `true`. */ groupable?: boolean; /** DataTable: enable row selection checkboxes. Default `true`. */ selectable?: boolean; /** DataTable: row click handler (e.g. navigate to detail route). */ onRowClick?: (row: TRow) => void; /** * Controlled `displayOptions` — when provided (with `onDisplayOptionsChange`), the hub client * owns persistence (e.g. Placements page persists across tab switches). Otherwise `HubTable` * owns internal state from `displayOptionsInit`. */ displayOptions?: DataListDisplayOptions; onDisplayOptionsChange?: (patch: Partial) => void; /** * Pagination toggle forwarded to `TablePropertiesDrawerButton` so the drawer can offer * "Show pagination" on the Display panel. The hub still implements its own pagination chrome * around the table body via `tableRenderer`. Defaults to `false` / no toggle. */ pagination?: boolean; onPaginationChange?: (v: boolean) => void; /** Show record counts on each view tab — surfaced in the Properties Display panel. */ showViewCounts?: boolean; onShowViewCountsChange?: (v: boolean) => void; /** Imperative handle (`openPropertiesDrawer`) for hub clients that pass `tablePropertiesRef`. */ handleRef?: React.Ref; /** Optional override for the `data-table` view. Default mounts ``. */ tableRenderer?: (args: HubTableRendererArgs) => React.ReactNode; /** * Forwarded to `useTableState` so the hub can switch on server-style pagination * with externally-controlled page/pageSize (advanced; most hubs should leave * this undefined and let `HubTable` own the internal page state — see * `pagination` + `paginationPageSizeOptions`). */ paginationOverride?: { page: number; pageSize: number; }; /** Page size options shown in the toolbar ``. Default `[10, 25, 50, 100]`. */ paginationPageSizeOptions?: number[]; /** Initial page size when `HubTable` owns pagination internally. Default `10`. */ paginationInitialPageSize?: number; /** * Forwarded to `useTableState` to sync toolbar search from `?q=` (Library search routes). * Defining as `""` enables sync without an initial query. */ syncedSearchFromUrl?: string; /** Default `list-with-toolbar` renderer body — `HubTable` wraps with toolbar + `DataRowList`. */ renderListRow?: (row: TRow) => React.ReactNode; /** Override the `aria-label` on the `
    ` from `renderListRow`. Defaults to `hubLabel`. */ listAriaLabel?: string; /** Empty-state for the default list renderer. Defaults to "No records match your filters." */ listEmptyState?: React.ReactNode; /** Virtualise after N rows in the default list renderer. Default 100; pass `0` to disable. */ listVirtualizeThreshold?: number; /** Estimated row height (px) for the default list virtualiser. Default 96. */ listEstimatedRowHeight?: number; /** Default `board-with-toolbar` renderer body — `HubTable` wraps with toolbar + `ListPageBoardTemplate`. */ renderBoardCard?: (row: TRow) => React.ReactNode; /** Required if `renderBoardCard` is set: how rows group into columns. */ boardGroups?: ListPageBoardColumnDef[]; /** Per-column count badge tint classes for the default board renderer. */ boardColumnCountBadgeClassName?: Record; /** Empty column copy for the default board renderer. Defaults to "No items". */ boardEmptyColumnLabel?: string; /** * **Opt-in localStorage persistence** for the table lifecycle: sort, * search, filters, column order/widths/pins/hidden, row height, gridlines, * conditional rules, and pagination. When set, the hub state is restored * on reload — without this prop, the table works exactly as before * (in-memory only). * * The string is the namespace (e.g. `"placements"`, `"team"`, `"library"`) * — it becomes part of the storage key * `exxat-ds::lifecycle:v1:`. **Use the same key * across renders** of the same hub or persistence will reset. * * For per-tab persistence inside a hub (e.g. Placements "all / mine / * shared"), pass the active scope as `persistTabId`. * * @see `apps/web/docs/persisted-state-pattern.md` * @see `.cursor/rules/exxat-persisted-state.mdc` */ persistKey?: string; /** * Sub-key for per-scope persistence (e.g. the active Placements scope id). * Defaults to `"main"` — most hubs only need a single scope. */ persistTabId?: string; /** * When non-null, opens the Properties drawer in creation mode wired to a * SEPARATE, ephemeral `useTableState` buffer (NOT the active view's live * state). The user can configure filters / sort / columns / conditional * rules / display options for the new view without affecting the current * view. Set to `null` to close the creation drawer. * * Hub clients drive this from the `ListPageTemplate.onRequestCreateView` * callback. */ creatingViewType?: DataListViewType | null; /** * Controlled name input for the new view. Required when `creatingViewType` * is non-null — the Create button is disabled while the trimmed name is * empty. */ creatingViewName?: string; onCreatingViewNameChange?: (name: string) => void; /** * Fired when the user dismisses the creation drawer (Esc, Cancel, or close * icon). The parent should set `creatingViewType` back to `null` and reset * any draft name. */ onCancelCreation?: () => void; /** * Fired when the user clicks "Create view". Receives a fully-typed spec * reflecting the ephemeral creation state at commit time. The parent * typically calls `seedTableStateLifecycle` with the new tab id and the * spec's writable slices so the new tab restores them on first mount. */ onCommitCreation?: (spec: CreatedViewSpec) => void; } declare function HubTable>({ rows, columns, view, onViewChange, viewName, onViewNameChange, supportedViewTypes: supportedViewTypesProp, hubLabel, lifecycleTabLabel, searchAriaLabel, getRowId, getRowSelectionLabel, defaultSort, emptyState, renderers, bulkActions, bulkActionsSlot, boardGroupByColumnOptions, displayOptionsInit, renderFilterOptionValue, groupable, selectable, onRowClick, displayOptions: displayOptionsControlled, onDisplayOptionsChange: onDisplayOptionsChangeControlled, pagination, onPaginationChange, showViewCounts, onShowViewCountsChange, handleRef, tableRenderer, paginationOverride, paginationPageSizeOptions, paginationInitialPageSize, syncedSearchFromUrl, renderListRow, listAriaLabel, listEmptyState, listVirtualizeThreshold, listEstimatedRowHeight, renderBoardCard, boardGroups, boardColumnCountBadgeClassName, boardEmptyColumnLabel, persistKey, persistTabId, creatingViewType, creatingViewName, onCreatingViewNameChange, onCancelCreation, onCommitCreation, }: HubTableProps): react_jsx_runtime.JSX.Element; declare namespace HubTable { var displayName: string; } export { type BulkAction, type CreatedViewSpec, type HubDrawerToolbarProps, HubTable, type HubTableHandle, type HubTableProps, type HubTableRendererArgs, type HubTableRenderers, columnsToFieldDefinitions, columnsToFilterFields };