"use client"; import * as React from "react"; import { Clock, Loader2, Mail, UserCheck, UserPlus } from "lucide-react"; import { Input } from "@/components/ui/input"; import { api } from "@/lib/trpc"; import { cn } from "@/lib/utils"; import type { InviteSuggestion } from "@tasks/shared"; /** * Standalone combobox for the invite recipient field. Fully controlled — * the parent owns the raw email string via `value`/`onChange` and may * react to a non-`new_email` pick (existing member, pending invite, * known user from a sibling workspace) via `onSelectSuggestion`. * * Behavior: * - Debounces the query 200ms before hitting `invites.suggestRecipient`. * - Shows nothing for queries shorter than 2 characters. * - Distinct row styling per `kind` so the inviter can tell at a glance * whether they're about to send a fresh invite vs. re-discover someone * who's already in the workspace. * - Keyboard: ArrowUp/Down to highlight, Enter to pick, Esc to close. * - For a `new_email` pick we just fill the input via `onChange` and let * the parent submit the form. For every other kind we also call * `onSelectSuggestion` so the parent can e.g. close the dialog and * scroll to the matching member row. */ export interface InviteRecipientComboboxProps { workspaceSlug: string; value: string; onChange: (email: string) => void; /** * Called when the user picks an existing-member / pending-invite / * known-user row. NOT called for `new_email`; for that kind, only * `onChange(suggestion.email)` runs. */ onSelectSuggestion?: (suggestion: InviteSuggestion) => void; placeholder?: string; disabled?: boolean; /** Optional id so an external `