import React from "react"; import type { VirtualTableSortKey } from "../../components/VirtualTable/VirtualTableProps"; /** * Supported view modes. * * Any other string is a key into the `customViews` prop. The `(string & {})` * arm keeps the four built-ins in autocomplete while admitting those keys. */ export type CollectionViewMode = "table" | "cards" | "kanban" | "list" | (string & {}); /** Supported collection sizes */ export type CollectionViewSize = "xs" | "s" | "m" | "l" | "xl"; /** * Enum value configuration. * Simple form: string label * Extended form: object with label + optional color + disabled */ export type CollectionEnumValueConfig = string | { label: string; color?: string; disabled?: boolean; }; /** * A data-agnostic property definition for rendering columns/cells. * This is a UI-only type — it describes HOW to render, not WHERE data lives. * * This shape is deliberately compatible with Rebase's Property type, * so the connected wrapper can pass properties with minimal mapping. */ export interface CollectionPropertyConfig { /** Property data type — determines how cells are rendered */ type: "string" | "number" | "boolean" | "date" | "array" | "map" | "reference" | "relation" | "geopoint"; /** Display name shown in column headers and card labels */ name: string; /** Optional description, shown as tooltip on column header */ description?: string; /** Column width in pixels */ columnWidth?: number; /** If true, this property is not shown in collection views */ hideFromCollection?: boolean; /** Map of value → label/config for enum properties */ enum?: Record | Map; multiline?: boolean; previewAsTag?: boolean; url?: boolean | string; markdown?: boolean; storage?: boolean; email?: boolean; of?: CollectionPropertyConfig; properties?: Record; propertiesOrder?: string[]; mode?: "date" | "date_time"; /** Custom preview component for this property */ Preview?: React.ComponentType; } /** * Data controller interface — the headless view reads data and state through this. * Consumer apps can build their own implementation. */ export interface CollectionDataController> { data: T[]; loading: boolean; noMoreToLoad: boolean; error?: Error; filterValues?: Record; setFilterValues?: (values: Record | undefined) => void; /** The sort keys in order of significance; the second breaks ties on the first. */ sortBy?: VirtualTableSortKey[]; setSortBy?: (sort?: VirtualTableSortKey[]) => void; searchString?: string; setSearchString?: (search?: string) => void; clearFilter?: () => void; initialScroll?: number; onScroll?: (props: { scrollDirection: "forward" | "backward"; scrollOffset: number; scrollUpdateWasRequested: boolean; }) => void; paginationEnabled?: boolean; pageSize?: number; itemCount?: number; setItemCount?: (count: number) => void; } /** * Props passed to cell renderers. */ export interface CellRendererProps> { row: T; propertyKey: string; property: CollectionPropertyConfig; value: unknown; size?: "small" | "medium" | "large" | "tiny"; width?: number; height?: number; } /** * Custom cell renderer function type. * Return undefined to fall through to the default renderer. */ export type CellRendererOverride> = (props: CellRendererProps) => React.ReactNode | undefined; /** * Selection controller for the headless view. */ export interface CollectionSelectionController> { selectedItems: T[]; setSelectedItems: React.Dispatch>; } /** * Kanban property option for the view mode toggle. */ export interface KanbanPropertyOption { key: string; label: string; } /** * What a custom view's component receives — the same set the built-in table, * card, list and kanban views are given, so a custom view starts at parity * with them and inherits the toolbar's search, the empty state and selection. */ export interface CollectionCustomViewProps> { dataController: CollectionDataController; properties: Record; propertiesOrder?: string[]; idProperty?: string; titleProperty?: string; onRowClick?: (row: T) => void; onRowCreate?: (defaults?: Record) => void; canCreate?: boolean; cellRenderer?: CellRendererOverride; selectionEnabled?: boolean; selectionController?: CollectionSelectionController; highlightedItems?: T[]; emptyComponent?: React.ReactNode; size?: CollectionViewSize; } /** * A custom view registration. Either the component on its own, or the * component with the label and icon its switcher entry should carry. * * Without a `name` the switcher falls back to the key, which is legible but * rarely what you want on screen. */ export type CollectionCustomViewEntry> = React.ComponentType> | { name?: string; icon?: React.ReactNode; Component: React.ComponentType>; };