import * as react_jsx_runtime from 'react/jsx-runtime';
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-BstmlfQ3.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/row-height.js';

/** Derive `FilterFieldDef[]` from a hub's column defs — preferred to hand-writing both. */
declare function columnsToFilterFields<TRow>(cols: ColumnDef<TRow>[]): FilterFieldDef[];
/** Field definitions for the drawer's Sort / Group / Columns panels — excludes utility columns. */
declare function columnsToFieldDefinitions<TRow>(cols: ColumnDef<TRow>[]): {
    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<string | number>` — they just react to typed rows.
 *
 * `variant`:
 *   - `"default"` (omit) → outline button — Archive, Export, Tag, etc.
 *   - `"destructive"`    → red destructive button — Delete, Remove, etc.
 */
interface BulkAction<TRow extends Record<string, unknown>> {
    /** Stable id (used as React key). */
    id: string;
    /** Visible button label. */
    label: string;
    /** Font Awesome glyph (e.g. `"fa-box-archive"`). Rendered as `<i className="fa-light ..." />`. */
    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 `<TablePropertiesDrawerButton {...drawerToolbarProps} state={s} extraActions={…} />`. */
interface HubDrawerToolbarProps {
    totalRows: number;
    filterFields: FilterFieldDef[];
    fieldDefinitions: {
        key: string;
        label: string;
        sortable: boolean;
    }[];
    resolveColumnLabel: (key: string) => string;
    displayOptions: DataListDisplayOptions;
    onDisplayOptionsChange: (patch: Partial<DataListDisplayOptions>) => void;
    conditionalRules: ConditionalRule[];
    onAddConditionalRule: (rule: Omit<ConditionalRule, "id">) => void;
    onRemoveConditionalRule: (id: string) => void;
    onUpdateConditionalRule: (id: string, patch: Partial<ConditionalRule>) => 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;
    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 `<TablePropertiesDrawerButton>`. */
interface HubTableRendererArgs<TRow extends Record<string, unknown>> {
    state: ReturnType<typeof useTableState<TRow>>;
    toolbar: React.ReactNode;
    toolbarShell: (body: React.ReactNode) => React.ReactNode;
    drawerToolbarProps: HubDrawerToolbarProps;
    displayOptions: DataListDisplayOptions;
    patchDisplay: (patch: Partial<DataListDisplayOptions>) => 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 `<ListPageViewNotConfigured>` — clear empty
 * state, never a silent dashboard fallback. */
type HubTableRenderers<TRow extends Record<string, unknown>> = Partial<Record<DataListViewRenderKind, (args: HubTableRendererArgs<TRow>) => React.ReactNode>>;
interface HubTableHandle extends OpenTablePropertiesHandle {
    drawerToolbarProps: HubDrawerToolbarProps | null;
}
/**
 * Spec emitted by `<HubTable>` 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<TRow extends Record<string, unknown>> {
    /** 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<TRow>[];
    /** 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 FULL_HUB_SUPPORTED_VIEWS} when omitted — keep in sync with
     * `ListPageTemplate.supportedViewTypes` on the same hub.
     */
    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<TRow>;
    /**
     * 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` /
     * `<Tip>` 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<TRow>[];
    /**
     * 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<string | number>) => 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<DataListDisplayOptions>) => 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<HubTableHandle>;
    /** Optional override for the `data-table` view. Default mounts `<DataTable {…}>`. */
    tableRenderer?: (args: HubTableRendererArgs<TRow>) => 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 `<PaginationBar>`. 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 `<ul>` 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<TRow>[];
    /** Per-column count badge tint classes for the default board renderer. */
    boardColumnCountBadgeClassName?: Record<string, string>;
    /** 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:<persistKey>:lifecycle:v1:<persistTabId>`. **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<TRow extends Record<string, unknown>>({ 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<TRow>): 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 };
