149 lines · 5.7 KB · TypeScript
RawDownload
import { type ProviderDriverKind, type ProviderInstanceId } from "@t3tools/contracts";import { memo } from "react";import { StarIcon } from "lucide-react";import {  getDisplayModelName,  getTriggerDisplayModelLabel,  type ModelEsque,  PROVIDER_ICON_BY_PROVIDER,} from "./providerIconUtils";import { ComboboxItem } from "../ui/combobox";import { Button } from "../ui/button";import { Badge } from "../ui/badge";import { Kbd } from "../ui/kbd";import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";import { cn } from "~/lib/utils";import { modelPickerModelKey } from "./modelPickerKeys"; export const ModelListRow = memo(function ModelListRow(props: {  index: number;  model: ModelEsque;  /** Instance the model belongs to — the routing key used in combobox values. */  instanceId: ProviderInstanceId;  /** Driver kind of the instance — used for the provider icon glyph. */  driverKind: ProviderDriverKind;  /**   * Display name to show in the secondary line (provider footer). Usually   * the instance's configured `displayName` so custom instances like   * "Codex Personal" render with their user-authored label.   */  providerDisplayName: string;  providerAccentColor?: string | undefined;  isFavorite: boolean;  isSelected: boolean;  showProvider: boolean;  preferShortName?: boolean;  useTriggerLabel?: boolean;  showNewBadge?: boolean;  unavailable?: boolean;  jumpLabel?: string | null;  disabledReason?: string | null;  onToggleFavorite: () => void;}) {  const ProviderIcon = PROVIDER_ICON_BY_PROVIDER[props.driverKind] ?? null;  const providerLabel = props.model.subProvider    ? `${props.providerDisplayName} · ${props.model.subProvider}`    : props.providerDisplayName;   const row = (    <ComboboxItem      hideIndicator      index={props.index}      value={modelPickerModelKey(props.instanceId, props.model.slug)}      disabled={Boolean(props.disabledReason)}      contentClassName="flex w-full items-center gap-3"      className={cn(        "group relative w-full !min-w-0 max-w-full cursor-pointer rounded-md px-2 py-2 transition-[background-color,box-shadow,color]",        "hover:bg-[color-mix(in_srgb,var(--popover)_90%,var(--contrast-foreground))] data-highlighted:bg-[color-mix(in_srgb,var(--popover)_90%,var(--contrast-foreground))] data-selected:bg-foreground/[0.08] data-selected:text-foreground data-selected:ring-0 [&[data-highlighted][data-selected]]:bg-[color-mix(in_srgb,var(--popover)_90%,var(--contrast-foreground))]",        props.disabledReason &&          "data-disabled:pointer-events-auto data-disabled:cursor-not-allowed data-disabled:hover:bg-transparent",      )}    >      <div className="min-w-0 flex-1 text-left">        <div className="flex min-w-0 items-center gap-2">          <div className="min-w-0 truncate text-xs font-medium leading-snug">            {props.useTriggerLabel              ? getTriggerDisplayModelLabel(props.model)              : getDisplayModelName(                  props.model,                  props.preferShortName ? { preferShortName: true } : undefined,                )}          </div>          {props.showNewBadge ? (            <span              className="shrink-0 rounded border border-update/35 bg-update/15 px-0.5 py-px text-[10px] font-bold uppercase leading-none tracking-wide text-update-foreground"              aria-label="New model"            >              New            </span>          ) : null}          {props.unavailable ? (            <Badge variant="outline" size="sm">              Unavailable            </Badge>          ) : null}        </div>        {props.showProvider && (          <div className="mt-1 flex items-center gap-1.5">            {ProviderIcon ? <ProviderIcon className="size-3 shrink-0" /> : null}            <span className="truncate text-xs font-normal leading-snug text-muted-foreground/70">              {providerLabel}            </span>          </div>        )}      </div>       <div className="flex shrink-0 items-center gap-1.5">        {props.jumpLabel ? (          <Kbd className="h-4 min-w-0 rounded-sm px-1.5 text-[10px]">{props.jumpLabel}</Kbd>        ) : null}        <Tooltip>          <TooltipTrigger            render={              <Button                size="icon-xs"                variant="ghost"                className={cn(                  "-mr-1 shrink-0 text-muted-foreground/70 opacity-64 transition-[color,opacity] hover:text-foreground hover:opacity-100 group-hover:opacity-100",                  props.isFavorite && "text-foreground opacity-100",                )}                onClick={(event) => {                  event.stopPropagation();                  props.onToggleFavorite();                }}                onKeyDown={(event) => {                  event.stopPropagation();                }}                disabled={Boolean(props.disabledReason)}                aria-label={props.isFavorite ? "Remove from favorites" : "Add to favorites"}              >                <StarIcon                  className={cn(                    "size-3.5 sm:size-3",                    props.isFavorite && "fill-current text-yellow-500",                  )}                />              </Button>            }          />          <TooltipPopup side="top" align="center">            {props.isFavorite ? "Remove from favorites" : "Add to favorites"}          </TooltipPopup>        </Tooltip>      </div>    </ComboboxItem>  );   if (!props.disabledReason) {    return row;  }   return (    <Tooltip>      <TooltipTrigger render={row} />      <TooltipPopup side="left" align="center" className="max-w-64 text-balance leading-snug">        {props.disabledReason}      </TooltipPopup>    </Tooltip>  );});