column-popover-presentation.ts1.3 KBView on GitHub
/**
 * Presentation options shared by every column filter/sort popover
 * (date, number, binary, task, custom field, enum, owner).
 *
 * A column header opens the popover 'full' — sort and filter together, since
 * that is the one place both are in scope. The filter list and the sort list
 * each open it scoped to their own concern, and pass a `crossLink` button that
 * hands the column over to the other list. They also anchor it beside the list
 * rather than below the row, so it reads as a nested menu.
 */
import type { ReactNode } from 'react';

/** Which half of a column popover to show. */
export type ColumnPopoverMode = 'full' | 'sort' | 'filter';

export interface ColumnPopoverPresentation {
  /** Preferred side of the trigger to open on. Radix flips it on collision. */
  side?: 'top' | 'right' | 'bottom' | 'left';
  align?: 'start' | 'center' | 'end';
  /** Defaults to 'full'. */
  mode?: ColumnPopoverMode;
  /** Hand-off button ("Set filter" / "Set sort") rendered where the hidden half would be. */
  crossLink?: ReactNode;
}

/** Anchoring the filter and sort lists use so their column popovers nest: `[list] [column]`. */
export const NESTED_COLUMN_POPOVER = { side: 'right', align: 'start' } as const satisfies Pick<
  ColumnPopoverPresentation,
  'side' | 'align'
>;